Requests
IntentJS provides a useful Request class. It automatically parses the incoming data, headers, and comes packed with many utilities.
Out of the box Intent supports following Content-Type.
application/jsontext/plainapplication/x-www-form-urlencodedmultipart/form-datatext/htmlapplication/xmlbufferbinary
Using the Request
To get the Request object, you will need to type-hint the Request class from @intentjs/core/http. The incoming request will automatically be injected into the controller's method.
import { Req, Request, Controller } from '@intentjs/core/http';
@Controller('books')
export class BookController {
@Post('')
async create(@Req() req: Request) {
const payload = req.all();
const name = payload.name
return { msg: 'Book Created Successfully!' };
}
}In the next section, you will see how can access the data we receive inside the request object using the Route Param Decorators
Route Param Decorators
The request object represents the HTTP Request and has properties of the query string, paramters, HTTP headers, etc. To access these data inside your route handler, you can use the dedicated decorators, such as @Body() or @Query(). Below is the complete list of decorators and their descriptions available.
| Decorator | Description |
|---|---|
@Req() | The Raw HTTP Request Object |
@Res() | The Raw HTTP Response Object, read more about it here |
@Dto() | Injects the instance of the class against which you do the typing |
@Query(key?: string) | Injects the value of the key present in the query param, if no key is passed, injects an object. |
@Param(key?: string) | Injects the value of the key present in the path param, if no key is passed, an object is injected. |
@Body(key?: string) | Injects the value of the key present in the body, if no key is passed, an object is injected. |
@Header(key? :string) | Injects the value of the header key passed, if no key is present, all headers are injected. |
@IP() | Injects the IP of the client |
@UserAgent() | Injects the user agent of the client |
@Host() | Injects the hostname of the client |
@Accepts() | Injects the accept header of the request |
@BufferBody() | Injects the payload as a buffer |
Let's see how we can use these decorators.
Request
To inject a Raw HTTP request object inside your route handler, you can make use of the @Req() decorator.
@Get('')
async get(@Req() req: Request) {
console.log(req)
}DTOs
To enable strict typing inside your request payloads, you can make use of the @Dto() decorator. Intent internally uses class-transformer to convert the request payload into a strongly typed class instances.
export class LoginDto {
email: string;
password: string;
}@Post('login')
async get(@Dto() dto: LoginDto) {
console.log(dto);
}Query Params
To inject values received from query string inside your route handler, you can make use of the @Query decorator.
@Post('login')
async get(@Query('page') page: number) {
console.log(page);
}
@Post('register')
async get(@Query() queryParams: Record<string, any>) {
console.log(queryParams); // injects the complete query params object
}Path Params
To inject values received from path parameters inside your route handler, you can make use of the @Param decorator.
@Get('users/:id')
async get(@Param('id') id: string) {
console.log(id);
}
@Get('users/:id/:key')
async get(@Param() params: Record<string, any>) {
console.log(params); // injects the complete path params object
}Body
To inject the values received from path parameters inside your route handler, you can make use of the @Body decorator.
@Post('login')
async get(@Body('email') email: string) {
console.log(email)
}
@Post('register')
async get(@Body() payload: Record<string, any>) {
console.log(payload); // injects the complete body object
}Headers
To inject the headers inside your route handler
@Post('register')
async get(@Header() headers: Record<string, any>) {
console.log(headers); // injects the complete headers object
}IP Address
To inject the IP of the client, you can use the @IP decorator.
@Post('register')
async get(@IP() ip: string) {
console.log(ip);
}User Agent
To inject the user agent of the client
@Post('register')
async get(@UserAgent() agent: string) {
console.log(agent);
}Host
To inject the req.hostname you can use the @Host decorator.
@Post('register')
async get(@Host() host: string) {
console.log(host);
}Accepts Header
To inject the accepts header you can use the @Accepts decorator.
@Post('register')
async get(@Accepts() accepts: string) {
console.log(accepts);
}Buffer Body
There could be situations where you will need the raw payload of the request for example to calculate x-signature. If you would like to get all of the body as a buffer, you can use the BufferBody decorator.
@Post('register')
async get(@BufferBody() bufferBody: Buffer) {
console.log(bufferBody);
}Custom Decorator
If you would like to make your own route param decorator, you could do so easily by making use of the createParamDecorator function.
import { createParamDecorator, ExecutionContext } from '@intentjs/core/http';
export const CustomParam = createParamDecorator(
(data: any, ctx: ExecutionContext, argIndex: number) => {
return 'data from custom decorator param';
},
);Request Inputs, Host, Path and Methods
INFO
If you are more used to the approach of accessing the Request instance inside your route handler, IntentJS provides some helpful methods to perform the same operations that you could do by just using the dedicated decorators we discussed above.
The Request instance comes packed with variety of methods.
Retrieving Inputs from Payload
To retrieve input for a particular key from the Request instance, you can use input method.
const name = req.input('sportsperson');
// Virat KohliYou can also pass the second argument as the default value to the input method. If the passed key is not present inside the payload, it will return the default value.
const name = req.input('sportsperson', 'Rohit Sharma');
// Rohit SharmaIf you want to get the complete payload from the req object, you can use all method, this would give you a unified object of path, query and body params.
INFO
The objects are spread in the order of path, query and body. So all the keys present in the body will be overriding the intersecting keys present in query and path params.
const inputs = req.all();WARNING
req.all() method only works when the Content-Type is application/json, application/x-www-form-urlencoded, multipart/form-data.
If you want to fetch a value as a string, you can use string method
const str = req.string('name');Alternatively, if you want to fetch a value parsed as a number, you can use the number method
const num = req.number('amount');If you would to fetch a value as a boolean, you can use the boolean method, this method returns true for all 'truthy' values. It would return true for 1, '1', true, 'true', 'yes', 'on', for all other values it would return false;
const bool = req.boolean('tncAgreed');INFO
If you try to access values which cannot be typed by Request, it will return undefined. It doesn't throw error because it can cause errors at runtime.
Accessing Query Parameters
If you want to specifically access query parameters, you can make use of query method inside the IntentRequest object.
To access a query param, you can pass the key to the query method like below.
const query = req.query('page');If you don't pass any argument to it, it would return all query params.
Input Presence
There can be situations where you want to just check if a particular key is present inside the payload or not. To do so, you can make use of has or hasAny method.
Using has method, you can check if a particular key is present inside the payload or not.
if (req.has('email')) {
// ...
}Similarly, if you want to check if either of keys are available or not, you can pass multiple keys to the same has method. It will return true as soon as any of the passed keys are present inside the payload.
if (req.has('email', 'phone')) {
// ...
}Accessing the Headers
Headers are important if you are building a REST API as they provide lots of meta information which you can use in your application. Request offers useful methods for headers which you can use.
To get a header by it's key, you can use the header method
const authorization = req.header('authorization');You can also pass the second argument as the default value to the header method. If the passed key is not present inside the payload, it will return the default value.
If you want to get all of the headers, you can use the headers method.
const headers = req.headers();As most of the REST APIs, use JWT for authentication, Request comes with a bearerToken method to help you easily fetch the bearer token without doing the hassle of parsing the header yourself. You can use the method like below
const token = req.bearerToken();To check if a request has a specific header, you can make use of hasHeader method.
if (req.hasHeader('authorization')) {
// ...
}If you want to check for multiple headers, you can simply pass the headers to the same hasHeader method only. It will return true if any one of the header is present inside the request.
if (req.hasHeader('authroization', 'cookie')) {
// ...
}Playing with Content Types
Request comes with variety of methods through which you can use to fetch and check for certain content types in your application.
To check if a particular request expects JSON, you can use expectsJson method.
if (req.expectsJson()) {
// ...
}To get all acceptable content types you can use getAcceptableContentTypes method.
const contentTypes = req.getAcceptableContentTypes();