As an application developer, you should never trust the data provided by users. At any possible input! That doesn’t only apply for request payload send within the request body, but also for query parameters.
This guide shows you how to apply query parameter validation for a given route in your hapi server using the joi plugin.
hapi Series Overview
- What You’ll Build
- Prepare Your Project: Stack & Structure
- Environment Variables and Storing Secrets
- Set Up MongoDB and Connect With Mongoose
- Sending Emails in Node.js
- Load the User’s Profile Picture From Gravatar Using Virtuals in Mongoose
- Implement a User Profile Editing Screen
- Generate a Username in Mongoose Middleware
- Displaying Seasons and Episodes for TV Shows with Mongoose Relationship Population
- Implementing Pagination for Movies
- Implement a Watchlist
- Create a Full Text Search with MongoDB
- Create a REST API with JSON Endpoints
- Update Mongoose Models for JSON Responses
- API Pagination for TV Shows
- Customize API Endpoints with Query Parameters
- Always Throw and Handle API Validation Errors
- Advanced API Validation With Custom Errors
- Create an API Documentation with Swagger
- Customize Your Swagger API Documentation URL
- Describe Endpoint Details in Your Swagger API Documentation
- 10 Tips on API Testing With Postman
- JWT Authentication in Swagger API Documentation
- API Versioning with Request Headers
- API Login With Username and Password to Generate a JWT
- JWT Authentication and Private API Endpoints
- Refresh Tokens With JWT Authentication
- Create a JWT Utility
- JWT Refresh Token for Multiple Devices
- Check Refresh Token in Authentication Strategy
- Rate Limit Your Refresh Token API Endpoint
- How to Revoke a JWT
- Invalidate JWTs With Blacklists
- JWT Logout (Part 1/2)
- JWT “Immediate” Logout (Part 2/2)
- A Better Place to Invalidate Tokens
- How to Switch the JWT Signing Algorithm
- Roll Your Own Refresh Token Authentication Scheme
- JWT Claims 101
- Use JWT With Asymmetric Signatures (RS256 & Co.)
- Encrypt the JWT Payload (The Simple Way)
- Increase JWT Security Beyond the Signature
- Unsigned JSON Web Tokens (Unsecured JWS)
- JWK and JWKS Overview
- Provide a JWKS API Endpoint
- Create a JWK from a Shared Secret
- JWT Verification via JWKS API Endpoint
- What is JOSE in JWT
- Encrypt a JWT (the JWE Way)
- Authenticate Encrypted JWTs (JWE)
- Encrypted and Signed JWT (Nested JWT)
- Bringing Back JWT Decoding and Authentication
- Bringing Back JWT Claims in the JWT Payload
- Basic Authentication With Username and Password
- Authentication and Remember Me Using Cookies
- How to Set a Default Authentication Strategy
- Define Multiple Authentication Strategies for a Route
- Restrict User Access With Scopes
- Show „Insufficient Scope“ View for Routes With Restricted Access
- Access Restriction With Dynamic and Advanced Scopes
- hapi - How to Fix „unknown authentication strategy“
- Authenticate with GitHub And Remember the Login
- Authenticate with GitLab And Remember the User
- How to Combine Bell With Another Authentication Strategy
- Custom OAuth Bell Strategy to Connect With any Server
- Redirect to Previous Page After Login
- How to Implement a Complete Sign Up Flow With Email and Password
- How to Implement a Complete Login Flow
- Implement a Password-Reset Flow
- Views in hapi 9 (and above)
- How to Render and Reply Views
- How to Reply and Render Pug Views (Using Pug 2.0)
- How to Create a Dynamic Handlebars Layout Template
- Create and Use Handlebars Partial Views
- Create and Use Custom Handlebars Helpers
- Specify a Different Handlebars Layout for a Specific View
- How to Create Jade-Like Layout Blocks in Handlebars
- Use Vue.js Mustache Tags in Handlebars Templates
- How to Use Multiple Handlebars Layouts
- How to Access and Handle Request Payload
- Access Request Headers
- How to Manage Cookies and HTTP States Across Requests
- Detect and Get the Client IP Address
- How to Upload Files
- Quick Access to Logged In User in Route Handlers
- How to Fix “handler method did not return a value, a promise, or throw an error”
- How to Fix “X must return an error, a takeover response, or a continue signal”
- Query Parameter Validation With Joi
- Path Parameter Validation With Joi
- Request Payload Validation With Joi
- Validate Query and Path Parameters, Payload and Headers All at Once on Your Routes
- Validate Request Headers With Joi
- Reply Custom View for Failed Validations
- Handle Failed Validations and Show Errors Details at Inputs
- How to Fix AssertionError, Cannot validate HEAD or GET requests
Prepare Your Project and Install Joi
You’ll use the joi
module from within hapi’s plugin ecosystem to validate provided query parameters on a given route. Before defining the validation itself, you need to add joi
as a dependency to your project:
npm i -S joi
Installation process finished successfully? Your project is ready to make use of joi
for input validation.
Use Joi for Query Parameter Validation
Query parameters aren’t defined within your route setup and users can provide any kind of value if they know what parameter keys you’re evaluating and processing within your app. Within the following code snippet, you can see how the actual query parameter validation is applied to a specific route.
In case you’ve the query parameter validation configured, hapi applies the defined constraints. Depending on whether the given parameter data passes the validation process successfully, the request will be proceeded by calling the route handler. If validation already fails, hapi will reply with a detailed boom error object including the reason why validation didn’t finish correctly.
var Joi = require('joi')
server.route({
method: 'GET',
path: '/tutorials',
config: {
handler: …,
validate: {
query: {
filter: Joi.array().items(Joi.string().valid('premium', 'video')).single()
}
}
}
})
As you can see within the code snippet above, to enable validation on your route, you need to define a config.validate
object. The query parameter validation is used with the help of the query
property.
The snippet shows an exemplary query parameter validation for the filter
key, like https://futurestud.io/tutorials?filter=video
. The actual validation rule looks kind of complex, but it just says that users are only allowed to use the premium
or video
or both values with the filter
parameter. If users provide other values than allowed, the validation will fail and users will see an error message.
You can find all applicable methods and constraints within joi
’s API reference.
Notice: if you apply validation for one of your query parameters, you need to define rules for every other as well. Joi
will validate every query parameter if you’re activating one or many for a given route. If you’re going to use the route from above, you can’t use another query parameter (like ?page=20
), because joi
only expects filter
.
Validate Multiple Query Parameters on a Route
In the paragraph above, you’ve read that if you apply validation to a single query parameter, you need to validate all of them. And that’s kind of straight forward by adding your query parameter keys to the validate.query
object in your hapi route.
Let’s extend the previous example with another query parameter, called page
. Assumingly you’re going to use the page
parameter for pagination through your list of tutorials. That means you’re expecting a number greater than zero.
validate: {
query: {
filter: Joi.array().items(Joi.string().valid('premium', 'video')).single(),
page: Joi.number().min(1)
}
}
If you want to validate further query parameters, just add them to the query
object within validate
.
Outlook
We hope you see the need and benefits of query parameter validation in your hapi project. Don’t trust user data and make sure to validate the input if there’s a chance to provide malicious information.
And please keep in mind, that once you apply validation for a single query parameter, you need to add the rules for all possible keys as well. Otherwise, the validation for those keys will fail.
To complete the validation on request data, follow along to learn the basics on path parameter validation in hapi.
Do you have any question or just want to leave a message? Use the comments below or find us on Twitter @futurestud_io
Make it rock & enjoy coding!
Additional Resources
- Joi validation library on GitHub
- HTTP-friendly error handling: boom
- Payload validation in hapi using Joi