REST API Update Resource
In the previous article REST API Request Validation we looked at how to create a resource using POST request and Joi validation. In this article we will look at how to use REST API Update operation to modify a resource. We will also be using Joi validation to ensure security and consistency.
Compared to creation, updating of a resource has its own small nuances. Below we will outline the main steps. For a deeper dive, please watch the following YouTube video.
Describe REST API Update Resource Request Shema with Joi
Let’s create updateTravelSchema
in requestsSchemas.ts
file, in middleware
folder.
export const updateTravelSchema = Joi.object({
name: Joi.string().min(3).max(30),
description: Joi.string(),
number_of_days: Joi.number().integer().greater(0),
is_public: Joi.bool(),
}).or("name", "description", "number_of_days", "is_public");
None of the fields are required, however at least one of them should be present. We will achieve that with Joi’s or
method.
Create a Route and Repository Update Method
Let’s go ahead and create a PUT route in routes/v1/travels
directory in index.ts
file.
travels.put("/:id", validateRequest(updateTravelSchema), updateTravel);
It will use validateRequest
middleware with updateTravelSchema
and use updateTravel
function form the controller for processing the request.
In the controller.ts
file in the same directory let’s create updateTravel
function.
export const updateTravel = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const repository = new TravelRepository();
const travelResource = new TravelResource(
await repository.update(req.params.id, req.body)
);
res.status(200).json({ travel: travelResource.item() });
} catch (error) {
next(error);
}
};
In the above code we instantiated Travel
repository and use update method to update Travel. We wpassed req.params.id and req.body into the update method. The output of the update method is passed into the instantiated Travel resource. updateTravel
method returns Travel
resource item with status 200 back to the user. If there’s an error, we pass it to the ErrorHandler
using next
function.
Now in BaseRepository.ts
file we need to create update
method.
async update(id: string, body: Record<string, any>): Promise<A> {
const instance = await this.modelClass.findByPk(id);
if (!instance) {
return instance;
}
return instance.update(body);
}
Frist we will try to fetch a travel instance by primary key. If there’s no instance (instance is null) we will return it. The travel resource will create a not found error and return it to the user. If instance exits, we will update it passing the body. Only fields that are in the body will be updated.
Since we are going to reuse the same code for validation errors for PUT /v1/travels request
, this is all the code we need. Let’s go ahead and test it.
Conclusion
The ability to efficiently modify resources is at the core of user interaction and data management. By adhering to best practices, handling PUT requests effectively, and prioritizing data integrity, we ensure that our APIs not only meet user expectations but also stand resilient against potential vulnerabilities.