OpenAPI

⭐ Interview Importance: HIGH
⏱️ Revision Time: 8 min

OpenAPI (formerly known as Swagger) is a specification for machine-readable interface files for describing, producing, consuming, and visualizing RESTful web services.

Overview

Before writing code for endpoints, or immediately after, it is vital to document them so that frontend teams (or external consumers) know exactly what data they can send and what they will receive.

Instead of writing this documentation manually in a Wiki, modern development relies on the OpenAPI Specification. NestJS leverages this standard to auto-generate documentation directly from your TypeScript code.

Key Concepts

  • Specification: A JSON or YAML file that describes your entire API (routes, inputs, outputs, authentication methods).
  • Swagger UI: A web-based user interface that reads the OpenAPI JSON/YAML file and generates a beautiful, interactive webpage where developers can test your API.
  • Contract-First vs. Code-First:
    • Contract-First: You write the OpenAPI YAML file by hand, and then generate the backend code from it.
    • Code-First: (NestJS Default) You write your backend code using decorators, and NestJS generates the OpenAPI JSON automatically.

Code Examples

The Underlying JSON (What NestJS Generates)

While you rarely write this by hand in NestJS, it is crucial to understand what the @nestjs/swagger module is actually building behind the scenes.

When you set up Swagger in a NestJS app and navigate to /api-json, you will see a massive JSON object that looks like this:

{
  "openapi": "3.0.0",
  "info": {
    "title": "Cats API",
    "description": "The Cats API description",
    "version": "1.0",
    "contact": {}
  },
  "tags": [],
  "servers": [],
  "components": {
    "schemas": {
      "Cat": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "age": {
            "type": "number"
          }
        },
        "required": [
          "name",
          "age"
        ]
      }
    }
  },
  "paths": {
    "/cats": {
      "post": {
        "operationId": "CatsController_create",
        "summary": "Create cat",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Cat"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The record has been successfully created."
          }
        }
      }
    }
  }
}

Best Practices

  • Always Keep It Updated: The biggest advantage of the “Code-First” approach in NestJS is that your documentation is tightly coupled to your code. If you add a new required property to a DTO, the documentation updates automatically.
  • Share the JSON: You can provide the /api-json endpoint URL to your frontend team. They can use tools like openapi-generator to automatically generate all the frontend TypeScript interfaces and Axios API clients, completely eliminating the need to write HTTP fetch logic manually!