Request Parameters
In RapidREST, the arguments of each HTTP handler function are composable, taking any number of arguments, whose values are injected by the framework
at execution time. This provides two key benefits over more traditional frameworks that use func(req, res, next) architecture. First, only the
data needed to process the request is injected into the handler function, thereby signficantly reducing code complexity. Second, declaring the
injected arguments in the function definition improves code readability and serves to self-document the code.
The following table describes all injectable value types for an HTTP handler function.
| Decorator | Resolves to |
|---|---|
@Param(name?) | req.params[name], or the whole params object if name is omitted |
@Query(name?) | req.query[name], or the whole query object if name is omitted |
@Header(name) | req.headers[name] |
@Request | the whole HttpRequest object (no parentheses) |
@Response | the whole HttpResponse object (no parentheses) |
@Socket | the underlying WebSocket, for @WebSocket handlers (no parentheses) |
@User | the authenticated user (req.auth?.user), if any (no parentheses) |
@AuthResult | the full auth result object (no parentheses) |
The following example illustrates three injected values for the GET /:id request handler; @Param('id'), @Query('version'), and @User.
@Get('/:id')
async getPet(@Param('id') id: string, @Query('version') version: string, @User user?: JWTUser) {
/* ... */
}
The @Param('id') injected value will extract the :id portion of the HTTP request's path (e.g. GET /my-pet → my-pet). The @Query('version')
portion will extract the value for the query paramater key version (e.g. GET /my-pet?version=3 → 3). Finally, the @User injects the
authenticated user (if applicable).
The @Request-injected object also carries req.cookies and, if sessions are configured, req.session — see
HTTP Engine → Sessions and HTTP Engine → Cookies & CORS.
The request body
The first handler argument that isn't decorated automatically receives the parsed request body. Note that this can be anywhere in the function definition, with preceding injected arguments and/or proceeding injected arguments as shown in the examples below.
@Post()
async createPet(pet: Pet) {
// `pet` is the parsed JSON body, no decorator needed
return this.petService.create(pet);
}
@Post()
async createPet2(@Query() query: any, pet: Pet) {
// `pet` is the parsed JSON body, no decorator needed
return this.petService.create(pet);
}
@Post()
async createPet3(pet: Pet, @User user: JWTUser) {
// `pet` is the parsed JSON body, no decorator needed
return this.petService.create(pet);
}
@Post()
async createPet4(@Query() query: any, pet: Pet, @User user: JWTUser) {
// `pet` is the parsed JSON body, no decorator needed
return this.petService.create(pet);
}
WebSocket example
When defining a WebSocket handler function it is necessary to have at least one @Socket decorated argument in order to implement the WebSocket
connection. If no @Socket argument is defined, the connection will be automatically closed.
@WebSocket('/connect')
onConnect(@Query('message') message: string, @Socket ws: WebSocket, @User user?: any) {
ws.on('message', (msg) => ws.send(`echo ${message ?? ''} ${msg}`));
}