During the last weeks we’ve kicked off a new hapi server, extended its functionality with plugins, wrote our own custom plugin, added authentication and defined those authentication strategies to apply for your routes within a selected hapi server instance.
As you’ve recognized within the title, this tutorial is geared towards the handling of query parameters and shows you how to manage them within your app.
Before diving into the details, have a look at the series outline and find posts that match your interests and needs.
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
Access Query Parameters
Query parameters are a common way to pass information from clients to the server and of course you’re able to make use of query parameters in hapi, too. Let’s start out with a straight forward example based on the URL below:
https://futurestud.io?name=marcus
Dividing the URL into its different parts will result in the query parameter string of ?name=marcus
. Query parameters in URLs are in the format of key=value
. The first query parameter pair is indicated within the URL by using the question mark ?
and any following pair is added by using the ampersand &
.
In hapi, you can access query parameters using the request
object. The request
instance provides a field called query
and by accessing it, you’ll receive an object with the parsed query parameters from your request’s URL. The code snippet below shows you how to access query parameters within a route handler.
hapi v17
server.route({
method: 'GET',
path: '/',
handler: (request, h) => {
// access request’s query parameter
const params = request.query
console.log(params)
}
})
hapi v16
server.route({
method: 'GET',
path: '/',
handler: function (request, reply) {
// access request’s query parameter
var params = request.query
console.log(params)
reply()
}
})
Based on the exemplary URL from the start of this section, the resulting query parameter object in hapi would look like this:
{
name: 'marcus'
}
Because you’ve only provided a single parameter with key name
and value marcus
, the object contains just this single field. If you pass more parameters with different keys, each of them is available as an individual field. But what if we provide multiple query parameters with the same key
? The following section shows you the details.
Multiple Query Parameters of the Same Name
You’ve seen how to access query parameters in hapi if you only provide a key
once within your request URL. Let’s assume you’re using the following URL that specifies a name
and two filter
.
https://futurestud.io?name=marcus&filter=premium&filter=video
In the process of extending the Future Studio Blog to the upcoming Future Studio University, we’ve added functionality that allows you to filter tutorials based on its type and content. Currently, we have videos available for selected guides, but you can’t filter for them. That will be different within the next major release of our platform (no release date yet, sorry).
You’ve already seen how to access query parameters, let’s recap it again:
hapi v17
server.route({
method: 'GET',
path: '/',
handler: (request, h) => {
// access request’s query parameter
var params = request.query
console.log(params)
}
})
hapi v16
server.route({
method: 'GET',
path: '/',
handler: function (request, reply) {
// access request’s query parameter
var params = request.query
console.log(params)
reply()
}
})
Based on the sample URL in the beginning of this section, we’re expecting the query parameter object to have a field for name
with value marcus
and aren’t sure what happens to filter
. Actually, you may have thought of a list with values and that’s exactly what hapi does and provides: a list of values for the key filter
.
{
name: 'marcus',
filter: [
'video',
'premium'
]
}
Notice: please keep in mind that hapi provides the individual value for a given key if you only pass it once within the request URL. If you add the same key twice or more often, you’ll receive an array of values. Make sure your application is aware of this scenario and can handle it properly. Don’t let users crash your server by adding keys manually within the URL and you’re expecting just a single value but get caught up in an array.
Empty Query Parameter Values
There are various scenarios that can happen and your server received invalid or malformed data. But what happens if the value is missing for the query parameter key?
https://futurestud.io?name=&filter=video
You’ll receive an empty string value for name
.
{
name: '',
filter: 'video
}
Query Parameters After Trailing Slash in Base URL
Adding query parameters to our base URL that doesn’t contain a trailing slash, browsers will add the trailing slash automatically. The functionality stays the same and query parameters get send properly with your request and parsed by hapi.
The following request URLs are actually the same:
https://futurestud.io?name=marcus
# and
https://futurestud.io/?name=marcus
If you request a base URL without trailing slash and query parameters within your browser, it will automatically add it.
The evaluation of query parameters will stay the same for paths other than root and query parameters are valid for those URLs with trailing slash as well, like:
https://futurestud.io/blog/?filter=video
The difference between base URL and URL paths is this: browsers won’t add the trailing slash after your path segment automatically.
Outlook
This guide walked you through the handling of query parameters in hapi. Actually, it’s kind of straight forward, because you’ll receive the individual values already parsed as a JavaScript Object. Please make sure that your app handles empty (undefined|null|{}
), single and arrays of values properly. Be cautious about the input within your implementation and look that your server doesn’t crash due to the query parameter values.
To close the realm of request parameters, you should get a grasp on path parameter handling including multi-segment and wildcard params.
We appreciate feedback and love to help you if there’s a question on your mind. Let us know in the comments or on twitter @futurestud_io.
Make it rock & enjoy coding!