Introduction: Creating New Resources in an API

Welcome to your first lesson in building the Reading Tracker API with NestJS! In this lesson, you will learn how to let users add new resources — specifically, new books — to your API. In the world of web APIs, a "resource" is just a piece of data, like a book, a user, or a review. When you want to add a new resource, you usually use a POST request. As a reminder, POST request is part of the HTTP protocol and is typically used when the client wants to send data to the server to create a new resource. In our case, the resource is a book.

For example, if you want to let someone add a new book to your reading tracker, you would create a POST endpoint. This endpoint will accept information about the book (like its title and author) and store it in your system. This is a common pattern in almost every web application.

By the end of this lesson, you will know how to:

  • Define a DTO (Data Transfer Object) to validate input.
  • Create a POST endpoint in a controller.
  • Use the UUID library to generate unique IDs for new resources.
What Are UUIDs and Why Do We Need Them?

Every resource in your system (book, user, session) needs a unique identifier. Instead of using simple numbers like 1, 2, 3, we use UUIDs (Universally Unique Identifiers).

A UUID is a long, random-looking string such as: 550e8400-e29b-41d4-a716-446655440000

They are designed to be globally unique, so you can safely generate IDs without worrying about collisions. UUIDs are commonly used in APIs, databases, and distributed systems.

In Node.js, we use the uuid library. Normally, you install it with:

But in the CodeSignal environment, everything is already pre-installed — so you’re ready to use it right away.

Every time we create a new user or book, uuidv4() generates a fresh, unique id.

What Is a DTO and Why It Matters

When someone sends data to your API (for example, to add a new book), you want to make sure the data is correct. This is where a Data Transfer Object (DTO) comes in. A DTO is a simple class that describes what data you expect and helps validate it.

DTO stands for Data Transfer Object. It acts as a contract between the client (like a frontend or mobile app) and your API. When someone wants to send data to your server (like creating a book), they must follow the structure you define in the DTO.

DTOs ensure:

  • Your code knows exactly what shape of data to expect.
  • Invalid or missing data is caught early before it breaks your business logic.
  • The frontend and backend can evolve independently while maintaining agreed structure.

To use these validation decorators, you need to install the validation libraries:

These libraries integrate with NestJS and automatically check incoming data before it reaches your service. If a request doesn’t pass validation (e.g., title is missing), NestJS returns a clear 400 Bad Request response — no manual checks required.

Here’s an example DTO for creating a new book:

Explanation:

  • @IsString() and @IsNotEmpty() are decorators from the class-validator library. They make sure that both title and author are non-empty strings.
Building a POST Endpoint with NestJS

Now, let’s see how to actually create a POST endpoint that uses this DTO. In NestJS, you use a controller to define your endpoints.

Here’s how you set up the POST endpoint for adding a new book:

Explanation:

  • @Controller('books') means all routes in this controller will start with /books.
  • @Post() creates a POST endpoint at /books.
  • @Body() createBookDto: CreateBookDto tells NestJS to take the request body, validate it using the CreateBookDto, and pass it to the create method.
  • The controller then calls the service to actually add the book.

NestJS automatically:

  • Transforms the incoming JSON payload into an instance of the CreateBookDto class.
How the Service Handles New Data

The controller passes the validated data to a service, which handles the logic of adding the new book to your database (in this case, an in-memory array).The service actually creates the new book and assigns it a UUID.

Here’s the service code:

Explanation:

  • The service gets the current list of books from the DatabaseService.
  • It creates a new book object, giving it a unique id.
  • The new book is added to the list and returned.

Example Request:

Example response:

This is what the client will see after successfully adding a book.

Why DTOs, UUIDs and Validation Are Critical in Real Projects

In production applications:

  • You might receive data from untrusted sources — frontend apps, third-party integrations, or mobile apps. You can't rely on them to always send clean data.
  • Validating user input at the boundary (controller level) protects your system from:
    • Missing required fields
    • Malformed types (e.g., title: 123)
    • Security vulnerabilities (e.g., injection attacks)
  • DTOs create a shared contract between frontend and backend teams. If someone changes the API structure, they can quickly detect and fix mismatches.
  • UUIDs guarantee uniqueness across all resources, making your API safe and predictable.

Without DTOs and validation: "Garbage in, garbage out" — your services and database may break or store bad data.

Summary and What’s Next

In this lesson, you learned how to:

  • Use UUIDs to generate unique IDs for books.
  • Use a DTO to validate incoming data for a new resource.
  • Create a POST endpoint in a NestJS controller.
  • Pass validated data to a service to add a new book.

These are the core steps for letting users add new resources to your API. And remember: a clean, validated API is easier to maintain, safer to expose to users, and more pleasant to work with as your project grows. Whether you're building a solo app or collaborating with a frontend team — DTOs, validation, and service delegation will save you hours of debugging. In the practice exercises that follow, you’ll get hands-on experience creating and testing your own POST endpoints with DTOs. This will help you build confidence in handling user input and structuring your API for real-world use.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal