Now that we understand the basics of YAML, we're ready to write our specification.
There are a few versions of the OpenAPI Specification available. At the time of writing this book, the OpenAPI Specification is at version 3.0.0 and was officially released on 26 July 2017. You may also find many OpenAPI 2.0 specifications in the wild as tooling support for 3.0.0 is lacking in many areas.
We will use OAS 3.0.0 as it is the latest version. Here, you'll find an overview of all the possible root properties in OAS 3.0.0. Not all fields are covered, and required fields are marked with an asterisk (*):
- openapi* (string): This specifies the OpenAPI specification version in use. We should specify the semver version; for us, we will use "3.0.0".
- info* (object): Metadata about the API.
- version* (string): The version of the API this specification is written for. Please note that this is the version of the API itself, not the OpenAPI Specification.
- title* (string): The name of your API.
- description (string): A short description of your API.
- contact (object): Information regarding whom to contact for support.
- name (string): The name of the person/department/organization to contact.
- url (string): A valid URL pointing to a page with contact information.
- email (string): A valid email address where inquiries can be sent.
- termsOfService (string): A valid URL pointing to the Terms of Service notice for the API.
- license (object): License information of the API.
- name* (string): Name of the license.
- url (string): A valid URL pointing to the license.
- servers (array of objects) A list of servers that are serving the API. This is an improvement on the OAS 2.0 root fields host and basePath, as it allows for multiple hosts to be specified.
- url* (string): A valid URL to the target host. This may be a relative URL, relative from the location at which the OpenAPI specification is being served.
- description (string): A short description of the host. This is useful for distinguishing between different hosts if multiple are specified.
- paths* (object): All paths and operations (such as endpoints) are exposed by the API. The paths object is a dictionary of paths (for example, /users) and Path Item Objects. A Path Item Object is a dictionary of (mostly) HTTP verbs (for example, post) and Operation Objects. The Operation Object is the one that defines the behavior of the endpoint, such as what parameters it accepts and the type of responses it emits:
paths:
/users: # Path
post: # Operation
... # Operation Object
- components (object): This holds a set of reusable objects to be reused. The purpose of components is to minimize duplication within the specification. For example, if multiple endpoints may return a 401 Unauthorized error with the message "The Authorization header must be set", we can define a component called NoAuthHeaderSet, and reuse this object in place of the response definition. Components can be referenced from other parts of the specification later using JSON references ($ref).
In OAS 2.0, the components root field did not exist; instead, the definitions, parameters, and responses root fields were used. In OAS 3.0.0, components are not limited to data types (or schema), parameters and responses, but also examples, request bodies, headers, security schemes, links, and callbacks. - security (array of objects): A list of Security Requirement Objects that are acceptable across the whole API. A Security Requirement Object is a dictionary of security schemes that are common across different operations. For example, we require that the client provides a valid token on many endpoints; therefore, we can define that requirement here, and apply it in a DRY manner within each definition. For endpoints that do not require a token, we can override this requirement on an individual basis.
- tags (array of strings): You can group operations using tags by specifying a list of strings inside the Operation Object. Tools, such as Swagger UI, may use these tags to group related endpoints together. The root tags property provides metadata (e.g. long description) on those tags.
- externalDocs (object): Additional external documentation.
Now that you have a brief overview of the root fields, let's begin composing our specification. To ease ourselves into it, we will start by defining the simpler fields like info, then moving on to endpoints that do not require authentication. Once we are more comfortable, we will define security schemes and security requirements and add the specification for endpoints that require authentication.
To get started, add the following metadata to spec/openapi/hobnob.yaml.
openapi: "3.0.0"
info:
title: Hobnob User Directory
version: "1.0.0"
contact:
name: Support
email: dan@danyll.com
servers:
- url: http://localhost:8080/
description: Local Development Server
tags:
- name: Authentication
description: Authentication-related endpoints
- name: Users
description: User-related endpoints
- name: Profile
description: Profile-related endpoints