Lesson 3
Implementing Update and Delete Handlers in NestJS
Introduction

Welcome to the lesson on implementing the Update and Delete handlers in a Todo REST API with NestJS. In this lesson, we'll build upon what we've learned so far to complete the CRUD functionality in our application.

Previously, you set up GET queries to fetch all Todo items or a specific item by its ID and implemented the POST handler to create new Todo items. Now, we'll focus on how to update and delete Todo items using PUT and DELETE requests, respectively.

Understanding PUT and DELETE Verbs in REST

In RESTful web services, HTTP methods (also known as verbs) play a crucial role in defining the actions that can be performed on resources. We've learned about GET and POST. Two key methods we will focus on in this lesson are PUT and DELETE.

  • PUT: The PUT method is used to update the state of a resource. If the resource does not exist, PUT can also create a new resource with the specified data, although this behavior can vary depending on implementation. In our implementation, we will not create a record via PUT if it does not already exist.
  • DELETE: The DELETE method is used to remove a resource. After a successful DELETE request, the resource should no longer exist on the server.
Adding PUT and DELETE to the TodoController

In NestJS, controllers handle incoming HTTP requests and send responses to the client. They typically delegate the business logic to services. For this lesson, we'll extend our TodoController to include methods for updating and deleting Todo items.

Here's the basic structure of our updated TodoController:

TypeScript
1import { Controller, Put, Delete, Param, Body } from '@nestjs/common'; 2import { TodoService } from './todo.service'; 3import { UpdateTodoDto } from './dtos/update-todo.dto'; 4 5@Controller('todos') 6export class TodoController { 7 constructor(private readonly todoService: TodoService) {} 8 9 // ... Existing GET and PUT handlers 10 11 // Decorate the PUT handler to require the ID in the URL for PUT /todos/:id 12 @Put(':id') 13 update( 14 // Decorate the id parameter to declare that it comes from the URL 15 @Param('id') id: string, 16 17 // Decorate the todo parameter to declare that it comes from the body of the request 18 @Body() todo: UpdateTodoDto, 19 ) { 20 return this.todoService.updateTodo(id, todo); 21 } 22 23 // Decorate the DELETE handler to require the ID in the url for DELETE /todos/:id 24 @Delete(':id') 25 remove( 26 // Decorate the id parameter to declare that it comes from the URL 27 @Param('id') id: string, 28 ) { 29 return this.todoService.deleteTodo(id); 30 } 31}
Adding edit and delete to the TodoService

Here’s the updated TodoService:

TypeScript
1@Injectable() 2export class TodoService { 3 private todos: TodoDto[] = []; 4 5 // ... existing fetch and create methods 6 7 // update an existing Todo 8 updateTodo(id: string, todo: UpdateTodoDto): TodoDto | null { 9 // Start by finding the existing Todo item. Return null if it doesn't exist. 10 const todoIndex = this.todos.findIndex(todo => todo.id === id); 11 12 if (todoIndex < 0) { 13 return null; 14 } 15 16 // Modify the existing item by using all the fields of the existing item 17 // and overwriting them with the updated fields. 18 this.todos[todoIndex] = { 19 ...this.todos[todoIndex], 20 ...todo, 21 }; 22 23 // Return the item we modified 24 return this.todos[todoIndex]; 25 } 26 27 // delete the existing Todo 28 deleteTodo(id: string): void { 29 // Remove the Todo by id 30 this.todos = this.todos.filter(todo => todo.id !== id); 31 } 32}
Create the UpdateTodoDto:

The UpdateTodoDto is used when updating an existing Todo item. Unlike TodoDto, which is for retrieving data, and CreateTodoDto, which is for creating new items, the UpdateTodoDto allows for partial updates of the Todo item. It contains optional properties like title, description, and completed, enabling users to update any combination of these fields without needing to provide all of them. This design ensures flexibility, allowing updates to be made without overwriting data unnecessarily, while still keeping the data validation and structure consistent across the application.

TypeScript
1// The Create TodoDto only needs some basic fields 2export class CreateTodoDto { 3 readonly title: string; 4 readonly description: string; 5} 6 7// The full Todo includes extra data like id and completed flags 8export class TodoDto extends CreateTodoDto { 9 readonly id: string; 10 readonly completed: boolean; 11} 12 13// The Update Todo can include any non-id field 14export class UpdateTodoDto { 15 readonly title?: string; 16 readonly description?: string; 17 readonly completed?: boolean; 18}
Summary and Preparation for Practice

In this lesson, we covered how to add update and delete functionalities to our Todo REST API. We extended the TodoController with methods to handle PUT and DELETE requests and implemented the corresponding business logic in the TodoService. These additions complete our CRUD operations setup.

Now it's time for you to put what you've learned into practice. Use the CodeSignal IDE to implement and test the update and delete handlers. Congratulations on reaching the end of the course! You've built a functional Todo REST API using NestJS, a powerful framework for building server-side applications. Keep practicing, and happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.