Implement List Task
Now that we have our task list CRUD operations implemented, let's start working on task management by implementing the ability to list tasks within a specific task list. We'll need to add methods to both our service and controller layers to handle this functionality.
Creating the Service Interface
First, let's create the TaskService interface in the com.devtiro.tasks.services package:
public interface TaskService {
List<Task> listTasks(UUID taskListId);
}The interface starts with a single method to retrieve all tasks for a specific task list. Note that we take a taskListId parameter to scope the results.
Implementing the Service
Now let's create the implementation in com.devtiro.tasks.services.impl:
@Service
public class TaskServiceImpl implements TaskService {
private final TaskListRepository taskListRepository;
private final TaskRepository taskRepository;
public TaskServiceImpl(TaskListRepository taskListRepository,
TaskRepository taskRepository) {
this.taskListRepository = taskListRepository;
this.taskRepository = taskRepository;
}
@Override
public List<Task> listTasks(UUID taskListId) {
return taskRepository.findByTaskListId(taskListId);
}
}Let's break down the key parts:
-
Service Annotation:
@Servicemarks this as a Spring service component- Allows Spring to manage the bean lifecycle
-
Dependencies:
- Injects both
TaskRepositoryandTaskListRepositorythrough constructor injection - Uses final fields for immutability
- Injects both
-
Implementation:
- Delegates to the repository's
findByTaskListId()method - Returns a list of Task entities for the specified task list
- No need to verify task list exists - empty list returned if not found
- Delegates to the repository's
Creating the Controller
Next, let's create the TasksController in the com.devtiro.tasks.controllers package:
@RestController
@RequestMapping(path = "/task-lists/{task_list_id}/tasks")
public class TasksController {
private final TaskService taskService;
private final TaskMapper taskMapper;
public TasksController(TaskService taskService, TaskMapper taskMapper) {
this.taskService = taskService;
this.taskMapper = taskMapper;
}
@GetMapping
public List<TaskDto> listTasks(@PathVariable("task_list_id") UUID taskListId) {
return taskService.listTasks(taskListId)
.stream()
.map(taskMapper::toDto)
.toList();
}
}Let's examine the important aspects of the controller:
-
Class-level Annotations:
@RestControllerindicates this is a REST controller@RequestMappingsets the base URL path, nested under task-lists- Note how tasks are accessed through their parent task list's URL
-
Dependencies:
TaskServicefor business logicTaskMapperfor entity-DTO conversion
-
The listTasks Method:
@GetMappingmaps this to HTTP GET requests- Takes a path variable for the task list ID
- Returns a
List<TaskDto>which Spring will convert to JSON - Uses Java streams to convert entities to DTOs
Repository Implementation
The functionality relies on a custom query method in the TaskRepository:
@Repository
public interface TaskRepository extends JpaRepository<Task, UUID> {
List<Task> findByTaskListId(UUID taskListId);
}Spring Data JPA will automatically implement this method based on the name:
findByindicates a queryTaskListIdtells Spring to filter by the id of the referenced TaskList entity
How It Works Together
When a GET request arrives at /task-lists/{task_list_id}/tasks:
- Spring routes the request to our controller's
listTasksmethod - The task list ID is extracted from the URL path
- The controller calls
taskService.listTasks(taskListId) - The service delegates to
taskRepository.findByTaskListId() - The repository returns a list of Task entities for that task list
- The controller uses the mapper to convert each entity to a DTO
- Spring converts the list of DTOs to JSON and sends it to the client
A successful response might look like:
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "Complete Project",
"description": "Finish the task management system",
"dueDate": "2024-11-01T09:00:00",
"priority": "HIGH",
"status": "OPEN"
},
{
"id": "789e4567-e89b-12d3-a456-426614174001",
"title": "Write Documentation",
"description": "Document the API endpoints",
"dueDate": "2024-11-02T17:00:00",
"priority": "MEDIUM",
"status": "OPEN"
}
]Summary
- Created the
TaskServiceinterface with list functionality scoped to task lists - Implemented the service to delegate to the repository
- Created the
TasksControllerwith proper REST resource nesting - Added a custom repository method to find tasks by task list