Sling Academy
Home/Node.js/How to Extract and Parse Headers in NestJS

How to Extract and Parse Headers in NestJS

Last updated: December 31, 2023

Introduction

In NestJS, a powerful server-side JavaScript framework built with TypeScript, handling request headers is crucial for many web applications. This guide will discuss how to effectively extract and parse request headers in NestJS, enabling fine-grained request inspection and manipulation.

Basic Header Extraction

To start off, let’s discuss the basics of how to extract headers from incoming HTTP requests in NestJS. Typically, you use decorators to achieve this.

First, ensure your NestJS environment is set up. If you need to install NestJS, you can do so using the following command:

npm i -g @nestjs/cli
nestjs new my-project
cd my-project
npm run start

Next, in your controller, import Headers from @nestjs/common package and use it as a decorator for your route handler’s argument:

import { Controller, Get, Headers } from '@nestjs/common';

@Controller('demo')
export class DemoController {
  @Get()
  getHeaders(@Headers() headers: any) {
    console.log(headers);
    return headers;
  }
}

The @Headers() decorator provides the headers object, which contains all the request headers.

Parsing Specific Headers

If you’re interested in a specific header, you can supply its name as a parameter to the @Headers() decorator:

import { Controller, Get, Headers } from '@nestjs/common';

@Controller('demo')
export class DemoController {
  @Get('special')
  getSpecificHeader(@Headers('authorization') authHeader: string) {
    console.log(authHeader);
    return authHeader;
  }
}

This code will extract the Authorization header and make it available in your handler method.

Using DTOs to Parse Headers

For a more structured approach, especially when dealing with multiple headers or when you want to enforce specific types, you can use DTOs (Data Transfer Objects).

import { Controller, Get, Headers } from '@nestjs/common';

class HeaderDto {
  'user-agent': string;
  authorization?: string;
}

@Controller('demo')
export class DemoController {
  @Get('dto')
  getDtoHeaders(@Headers() headers: HeaderDto) {
    console.log(headers);
    return headers;
  }
}

In the above example, we have a DTO that expects the User-Agent and optionally the Authorization header. NestJS will automatically attempt to match and assign the incoming headers to this DTO object.

Advanced Header Parsing with Pipes

For advanced scenarios, you may want to transform or validate headers. NestJS provides pipes for these tasks. Below is an example of how you might create a pipe to validate an API key passed in a header:

import { Injectable, PipeTransform, BadRequestException } from '@nestjs/common';

@Injectable()
export class ApiKeyPipe implements PipeTransform {
  transform(value: any): string {
    if (!value.authorization) {
      throw new BadRequestException('API key not provided');
    }

    if (value.authorization !== 'expected-api-key') {
      throw new BadRequestException('Invalid API key');
    }
    return value.authorization;
  }
}

Apply your pipe in your controller:

import { UsePipes } from '@nestjs/common';

@Controller('secure')
export class SecureController {
  @Get()
  @UsePipes(new ApiKeyPipe())
  secureEndpoint(@Headers() headers: any) {
    return 'Access granted';
  }
}

With @UsePipes(), the ApiKeyPipe will validate every request to the secured endpoint.

Extracting Header Arrays

HTTP allows multiple values for the same header under certain conditions. You can extract such values in NestJS by just looking for them in the headers object:

import { Controller, Get, Headers } from '@nestjs/common';

@Controller('array')
export class ArrayHeaderController {
  @Get()
  getArrayHeaders(@Headers('set-cookie') cookies: string[] | string) {
    console.log(Array.isArray(cookies) ? cookies : [cookies]);
    return cookies;
  }
}

In cases when multiple headers are present, the value is an array, otherwise it’s a single string.

Typing and Interfaces

To further enforce clean code and type safety, you can use TypeScript interfaces:

import { Controller, Get, Headers } from '@nestjs/common';

interface MyHeaders {
  authorization?: string;
  'user-agent': string;
}

@Controller('typed')
export class TypedController {
  @Get()
  getTypedHeaders(@Headers() headers: MyHeaders) {
    console.log(headers);
    return headers;
  }
}

Applying interfaces can help to prevent accessing undefined headers and improve overall code reliability.

Conclusion

The process of extracting and parsing headers in NestJS is straightforward but powerful. By using decorators, DTOs, pipes, and interfaces, you can effortlessly manage request headers and inject only what your application needs. Mastering these capabilities allows you to write more secure, efficient, and maintainable NestJS applications.

Next Article: How to Return Raw HTML in NestJS

Previous Article: How to Log Requests in NestJS

Series: Nest.js Tutorials: From Basics to Advanced

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates