How to get all the body values from a POST request in Nestjs?

February 4, 2022 - 6 min read

To get the body values from the POST method request, you can use the @Body() decorator function from the @nestjs/common module in Nestjs.

TL;DR

import { Controller, Post, Body } from "@nestjs/common";

// DTO
import { PostDTO } from "../dto/post";

// the @Controller() decorator function will instruct Nestjs
// to add a route of `/posts`
@Controller("posts")
export class PostsController {
  // Some Important Points 🌟
  // 1.
  // the @Post() decorator function will instruct Nestjs
  // that this is the default method that should be
  // invoked when the user requests a `POST` to `/posts` endpoint

  // 2.
  // Using `body` parameter to get the values
  // from the body of the request

  // 3.
  // and the `Body()` decorator function will
  // instruct Nestjs to bind the request `body` values to it.

  // 4.
  // Also using the `PostDTO` as the type for the `body` parameter.
  @Post()
  createPost(@Body() body: PostDTO) {
    return `Created a new post with values of ${JSON.stringify(body)} 🚀`;
  }
}

For example, let's say we want to create an API request endpoint called /posts and on a request of the POST method to this endpoint, it should create a new post based on the values from the body of the request.

To do that first, we have to make a controller for the /posts endpoint and then wire up a method that should be invoked when POST requests are made to the /posts endpoint.

It can be done like this,

import { Controller, Post } from "@nestjs/common";

// the @Controller() decorator function will instruct Nestjs
// to add a route of `/posts`
@Controller("posts")
export class PostsController {
  // the @Post() decorator function will instruct Nestjs
  // that this is the default method that should be
  // invoked when the user requests a `POST` to `/posts` endpoint
  @Post()
  createPost() {
    return `Created a new post 🚀`;
  }
}

To know more about creating a POST request endpoint in Nestjs, see the blog on How to make a simple POST request or an API endpoint in Nestjs?.

After creating a POST method request endpoint for the /posts route, we can now take a parameter called body inside the createPost() method.

It can be done like this,

import { Controller, Post, Body } from "@nestjs/common";

// the @Controller() decorator function will instruct Nestjs
// to add a route of `/posts`
@Controller("posts")
export class PostsController {
  // Some Important Points 🌟
  // 1.
  // the @Post() decorator function will instruct Nestjs
  // that this is the default method that should be
  // invoked when the user requests a `POST` to `/posts` endpoint

  // 2.
  // Using `body` parameter to get the values
  // from the body of the request
  @Post()
  createPost(body) {
    return `Created a new post with values of ${JSON.stringify(body)} 🚀`;
  }
}

The problem is that Nestjs runtime doesn't know what value should be injected into the body parameter of the createPost() method. To instruct Nestjs that we need the body values from the request, we should use the @Body() decorator function from the @nestjs/common module before the body parameter. Doing this will bind the body values from the request to the body parameter in the createPost() method.

It can be done like this,

import { Controller, Post, Body } from "@nestjs/common";

// the @Controller() decorator function will instruct Nestjs
// to add a route of `/posts`
@Controller("posts")
export class PostsController {
  // Some Important Points 🌟
  // 1.
  // the @Post() decorator function will instruct Nestjs
  // that this is the default method that should be
  // invoked when the user requests a `POST` to `/posts` endpoint

  // 2.
  // Using `body` parameter to get the values
  // from the body of the request

  // 3.
  // and the `Body()` decorator function will
  // instruct Nestjs to bind the request `body` values to it.
  @Post()
  createPost(@Body() body) {
    return `Created a new post with values of ${JSON.stringify(body)} 🚀`;
  }
}

Now since we are using TypeScript, TypeSript might show an error for the body parameter since we are not using any type for it.

To resolve that we can create something called a DTO (aka Data Transfer Object) in Nestjs, in simple terms a class that defines the values of the body from the request. You may ask why use class instead of an interface? This is because the class is now a standard within the JavaScript specification and it will provide us with a runtime check for the body values. We will discuss validating body values within Nestjs in upcoming blog posts. (I will link to it hereafter it's been published 🤞🏽).

Let's make a new directory called dto and create a file called post.ts. To make this within a terminal use the following commands,

mkdir dto && touch ./dto/post.ts

Now the directory hierarchy will look like this,

- dto
  - post.ts
- post
  - posts.controller.ts

Inside the post.ts file let's create a class called PostDTO with some basic fields called title, description, and content having the string type.

It can be done like this,

dto/post.ts file

// Post DTO (aka Data transfer Object)
// with some basic fields
class PostDTO {
  title: string;
  description: string;
  content: string;
}

export { PostDTO };

Now that we have a well defined DTO for our /posts endpoint let's use it as the type for the body parameter in the createPost() method in the PostsController class like this,

import { Controller, Post, Body } from "@nestjs/common";

// DTO
import { PostDTO } from "../dto/post";

// the @Controller() decorator function will instruct Nestjs
// to add a route of `/posts`
@Controller("posts")
export class PostsController {
  // Some Important Points 🌟
  // 1.
  // the @Post() decorator function will instruct Nestjs
  // that this is the default method that should be
  // invoked when the user requests a `POST` to `/posts` endpoint

  // 2.
  // Using `body` parameter to get the values
  // from the body of the request

  // 3.
  // and the `Body()` decorator function will
  // instruct Nestjs to bind the request `body` values to it.

  // 4.
  // Also using the `PostDTO` as the type for the `body` parameter.
  @Post()
  createPost(@Body() body: PostDTO) {
    return `Created a new post with values of ${JSON.stringify(body)} 🚀`;
  }
}

Now if we send a POST request to the /posts endpoint with the title, description, and the content fields, we can see a response saying that the post has been created with the fields we supplied.

We have successfully got the body values from a POST request in Nestjs.

See the above code live in codesandbox.

Go to Hoppscotch API tester 🚀 to send a POST request to the URL in the above codesandbox container.

NOTE: If you were not able to send a request using the above Hoppscotch URL try turning on the proxy in the app.

That's all 😃!

Feel free to share if you found this useful 😃.