Skip to content

OpenAPI / Swagger Specification Guide — Step-by-Step

DodaTech Updated 2026-06-23 8 min read

In this tutorial, you'll learn about OpenAPI / Swagger Specification Guide. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The OpenAPI Specification (formerly Swagger) is a standard, language-agnostic format for describing REST APIs using YAML or JSON, enabling automated documentation, client generation, and API testing.

What You'll Learn

You will learn to write OpenAPI 3.1 specifications from scratch, define endpoints, parameters, request bodies, responses, security schemes, and generate interactive documentation automatically.

Why OpenAPI Matters

OpenAPI has become the industry standard for API description. It eliminates ambiguity in API contracts, enables automatic Code Generation for 40+ languages, and powers tools like Swagger UI, Swagger Editor, and Stoplight. Teams using OpenAPI ship APIs 50 percent faster with fewer integration bugs.

Real-World Use

DodaTech uses OpenAPI to document all internal and external APIs. Doda Browser sync API, DodaZIP update service, and Durga Antivirus Pro threat intelligence endpoints all have OpenAPI specifications that generate client libraries automatically for web, desktop, and mobile platforms.

OpenAPI Specification Learning Path

flowchart LR
  A[REST API Design] --> B[OpenAPI Basics]
  B --> C[Paths & Operations]
  C --> D[Schemas & Components]
  D --> E[Security Schemes]
  E --> F[Code Generation]
  F --> G[API Documentation]
  B:::current

  classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px

Prerequisites

You should understand RESTful Api Design Best Practices before writing OpenAPI specs. Familiarity with JSON Data Format and YAML syntax is helpful. Knowing HTTP Protocol Basics methods and status codes is required.

What is OpenAPI?

OpenAPI is a specification for describing RESTful APIs. It defines a standard way to describe:

  • Available endpoints and operations (GET, POST, PUT, DELETE)
  • Input parameters (path, query, header, cookie)
  • Request bodies and data schemas
  • Response formats and status codes
  • Authentication methods
  • Contact information, license, and terms of service
  • Servers where the API is hosted

An OpenAPI specification can be written in YAML or JSON. YAML is more common because it is more readable.

OpenAPI Document Structure

graph TD
  A[openapi: 3.1.0] --> B[info]
  A --> C[servers]
  A --> D[paths]
  A --> E[components]
  A --> F[security]
  A --> G[tags]
  D --> H[/users]
  D --> I[/users/{id}]
  E --> J[schemas]
  E --> K[responses]
  E --> L[securitySchemes]
  E --> M[parameters]

Writing Your First OpenAPI Spec

Step 1: The Basic Structure

openapi: 3.1.0
info:
  title: DodaTech Users API
  description: Manage users for DodaTech platform services
  version: 1.0.0
  contact:
    name: API Support
    email: api@dodatech.com
servers:
  - url: https://api.dodatech.com/v1
    description: Production server
  - url: https://staging-api.dodatech.com/v1
    description: Staging server
paths:
  /users:
    get:
      summary: List all users
      operationId: listUsers
      responses:
        "200":
          description: A list of users

This is a minimal valid OpenAPI 3.1 specification. It defines one endpoint that returns a list of users.

Step 2: Defining Paths and Operations

Each path can have multiple operations (get, post, put, patch, delete).

paths:
  /users:
    get:
      summary: List all users
      operationId: listUsers
tags:
        - Users
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
    post:
      summary: Create a new user
      operationId: createUser
tags:
        - Users
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateUserRequest"
      responses:
        "201":
          description: User created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"
        "422":
          description: Validation error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

Step 3: Defining Schemas in Components

Schemas define the structure of your data.

components:
  schemas:
    User:
      type: object
      required:
        - id
        - name
        - email
      properties:
        id:
          type: integer
          format: int64
          description: Unique identifier
        name:
          type: string
          description: Full name of the user
        email:
          type: string
          format: email
          description: Email address
        createdAt:
          type: string
          format: date-time
          description: Account creation timestamp
    CreateUserRequest:
      type: object
      required:
        - name
        - email
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 100
        email:
          type: string
          format: email
        password:
          type: string
          format: password
          minLength: 8
    Error:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
        details:
          type: array
          items:
            type: string

Step 4: Adding Parameters

Define parameters for filtering, sorting, and pagination.

parameters:
  listUsersPage:
    name: page
    in: query
    description: Page number for pagination
    schema:
      type: integer
      minimum: 1
      default: 1
  listUsersLimit:
    name: limit
    in: query
    description: Number of items per page
    schema:
      type: integer
      minimum: 1
      maximum: 100
      default: 20

Step 5: Security Schemes

OpenAPI supports multiple authentication methods.

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://auth.dodatech.com/oauth/authorize
          tokenUrl: https://auth.dodatech.com/oauth/token
          scopes:
            read:users: Read user data
            write:users: Create and update users

security:
  - BearerAuth: []

Step 6: Reusable Responses

Define common responses once and reference them.

components:
  responses:
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Authentication required
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    ValidationError:
      description: Validation failed
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"

Using OpenAPI Tools

Swagger UI

Swagger UI renders your OpenAPI spec as interactive documentation. Users can test endpoints directly from the browser.

# Using Swagger UI with Docker
docker run -p 8080:8080 -e SWAGGER_JSON=/spec/openapi.yaml -v $(pwd):/spec swaggerapi/swagger-ui

Swagger Codegen

Generate server stubs and client libraries from your spec.

# Generate a Python client
npx @openapitools/openapi-generator-cli generate \
  -i openapi.yaml \
  -g python \
  -o /tmp/python-client

# Generate a Node.js Express server stub
npx @openapitools/openapi-generator-cli generate \
  -i openapi.yaml \
  -g nodejs-express-server \
  -o /tmp/server-stub

Validating Your Spec

Validate your OpenAPI spec to catch errors early.

# Using swagger-cli
Npm install -g swagger-cli
swagger-cli validate openapi.YAML
# Expected output: openapi.YAML is valid

# Using openapi-validator
npx ibm-openapi-validator openapi.YAML

Complete Example

Here is a complete OpenAPI 3.1 specification for a simple task management API:

openapi: 3.1.0
info:
  title: DodaTask API
  description: Task management API for DodaTech productivity suite
  version: 1.0.0
servers:
  - URL: HTTPS://API.dodatech.com/v1
paths:
  /tasks:
    get:
      operationId: listTasks
      summary: Retrieve all tasks
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [pending, completed, archived]
      responses:
        "200":
          description: List of tasks
          content:
            application/JSON:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Task"
    post:
      operationId: createTask
      summary: Create a new task
      requestBody:
        required: true
        content:
          application/JSON:
            schema:
              $ref: "#/components/schemas/CreateTask"
      responses:
        "201":
          description: Task created
          content:
            application/JSON:
              schema:
                $ref: "#/components/schemas/Task"
  /tasks/{taskId}:
    get:
      operationId: getTask
      summary: Get a single task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Task details
          content:
            application/JSON:
              schema:
                $ref: "#/components/schemas/Task"
        "404":
          $ref: "#/components/responses/NotFound"
    delete:
      operationId: deleteTask
      summary: Delete a task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "204":
          description: Task deleted
        "404":
          $ref: "#/components/responses/NotFound"
components:
  schemas:
    Task:
      type: object
      properties:
        id:
          type: integer
        title:
          type: string
        description:
          type: string
        status:
          type: string
          enum: [pending, completed, archived]
        dueDate:
          type: string
          format: date
    CreateTask:
      type: object
      required:
        - title
      properties:
        title:
          type: string
        description:
          type: string
        dueDate:
          type: string
          format: date
  responses:
    NotFound:
      description: The specified resource was not found
      content:
        application/JSON:
          schema:
            type: object
            properties:
              message:
                type: string

Common Errors

  1. Missing required fields in schemas — Defining properties without marking required fields. Clients may send incomplete data and the server receives unexpected null values. Always specify which fields are required using the required array.

  2. Incorrect indentation in YAMLYAML is sensitive to indentation. Using spaces and tabs inconsistently causes Parsing errors. Use a YAML linter to validate your file.

  3. Using unreferenced schemas — Defining schemas in components but never using $ref to reference them. Unreferenced schemas are unused and bloat the specification.

  4. Missing response definitions — Not defining error responses like 400, 401, 404, and 500. Clients need to know what error formats to expect. Define common error responses in components and reuse them.

  5. Incorrect path parameter definitions — Using {paramName} in the path but not defining it in the parameters section. The path parameter must have a corresponding parameter definition with in: path and required: true.

  6. Overly complex schemas — Creating deeply nested schemas with many levels of $ref. Keep schemas flat by extracting reusable components.

  7. Not specifying content types — Omitting the content field under requestBody or responses. Always specify application/json or other media types explicitly.

Practice Questions

  1. What is the difference between OpenAPI 3.0 and 3.1 regarding JSON Schema support?
  2. How do you define a path parameter in OpenAPI?
  3. What is the purpose of the components section?
  4. How do you specify that an endpoint requires authentication?
  5. What tool can you use to generate a Python client from an OpenAPI spec?

Challenge

Write a complete OpenAPI 3.1 specification for a document management API. The API should support creating, reading, updating, and deleting documents. Documents have a title, content, author, and tags. The API should support filtering by tags and pagination. Include security schemes for both JWT and API key authentication. Validate your spec using swagger-cli validate.

FAQ

What is the difference between Swagger and OpenAPI? Swagger is the original name of the specification developed by SmartBear. In 2016, the specification was donated to the OpenAPI Initiative and renamed to OpenAPI. Swagger tools (Swagger UI, Swagger Editor) are now open-source tooling that works with OpenAPI specs.

Can I use OpenAPI for non-HTTP APIs? OpenAPI is designed specifically for HTTP APIs. For other protocols, consider gRPC with Protocol Buffers or AsyncAPI for event-driven APIs.

Should I write the OpenAPI spec before or after implementing the API? Write the spec before implementation (API-first approach). This forces you to think through the contract before coding, catches design issues early, and lets frontend and backend teams work in parallel.

How do I handle file uploads in OpenAPI? Use multipart/form-data content type with type: string and format: binary for the file field. OpenAPI supports both single and multiple file uploads.

Is OpenAPI only for REST APIs? OpenAPI is designed for RESTful HTTP APIs. For GraphQL, use the GraphQL schema language. For SOAP, use WSDL. For gRPC, use Protocol Buffers.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro