In this task, you will implement input validation for the Post
model in the API. You will use the Zod library to define validation schemas for the input data and validate the request payloads before processing them. Input validation helps ensure data integrity, improve error handling, and prevent security vulnerabilities.
Input validation is a critical aspect of building secure and robust APIs. By validating the input data, you can ensure that the data meets the expected format and constraints before processing it. This helps to ensure data integrity, improve error handling, and prevent security vulnerabilities such as SQL injection and cross-site scripting (XSS) attacks.
There are various ways to perform input validation in an API. Moreover, there are many libraries and tools available to simplify the process. In this task, you will use the Zod library to define validation schemas for the Post
model and validate the request payloads before processing them.
Zod is a TypeScript-first schema declaration and validation library that provides a simple and expressive way to define data schemas and validate data against those schemas. It allows you to define complex validation rules, handle nested data structures, and generate detailed error messages when validation fails.
Middlewares are functions that have access to the request and response objects in an API. They can perform tasks such as parsing request bodies, authenticating users, logging requests, and handling errors. In Hono.js, middlewares can intercept and process the Request and Response objects before and after the route Handler handles the request.
For example, we can write a middleware to add the “X-Response-Time” header as follows:
In the code above, the middleware calculates the response time of the request. It “starts” measuring the time before calling next()
to pass control to the next middleware or route handler. After the next middleware or route handler finishes processing the request, it “ends” measuring the time and sets the “X-Response-Time” header in the response.
Notice the the following:
c
(the Context object) and next
(a function to call the next middleware or route handler).await next()
statement calls the next middleware or route handler in the chain.app.use
method.While app.use
adds a middleware to the global middleware stack, you can also add middlewares to specific routes using the router.use
method. Moreover, you can apply a middleware (or multiple ones) to a specific route handler by passing it as an argument to the route handler.
First, install the Zod library using the following command:
With Zod installed, you can now define validation schemas for the Post
model.
Create a new file named src/validators/schemas.ts
and define the validation schema for the Post
model using Zod.
In the code above, we define a validation schema for creating a new post (createPostSchema
) that requires a content
field of type string
with a minimum length of 1 character and a maximum length of 240 characters.
Currently, the validation schemas are simple and only validate the content
field. You can add more validation rules and constraints as needed for your application.
POST /posts
route to include input validationUpdate the src/routes/posts.ts
file to include input validation for the POST
route using the Zod library and a custom middleware.
In the code above:
src/validators/schemas.ts
.POST
route using the createPostSchema
validation schema.safeParse
method of the Zod schema to validate the request payload. If the validation succeeds, the middleware calls the next
function to pass control to the route handler. If the validation fails, the middleware returns a 400 Bad Request
response with detailed error messages.Run the API and test the POST
route with valid and invalid input data to verify that the input validation is working as expected. You can try the following payload as a test input:
Hono provides a built-in validation middleware that simplifies input validation using Zod schemas. Update the src/routes/posts.ts
file to use the built-in validation middleware for the POST
route.
In the code above:
validator
middleware from hono/validator
.validator
middleware to validate the request payload for the POST
route using the createPostSchema
validation schema.validator
middleware takes two arguments: the type of input to validate (json
in this case) and a validation function that returns the validated data or an error response.const { content } = c.req.valid("json")
statement retrieves the validated data from the request object. The valid
method is used to access the validated data after input validation.Run the API and test the POST
route with valid and invalid input data to verify that the input validation is working as expected.
Hono provides a middleware called @hono/zod-validator
that further simplifies input validation using Zod schemas. Install the @hono/zod-validator
package using the following command:
Next update the src/routes/posts.ts
file to use the zValidator
middleware for input validation.
In the code above:
zValidator
middleware from @hono/zod-validator
.zValidator
middleware to validate the request payload for the POST
route using the createPostSchema
validation schema.zValidator
middleware automatically validates the request payload against the specified schema and returns a 400 Bad Request
response with detailed error messages if the validation fails. We only need to provide the type of input to validate (json
in this case) and the validation schema (createPostSchema
).Run the API and test the POST
route with valid and invalid input data to verify that the input validation is working as expected.
Update the src/validators/schemas.ts
file to include a partial validation schema for updating an existing post.
In the code above, we define a partial validation schema for updating an existing post (updatePostSchema
) that allows updating the content
field. The partial()
method allows the schema to accept partial data, meaning that only the specified fields are validated while other fields are ignored.
PATCH /posts/:id
route to include input validationIn the code above:
We import the the updatePostSchema
validation schema from src/validators/schemas.ts
.
We use the zValidator
middleware to validate the request payloads for the PATCH
route. Notice that the middleware is placed before the route handler to validate the request payload before processing it.
Run the API and test the POST
and PATCH
routes with valid and invalid input data to verify that the input validation is working as expected. You can try the following Dijkstra’s quote as a test input:
We can also validate path parameters using the Zod library. Update the src/validators/schemas.ts
file to include a validation schema for the id
path parameter.
In the code above, we define a validation schema for the id
path parameter (getPostSchema
) that requires a positive integer value. The coerce.number().int().positive()
chain of methods ensures that the value is coerced to a number, an integer, and a positive number.
Next, update the src/routes/posts.ts
file to include input validation for the routes that use path parameters.
In the code above:
getPostSchema
validation schema from src/validators/schemas.ts
.zValidator
middleware to validate the path parameters for the GET
, DELETE
, and PATCH
routes that use the id
path parameter. The middleware is placed before the route handler to validate the path parameters before processing the request.Run the API and test the GET
, DELETE
, and PATCH
routes with valid and invalid path parameters to verify that the input validation is working as expected.
In this task, you learned how to implement input validation for the Post
model in the API using the Zod library. You defined validation schemas for creating and updating posts, validated request payloads using custom middleware, Hono’s built-in validation middleware, and the @hono/zod-validator
middleware. You also learned how to validate path parameters using Zod schemas. Input validation is an essential part of building secure and robust APIs, and using libraries like Zod can simplify the process and improve data integrity and error handling.