Last week’s tutorial on hapi walked you through optional path parameters and showed you how to specify routes leveraging optional parameters in their path. Within this week’s guide you’ll learn about route definitions using wildcard path parameters to match routes with multiple segments.
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
Wildcard Parameters on Routes
Besides optional path parameters, you can make use of wildcard parameters for your route specifications that allow multiple path parameter segments. Each segment is divided by a forward slash /
.
On the hapi route definition, wildcard parameters are indicated by using the asterisk *
character followed by a number at the end of defined parameter name.
hapi v17
server.route({
method: 'GET',
path: '/js/{file*}',
handler: (request, h) => {
const params = request.params
return params
}
})
hapi v16
server.route({
method: 'GET',
path: '/js/{file*}',
handler: function (request, reply) {
var params = request.params
reply(params)
}
})
Actually, you can omit the number of segments and hapi will match any available number of segments (like we did in the example above). We’ll have a detailed look at defining multiple segments in the section below.
hapi parses the provided path parameters within the request URL and provides access
to them within an object that is available via request.params
.
For now, let’s visualize the usage of wildcard parameters based on the code snippet from above and the following base URL:
https://futurstud.io/
The code example above indicates that the route will serve JS files. A request to the URL
https://futurstud.io/js/test.js
will result in the following parsed path parameter object:
{
file: 'test.js'
}
You might ask yourself, what if I’m going to request a JS file that has a “nested” location within your project and is not at the same level like the test.js
file? How would I define the route? Actually, your route is already defined :)
The wildcard route as you’ve defined like in the code block above already matches requests with multiple segments. hapi provides the value for your parameter name (here file
) as a complete string.
Imagine a request to
https://futurestud.io/js/vuejs/vue.min.js
will result in the parsed path parameter values of
{
file: 'vuejs/vue.min.js'
}
You can read more about serving static files with hapi within the previously published tutorial in this hapi series.
Multi-Segment (Wildcard) Parameters
If you expect a fixed amount of parameters for a given route, you can define them using a number after the asterisk.
hapi v17
server.route({
method: 'GET',
path: '/filter/{type*2}',
handler: (request, reply) => {
// this route matches only if 2 path segments are provided after "filter"
const params = request.params
return params
}
})
hapi v16
server.route({
method: 'GET',
path: '/filter/{type*2}',
handler: function (request, reply) {
// this route matches only if 2 path segments are provided after "filter"
var params = request.params
reply(params)
}
})
Be aware that the route above only matches on requests to /filter/<first-value>/<second-value>
. If you provide only a single value or more than two values, hapi won’t match this definition.
Let’s illustrate how the path parameters will look if your request URL looks like this:
https://futurestud.io/filter/video/premium
Results in a path parameter object like this:
{
type: 'video/premium'
}
Notice that hapi will keep the forward slash /
within the parameter string. You can get the individual values by using request.params.type.split('/')
and access them within the resulting array. Adjust the manipulation of your received parameters to your needs :)
Only Last Named Path Parameter Can Be Optional
You can’t define a route having a wildcard parameter in the middle of your path. Actually, this restriction is kind of obvious when creating an exemplary route’s path like /filter/{type*2}/comments/{commentId}
. Creating a request without providing two segments for type
, the URL will look like /filter///comments/123
and that’s an invalid request URL.
Notice: only the last named path parameter can be optional.
Also, there’s no fallback solution or default values for wildcard parameters. Meaning, you can’t work around hapi routes to make use of optional path parameters using predefined values.
Outlook
Hopefully this guide shows you the advantages of wildcard parameters and how to apply them for multiple segments. Please keep in mind that hapi only allows the last named parameter to be optional and that applies to wildcard parameters as well.
At this point you know the fundamentals on how to handle incoming data with requests. Next stop: how to validate incoming data within the request payload using the joi library.
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!