Skip to content

OpenAPI Structure — Info, Paths, and Components Explained

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about OpenAPI Structure. We cover key concepts, practical examples, and best practices to help you master this topic.

The OpenAPI document structure consists of top-level sections including info, servers, paths, components, security, tags, and external docs that together define a complete API contract.

In this tutorial, you will learn every section of the OpenAPI document structure in detail, how they relate to each other, and how to organize your specification for maximum readability and reusability.

What You'll Learn

You will learn the purpose and content of each top-level OpenAPI section, how to structure the paths object with operations, how to use components for reusability, and best practices for organizing large specifications.

Why It Matters

Understanding the document structure is essential for writing valid OpenAPI specs. A well-organized spec is easier to maintain, review, and extend. Poor structure leads to duplicate definitions, missing fields, and validation errors.

Real-World Use

DodaTech splits large OpenAPI specs into multiple files using $ref for reusability. Common schemas like User, Error, and Pagination live in shared files that multiple API specs reference. This reduces duplication and ensures consistent data models across all APIs.

graph TD
  A[openapi.yaml] --> 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[parameters]
  E --> M[securitySchemes]
  A:::current
  classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px

The Info Object

The info object provides metadata about the API. It is the first section developers read.

info:
  title: DodaTech Users API
  description: |
    Comprehensive API for managing users on the DodaTech platform.

    ## Features
    - Create, read, update, and delete users
    - Role-based access control
    - Audit logging for all operations
  termsOfService: https://dodatech.com/terms
  contact:
    name: API Support Team
    url: https://support.dodatech.com
    email: api@dodatech.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  version: 2.1.0

The title and version are required. Description supports Markdown formatting. Contact and license are optional but recommended for public APIs.

The Servers Object

The servers object specifies the base URLs for the API. You can define multiple servers for different environments.

servers:
  - url: https://api.dodatech.com/v2
    description: Production server
  - url: https://staging-api.dodatech.com/v2
    description: Staging server
  - url: http://localhost:3000/v2
    description: Local development

Each server can have variables for dynamic URLs:

servers:
  - url: https://{environment}.dodatech.com/v2
    variables:
      environment:
        default: api
        enum:
          - api
          - staging
          - dev
        description: Deployment environment

The Paths Object

The paths object contains all API endpoints. Each path is a relative URL that maps to an operation object.

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

Path parameters use curly brace syntax:

/users/{userId}:
    get:
      operationId: getUser
      summary: Get a user by ID
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: User details

The Components Object

Components store reusable definitions that can be referenced from anywhere in the spec using $ref.

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
  parameters:
    pageParam:
      name: page
      in: query
      schema:
        type: integer
        default: 1
  responses:
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer

Referencing components:

paths:
  /users:
    get:
      parameters:
        - $ref: "#/components/parameters/pageParam"
      responses:
        "200":
          description: Users list
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
        "404":
          $ref: "#/components/responses/NotFound"

Tags and External Docs

Tags group related endpoints. External docs link to additional guides.

tags:
  - name: Users
    description: Operations related to user accounts
    externalDocs:
      description: User management guide
      url: https://docs.dodatech.com/users
  - name: Authentication
    description: Login, logout, and token management

externalDocs:
  description: Complete API documentation
  url: https://docs.dodatech.com/api

Organizing Large Specifications

For large APIs, split the spec into multiple files:

# Main spec file: openapi.yaml
openapi: 3.1.0
info:
  title: DodaTech Platform API
  version: 1.0.0
paths:
  /users:
    $ref: "./paths/users.yaml"
  /users/{userId}:
    $ref: "./paths/users-userId.yaml"
# Separate file: paths/users.yaml
get:
  operationId: listUsers
  summary: List all users
  parameters:
    - $ref: "../parameters/pagination.yaml"
  responses:
    "200":
      description: Users list
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: "../schemas/User.yaml"

Common Mistakes

  1. Missing required fields — Omitting openapi version, info.title, or info.version. These are the only required fields but without them the spec is invalid.

  2. Path parameters without definitions — Using {userId} in the path but not defining userId in the parameters section. Every path parameter must have in: path and required: true.

  3. Inconsistent component naming — Using different names for the same schema across specs. Standardize names like User, Error, Pagination across all API specs.

  4. Too many levels of nesting — Creating deeply nested $ref chains that are hard to follow. Keep max two or three levels of indirection.

  5. No response definitions — Defining endpoints without any response. Every operation must have at least one response defined, typically 200 for success.

Practice Questions

  1. What are the required fields in the OpenAPI info object?
  2. How do you define multiple server environments in OpenAPI?
  3. What is the purpose of the components section?
  4. How do path parameters work in OpenAPI?
  5. How can you organize a large OpenAPI spec across multiple files?

Challenge

Take the minimal OpenAPI spec from the previous lesson and expand it with a complete info object, two server environments, three paths with multiple operations each, and reusable components for User, Error, and Pagination schemas.

FAQ

Can I have paths without operations?

No. Every path must have at least one operation (get, post, put, patch, delete, head, options, trace). A path with no operations is ignored.

What is the difference between parameters defined inline and in components?

Inline parameters are specific to one operation. Component parameters can be reused across multiple operations using $ref. Use components for common parameters like pagination.

Do I need to define all HTTP methods for each path?

No. Define only the methods your API supports. If a client sends an unsupported method, the API can return 405 Method Not Allowed.

How do I define Webhooks in OpenAPI?

OpenAPI 3.1 added a webhooks section at the document root. It defines events that the API can emit to registered callbacks.

Can I use OpenAPI for non-HTTP APIs?

OpenAPI is designed specifically for HTTP APIs. For event-driven APIs, use AsyncAPI. For gRPC, use Protocol Buffers.

Mini Project

Write a complete OpenAPI 3.1 specification for a task management API with at least five paths (list, create, get, update, delete tasks), reusable User and Task schemas, common parameters for pagination, and common responses for errors. Organize it with at least one $ref to an external file.

What's Next

In the next lesson, you will learn how to define data schemas in OpenAPI components, including types, formats, validation constraints, and relationships between objects.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro