How to Describe API Goals with the OpenAPI Specification (OAS): A Complete Beginner-to-Advanced Guide

How to Describe API Goals with the OpenAPI Specification (OAS): A Complete Beginner-to-Advanced Guide

When I sit down to build a new API, the first thing I do isn’t write code. It’s write a contract. That contract is the OpenAPI Specification, or OAS, and in this guide I want to walk you through exactly how I use it to describe what an API is actually trying to achieve — not just its endpoints, but its purpose, its promises, and its boundaries.

If you’re new to API design, or you’ve used Swagger/OpenAPI before but only ever copy-pasted YAML without really understanding why it’s structured the way it is, this article is for you. I’m going to explain everything in plain, easy English, and I’ll expand into every sub-topic I think you need to know to actually design good APIs, not just document them after the fact.

What “Describing API Goals” Really Means

A lot of people think OpenAPI is just documentation. That’s a huge underestimation of what it does. When I describe an API’s goals with OAS, I’m answering these questions before I write a single line of backend code:

OpenAPI gives me a machine-readable and human-readable way to answer all of this. It’s not an afterthought — it’s the blueprint. I always compare it to an architect’s drawing. You don’t start pouring concrete before you know the shape of the building.

Why Design-First Beats Code-First

There are two common approaches to building APIs:

  1. Code-first: You write your backend logic, then generate an OpenAPI document from your code (using annotations or reflection).
  2. Design-first: You write the OpenAPI document first, review it, get feedback, and only then start implementing.

I almost always recommend design-first, and here’s why. When you design first, you’re forced to think about the consumer’s experience before you think about your database schema or your framework’s quirks. It separates “what the API does” from “how it’s implemented,” which means:

I keep a personal collection of API design patterns and starter templates on my GitHub at github.com/aw-junaid, and I regularly write about these workflows on my blog at awjunaid.com if you want to see real working examples alongside this theory.

The Anatomy of an OpenAPI Document

Every OpenAPI document, whether written in YAML or JSON, has a predictable skeleton. Let me break down each part and explain what “goal” it serves.

1. The openapi Field

openapi: 3.1.0

This simply tells any tool reading the file which version of the spec you’re using. I always pin this explicitly because tools behave differently across 3.0.x and 3.1.x, especially around JSON Schema compatibility (more on that in my next article about JSON Schema and OAS).

2. The info Object — Where the “Goal” Lives First

info:
  title: Order Management API
  description: >
    This API allows retail partners to create, track, and cancel
    customer orders in real time, replacing the legacy batch-file
    integration process.
  version: 1.2.0
  contact:
    name: API Support Team
    email: support@example.com
  license:
    name: Apache 2.0

This is where I write the actual mission statement of the API. I don’t just say “Order API” — I explain who it’s for and what problem it solves. A well-written description field here does more to communicate intent than a hundred lines of code comments.

I treat this section like the opening paragraph of a book. If a new engineer, a product manager, or an external partner reads only this, they should understand exactly why the API exists.

3. Servers — Describing Where the Goal Is Fulfilled

servers:
  - url: https://api.example.com/v1
    description: Production server
  - url: https://sandbox.api.example.com/v1
    description: Sandbox for testing

I always include multiple environments here. It communicates a goal too: “you can test this safely before going live.” Consumers appreciate knowing there’s a sandbox without having to ask.

4. Paths — The Verbs and Nouns of Your API’s Purpose

This is the heart of the document. Every path and operation should map directly back to a real user goal.

paths:
  /orders:
    post:
      summary: Create a new order
      operationId: createOrder
      description: >
        Creates a new customer order. This is typically the first
        step in the checkout flow.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderRequest'
      responses:
        '201':
          description: Order created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Order'
        '400':
          description: Invalid order payload
        '409':
          description: Duplicate order detected

Notice how every operation has a summary and description. I never skip these. The summary is a short, scannable phrase; the description is where I explain the actual business goal, edge cases, and any side effects (like triggering an email notification, or reserving inventory).

I also always fill in operationId. This isn’t just cosmetic — code generators use it to name functions in generated SDKs. A vague operationId like doThing1 becomes a vague method name in every generated client library, which frustrates consumers.

Turning Business Requirements into OpenAPI Goals

Here’s a practical exercise I go through every time I start a new API design. I take a business requirement, written in plain English, and translate it step-by-step into an OpenAPI structure.

Business requirement: “Partners should be able to check the delivery status of an order without needing full order details.”

My translation process:

  1. Identify the resource: order (specifically, its status).
  2. Identify the operation: read-only, so GET.
  3. Decide on a lightweight response, separate from the full order object, to respect the “without needing full order details” requirement.
  4. Design the path: GET /orders/{orderId}/status.
  5. Define a slim schema: OrderStatus with fields like status, updatedAt, estimatedDelivery.
/orders/{orderId}/status:
  get:
    summary: Get order delivery status
    operationId: getOrderStatus
    parameters:
      - name: orderId
        in: path
        required: true
        schema:
          type: string
    responses:
      '200':
        description: Current delivery status
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderStatus'
      '404':
        description: Order not found

This is what I mean by describing goals with OAS — every field, every path, every response code traces back to an actual requirement, not a guess.

Documenting Non-Functional Goals Too

APIs don’t just have functional goals (“create an order”). They also have non-functional goals: performance expectations, rate limits, versioning strategy, deprecation policy. OpenAPI has ways to express some of these too, and I always try to capture as much as possible:

/orders/{orderId}/legacy-status:
  get:
    deprecated: true
    summary: (Deprecated) Get legacy order status
    description: >
      This endpoint is deprecated as of v1.2.0 and will be removed
      on 2027-01-01. Use GET /orders/{orderId}/status instead.

Tags: Grouping Goals for Readability

As an API grows, dozens of endpoints become hard to scan. I use tags to group operations by business capability, not by technical layer.

tags:
  - name: Orders
    description: Operations related to creating and tracking orders
  - name: Inventory
    description: Operations related to stock levels and reservations

Good tagging turns a flat list of 40 endpoints into a readable, goal-oriented table of contents — which matters enormously once you generate documentation portals from the spec.

Common Mistakes I See (and Used to Make Myself)

examples:
  successfulOrder:
    summary: A typical successful order
    value:
      id: "ord_8f92a"
      status: "processing"
      total: 49.99
      currency: "USD"

How This Connects to the Rest of the API Design Lifecycle

Describing goals with OpenAPI is just step one. Once the goals and paths are clear, the next problem is describing the actual shape of your data precisely — which is where JSON Schema inside OAS comes in, and I cover that in detail in the next article in this series: “How to Describe Data with JSON Schema and OAS.” After that, you’ll want to avoid repeating yourself across dozens of schemas, which is where reusable components come in.

Key Takeaways

Writing a clear OpenAPI document is one of the highest-leverage things you can do early in a project. It saves arguments later, it speeds up onboarding, and it gives your API consumers — whether that’s a frontend team, a partner company, or the public — a real sense that the API was designed with intention, not just assembled.

Exit mobile version