Implement Create Task List
Now that we can list task lists, let's implement the ability to create new ones. We'll need to add methods to both our service and controller layers to handle this functionality.
Updating the Service Interface
First, let's add the create method to our TaskListService interface:
public interface TaskListService {
List<TaskList> listTaskLists();
TaskList createTaskList(TaskList taskList); // Add this method
}Implementing the Service Method
Now let's implement the create functionality in TaskListServiceImpl:
@Service
public class TaskListServiceImpl implements TaskListService {
private final TaskListRepository taskListRepository;
public TaskListServiceImpl(TaskListRepository taskListRepository) {
this.taskListRepository = taskListRepository;
}
@Override
public TaskList createTaskList(TaskList taskList) {
if (null != taskList.getId()) {
throw new IllegalArgumentException("Task list already has an ID!");
}
if (null == taskList.getTitle() || taskList.getTitle().isBlank()) {
throw new IllegalArgumentException("Task list title must be present!");
}
LocalDateTime now = LocalDateTime.now();
return taskListRepository.save(new TaskList(
null,
taskList.getTitle(),
taskList.getDescription(),
null,
now,
now
));
}
}Let's examine the key aspects of this implementation:
-
Input Validation:
- Checks that the task list doesn't already have an ID (it's a new task list)
- Ensures the title is not null or blank
-
Timestamp Handling:
- Sets both created and updated timestamps to the current time
- This ensures consistent timestamp creation
-
Clean Creation:
- Creates a new TaskList instance rather than using the input directly
- Ensures no unexpected data gets persisted
- Sets tasks to null as new lists start empty
Updating the Controller
Finally, let's add the create endpoint to our TaskListController:
@RestController
@RequestMapping(path = "/task-lists")
public class TaskListController {
private final TaskListService taskListService;
private final TaskListMapper taskListMapper;
public TaskListController(TaskListService taskListService, TaskListMapper taskListMapper) {
this.taskListService = taskListService;
this.taskListMapper = taskListMapper;
}
@PostMapping
public TaskListDto createTaskList(@RequestBody TaskListDto taskListDto) {
TaskList createdTaskList = taskListService.createTaskList(
taskListMapper.fromDto(taskListDto)
);
return taskListMapper.toDto(createdTaskList);
}
}Let's break down the new controller method:
-
Annotation:
@PostMappingmaps this to HTTP POST requests@RequestBodytells Spring to deserialize the request body into a TaskListDto
-
Implementation:
- Converts the incoming DTO to an entity using our mapper
- Calls the service to create the task list
- Converts the result back to a DTO for the response
How It Works Together
When a POST request arrives at /task-lists:
- Spring deserializes the JSON request body into a TaskListDto
- The controller converts the DTO to a TaskList entity
- The service validates the input and creates a new TaskList
- The repository persists the TaskList to the database
- The controller converts the saved entity back to a DTO
- Spring serializes the DTO to JSON for the response
Note that if validation fails, exceptions will be thrown. We'll handle these exceptions properly in the next lesson.
Testing the Endpoint
We can now create task lists through the frontend. The app will send a POST request with a JSON body like:
{
"title": "My New List",
"description": "A list of important tasks"
}
And receive a response like:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"title": "My New List",
"description": "A list of important tasks",
"count": 0,
"progress": null,
"tasks": null
}
Summary
- Added create functionality to the
TaskListService - Implemented input validation in the service layer
- Added the POST endpoint to create task lists
- Connected all layers for a complete create operation