Skip to main content

On mobile? Send a link to your computer to download HTTP Toolkit there:

No spam, no newsletters - just a quick & easy download link

On mobile? Send a link to your computer to download HTTP Toolkit there:

No spam, no newsletters - just a quick & easy download link

openapi

apis

standards

A brief introduction to OpenAPI

It's hard to work on APIs without hearing about OpenAPI.

OpenAPI is an API description format, which is essentially metadata that describes an HTTP API: where it lives, how it works, what data is available, and how it's authenticated. Additional keywords can be used to provide all sorts of validation information, adding a type system to what would otherwise just be arbitrary JSON flying around the internet.

OpenAPI has been around for donkeys years, previously known as Swagger but renamed to OpenAPI in 2016. It's powered by JSON Schemaopens in a new tab, which is also pretty popular in certain circles, but it's only in the last few years that OpenAPI has solidified its place as the description format for HTTP APIs, pushing aside others like RAML and API Blueprint.

Elder developers will remember working with WSDLs and XML Schema, and gRPC and GraphQL folks might be thinking "hang on this sounds a bit familiar", and absolutely. Type systems for APIs are pretty common, but here's an excellent one you can use for your REST/RESTish API.

Here's an example to give you an idea:

Code example

Code exampleopenapi: 3.1.3

info:
  title: Your Awesome API
  version: '1.0.3'
  description: More information and introduction.

paths:
  /things:
    post:
      summary: Create a thing
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  examples:
                    - Tim

      responses:
        '201':
          description: "Created"
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  name:
                    type: string
                    examples:
                      - Tim
                  created_at:
                    type: string
                    format: date-time
                    example: 2020-01-01T00:00:00Z

This describes an API in a machine-readable format, including overall metadata, endpoint paths, request formats, and the details of possible responses you might receive.

What can OpenAPI do?

OpenAPI specifications provide a machine-readable base on top of which lots of neat API tools can be used and even generated.

One of the most common uses by many API teams to to generate API reference documentation, which helps end-users learn about the API in the same sort of way you'd look up functions and classes to work with a code package. Tools like Redocopens in a new tab make it possible to create beautiful API documentation sites automatically, directly from the OpenAPI spec file:

Preview of the popular OpenAPI documentation tool Redoc

API developers and API end-users all find this pretty helpful, but increasingly OpenAPI is being used throughout the entire API lifecycle.

OpenAPI can be used for validation, to power contract testing and do server-side & client-side validation, and you can use it to generate SDKs, backend server stubs, or even realistic mock servers so that clients can play around with the API before it's even built!

As one example, HTTP Toolkitopens in a new tab uses OpenAPI internally to automatically understand requests to a huge list of public APIs with published OpenAPI specifications. For each request, using the OpenAPI spec HTTP Toolkit can validate the request parameters, and show metadata alongside the raw request & response information, so you can easily understand what an API response actually means and jump straight from a request to the corresponding documentation.

Similarly, you can also load your OpenAPI spec into HTTP Toolkit and other alternative tools, adding your own metadata and validation to help you debug intercepted traffic & requests.

Before getting too much further into use cases though, how does OpenAPI actually work?

How does OpenAPI work?

OpenAPI Documents

OpenAPI generally exists as a YAML or JSON document usually called something like openapi.yaml. The simple example above showed how to describe a POST with a response, but you can do a lot more, describing any HTTP method, and defining path parameters, query string parameters, and headers, providing their validation rules too if you like.

Code example

Code exampleopenapi: 3.1.3

info:
  title: Widget API
  description: The worlds best collection of Widgets.
  version: '1.1.0'

paths:
  /widgets/{uuid}:
    get:
      operationId: fetch-widget
      description: Fetch a Widget

      parameters:
        - name: uuid
          in: path
          required: true
          description: A unique identifier that each Widget has to help you look it up.
          schema:
            type: string
            format: uuid

      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  other-fields:
                    type: string

This is a very simplistic API, but regardless how complicated your API is, OpenAPI can describe it, with all sorts of powerful keywords covering the vast majority of needs. We'll just provide a basic introduction here, but you can look through the full OpenAPI referenceopens in a new tab for more details as required.

An OpenAPI document is split into four key sections: info, paths, webhooks, and components.

info

The info section establishes general information about the API, helping people find support if they need it, learn about the license, and read a whole introduction.

Code example

Code exampleopenapi: 3.1.3
info:
  title: Your Awesome API
  version: '1.0.3'
  description: >
    More information, getting started, etc. *with Markdown!*
  contact:
    name: Who Owns the API
    url: https://www.example.org/support
    email: support@example.com
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html

The description which can be quite extensive and powered by CommonMarkopens in a new tab (standardized Markdown), so when it's picked up by API documentation tools it's like a little getting started guide (if you don't have one of those elsewhere).

paths

This is the most important section, it helps outline all the endpoints (resources) of the API. It covers HTTP headers (a.k.a HTTP fields), parameters, and points to which authentication schemes are involved if any.

Using the Tic Tac Toe example from OpenAPI Initiative, you can define multiple methods per path.

Code example

Code examplepaths:
  /board:
    get:
      ...
    put:
      ...

Each of these HTTP methods has an "Operation", which looks a bit like this:

Code example

Code examplepaths:
  /board:
    get:
      summary: Get the whole board
      description: Retrieves the current state of the board and the winner.
      operationId: get-board
      responses:
        "200":
          description: "OK"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/status"

The $ref is a Reference to another component, which helps us reduce repetition in the OpenAPI document, and we'll explain that a bit in a moment.

Find out more about Paths on Learn OpenAPI: API Endpointsopens in a new tab.

webhooks

A webhook is a way for two systems to communicate in real-time. Instead of an API client repeatedly making requests to the other for updates, the API client provides a URL to the API, and the API will send a HTTP request to that URL when a relevant event occurs.

Describing webhooks is almost identical to describing paths, but instead of describing a request that comes from the API client, and a response made by the API provider, you flip that around: The API provider will send the API client a request, and the API client should respond with a response as described in the webhook.

If a Tic Tac Toe game had a webhook, maybe it is letting another backend system know who won a game.

Code example

Code exampleopenapi: 3.1.3

webhooks:
  # Arbitrary name for the webhook
  newThing:
    post:
      requestBody:
        description: "A game was completed"
        content:
          application/json:
            schema:
              type: object
              properties:
                winner: https://example.org/api/users/Tim
                loser: https://example.org/api/users/Phil
                duration: 30
      responses:
        '200':
          description: "OK"

For a webhook, the requestBody is now explaining what HTTP body the API client can expect in the webhook messages, and the responses section now explains that the API client should return a 200 in order to mark it as a success.

components

Components allow you to define schemas, headers, parameters, requestBodies, responses, and other reusable bits of OpenAPI to be used in multiple places.

Code example

Code examplecomponents:

  schemas:
    coordinate:
      type: integer
      minimum: 1
      maximum: 3

  parameters:
    rowParam:
      name: row
      in: path
      required: true
      schema:
        $ref: "#/components/schemas/coordinate"
    columnParam:
      name: column
      in: path
      required: true
      schema:
        $ref: "#/components/schemas/coordinate"
paths:
  /board/{row}/{column}:
    parameters:
      - $ref: "#/components/parameters/rowParam"
      - $ref: "#/components/parameters/columnParam"

This keeps things nice and tidy, and you can even spread them across multiple documents to share components between multiple APIs, or at least just keep your file sizes down.

Find out more about Components on Learn OpenAPI: Reusing Descriptionsopens in a new tab.

Schema Objects

Within each of these sections, the schema keyword is used to describe types, very similar to XML Schema, protobuff, or gRPC, but with a whole lot more options. The latest version of OpenAPI (v3.1.0) is specifically powered by JSON Schema Draft 2020-12.

It's important to understand these JSON schemas to be able to interpret or write complex OpenAPI types, but fortunately they're mostly quite readable, and often self-explanatory even if you're not already familiar with them.

A full example looks like this:

Code example

Code exampledescription: A representation of a movie
type: object
required:
- title
- director
- releaseDate
properties:
  title:
    type: string
  director:
    type: string
  releaseDate:
    type: string
    format: date
  genre:
    type: string,
    enum:
    - Action
    - Comedy
    - Drama
    - Science Fiction
  duration:
    type: string
  cast:
    type: array
    items:
      type: string

Head over to the JSON Schemaopens in a new tab website for an in-depth intro.

How can you use OpenAPI as an API developer?

Creating this OpenAPI description might seem like extra work, but by being able to generate beautiful interactive documentation, reduce the redundancy in contract tests, automatically build SDKs, and even reduce how much code needs to be written for validation, overall you'll save a lot more time that you ever put in.

The most common workflow is to create it manually with text editorsopens in a new tab or graphical editorsopens in a new tab. Whilst this is a fair bit of up-front work, it can then be used to reduce repetitive tasks throughout the rest of the API Lifecycle, like contract testingopens in a new tab and server-side validationopens in a new tab. This is known as the API Design-first workflowopens in a new tab.

Whilst most OpenAPI is built up-front, there are plenty of options for other workflows. OpenAPI can generated from code via annotations or educated guesses. This is known as code-first (or contract-first).

Other workflows can be guesstimated from HTTP trafficopens in a new tab, which is not a great ongoing solution, but it can be handy for "catching up" when you've built a whole API and need to get OpenAPI generated for it to match up with the rest of the company having nice OpenAPI-based documentation and testing.

It can also be converted from other formats like Postman Collections or HAR, using something like API Transformeropens in a new tab or via OpenAPI conversion toolsopens in a new tab.

Having this machine-readable API description sitting around in the source code means your API code and API description are always being updated with each pull request, and by powering your contract testing you know it's accurate.

How can you use OpenAPI as an API consumer?

OpenAPI is often discussed as if it's useful to API developers only, but it has plenty of benefits for API consumers too. You can use OpenAPI to more easily understand an API you'll be using and the responses it'll give you, to validate your requests and provide mocking during testing, to boost the power of your HTTP debugging tools, or generate your own libraries & SDKs to more easily interact with servers.

For example, if you are working with API developers using the API design-first workflow, they'll likely get you involved earlier on to work with mock servers. This might be a hosted mock server they control, or perhaps they'll give you the OpenAPI and let you run your own mock server, which could be as simple as running:

Code example

Code examplenpm install -g @stoplight/prism-cli
prism mock openapi.yaml

Now you'll have a pretend API running locally that you can try integrating with, and whilst it might not have any business logic it'll help you make sure your code is about right, and identify where data is missing for the sort of work you're trying to do, before they waste loads of your time building something that doesn't work for you.

If the team doesn't provide an OpenAPI spec yet, as quick fix you can even record your own just from sniffing HTTP trafficopens in a new tab.

Going forwards with OpenAPI

I hope that's been an interesting introduction! If you'd like some real examples, take a look at these large companies' downloadable versions:

OpenAPI can be complicated to get started with, but it's useful on both the front & back-end, for testers, developers and others, so it's well worth understanding. Take a look at the above examples for some real-world cases, and feel free to get in touchopens in a new tab if you have any questions.

Share this post:

Blog newsletter

Become an HTTP & debugging expert, by subscribing to receive new posts like these emailed straight to your inbox:

Related content

apis

Designing API Errors

When everything goes smoothly with an API, life is pretty straightforward: you request a resource, and voilà, you get it. You trigger a procedure, and the API politely informs you it’s all gone to plan. But what happens when something goes pear-shaped? Well, that’s where things can get a bit tricky. HTTP status codes are like a first aid kit: they’re handy, but they won’t fix everything. They give you a broad idea of what’s gone wrong, which can help plenty of tools and developers make reasonable assumptions, like:

http

22 years later, YAML now has a media type

As of February 14th 2024, RFC 9512 formally registers "application/yaml" as the media type for all YAML content, and adds "+yaml" as a standard structured suffix for all YAML-based more specific media types. With this registration, it's now included in the official media types list maintained by the IANA. Media types like this (also known as the MIME types, from their original invention for email attachment metadata) are heavily used particularly in HTTP "Content-Type" headers for both requests & responses, and in all sorts of file metadata and processing logic elsewhere. These names give applications a common vocabulary to describe data when passing it around.

http

What is X-Forwarded-For and when can you trust it?

The X-Forwarded-For (XFF) HTTP header provides crucial insight into the origin of web requests. The header works as a mechanism for conveying the original source IP addresses of clients, and not just across one hop, but through chains of multiple intermediaries. This list of IPv4 and IPv6 addresses is helpful to understand where requests have really come from in scenarios where they traverse several servers, proxies, or load balancers. A typical HTTP request goes on a bit of a journey, traversing multiple layers of infrastructure before reaching its destination. Without the "X-Forwarded-For" header, the receiving server would only see the IP address of the last intermediary in the chain (the direct source of the request) rather than the true client origin.