# Xpresser Params Loader
GIT (opens new window) | NPM (opens new window) | DEMO
This plugin provides a middleware generator for requiring/loading url params
# Already installed? Jump to Usage
# About
Most urls in every large application includes parameters (params for short). For example:
# Example Urls
/user/:username
/post/:postId
:username and :postId are params.
Loading these params and finding what they represent can be done in controllers. For example:
// A controller action
function indexPage(http) {
const {username} = http.params;
if (!username) return http.status(404).send(`Username is required!`);
// use param
}
The above method becomes lengthy and redundant overtime as we need to repeat the same code for every single controller action.
With the params-loader plugin we can generate a middleware that will load params and save the loaded params
to http.state
# Middleware Process
- Check if param is defined or return
notFound - if
loadfunction is defined:- Call it, if it throws an error, return
loadErrorelse hold result. - Check if
loadresult value is undefined and returnnotFound - Save
loadresult tohttp.state
- Call it, if it throws an error, return
- Save
paramoriginal value tohttp.state.
# Installation
npm install @xpresser/params-loader
# Or
yarn add @xpresser/params-loader
# Plugins.json
Add npm://@xpresser/params to your plugins.json, if you don't have one then create a new one in your backend
folder.
{
"npm://@xpresser/params-loader": true
}
# Add Types
Add this to your xpresser.d.ts file.
import "@xpresser/params-loader/CustomRequestEngine";
# Define Params
Using the example urls defined above.
Assuming we have a file in our middleware directory ParamsMiddleware.(js|ts)
The example above shows how to register the username and postId params.
username is renamed to user and postId is renamed to post.
Below is a table that shows the options of each param and their descriptions.
# Param Options
| Option | Required | Description |
|---|---|---|
notFound | NO | if param is not found in http.params OR Param exists but has a falsy value before or after load, this function will be called. |
as | NO | Custom name of the param to be saved to http.state |
addToBoot | NO | Add param to the boot state using http.addToBoot() |
load | NO | Function to load the param. |
loadError | NO | Function to handle error if load expects an error to be thrown. |
# Type Definition
import {Http} from "xpresser/types/http";
type Options = {
notFound?: (http: Http, value: any) => any;
as?: string;
addToBoot?: boolean;
load?: (value: any, http: Http) => any;
loadError?: (http: Http, error: Error) => any;
};
# Register Middleware
Just like every other middleware, you can register it while routing using router.path() routes or in controller middleware.
# Via Route Path
router.path('/user/:username', () => {
router.get("=index")
router.post("=update")
}).middleware("Params.username")
The Param.username middleware will be applied to all routes with prefix /user/:username.
# Via Controller
const AppController = {
middlewares: {
"Params.username": ["getUser"],
"Params.postId": ["getPost"]
}
}
The above simply means that
Params.usernamemiddleware will be applied to all actions in its array value e.ggetUser.Params.postIdmiddleware will be applied to all actions in its array value e.ggetPost.
# Accessing Loaded Params
This plugin also extends xpresser's RequestEngine to add a few helper methods to the current request instance.
# loadedParam()
Get a loaded parameter.
# loadedParams()
Get all the loaded params or pick specified param if pick exists as 1st argument.
# hasLoadedParam()
Check if a request has a param loaded.
// let assume `postId` is an optional param and may not be loaded.
function getPost(http){
if(!http.hasLoadedParam()){
return // all posts
}
// else return post
return http.loadedParam('post');
}
# addLoadedParam()
Add a param to the loaded params. This may be useful if you are loading some parameters manually and want to add them to the loaded params.
// Assming we have a custom middleware loading some parameters
async function fileId(http) {
const {fileId} = http.params
// do some checks and loading if needed for example
const file = await File.findOne({id: fileId})
// add to loaded Params
http.addLoadedParam("file", fileId)
return http.next();
}