The OpenAPI spec is best known for descriptions of RESTful APIs, but it’s designed to be capable of describing any HTTP API whether that be REST or something more akin to RPC based calls. That leads to the spec having a lot of flexibility baked-in; there's a lot of ways to achieve the exact same result that are equally valid in the eyes of the spec. Because of this, the OpenAPI docs are very ambiguous when it comes to telling you how you should define your API. That’s why we’d like to take the time to eliminate some of the most common ambiguities that you’ll confront when you build your OpenAPI spec. In this case we’ll be taking a look at operationId.
Common OpenAPI Problem - OperationId
A common problem developers face is the handling of operationId (the name of a particular endpoint). The spec lists it as completely optional, but not including it will become a blocker when attempting to use your API Spec with tooling built to generate docs, SDKs, etc from your spec.
Now let’s take a look at the naming convention for operationId. The official OpenAPI documentation defines operationId as: “A unique string used to identify the operation. The id MUST be unique among all operations described in the API. The operationId value is case-sensitive. Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, it is RECOMMENDED to follow common programming naming conventions.”
While the IDs are case-sensitive, there are a number of tools and programming languages that might be targeted that will require case-insensitivity, case-insensitivity can also help with the readability of your spec. So if you are planning on using your OpenAPI spec to generate downstream artifacts like docs, SDKs, Server stubs, etc, it might be worthwhile ensuring your IDs are named consistently, descriptively and uniquely enough.
How to write OpenAPI Spec - OperationId
Our recommendation would be to treat the operationId as a required field, and make each operationId unique within the document treating it as case insensitive, while avoiding using anything other than alphanumerics and simple separators such as hyphens and underscores. Also be sure to avoid the potential of operationIds being non-unique when any separators are removed (which can happen with a number of tools as they convert your spec to code).
Treating operationIds this way gives you a number of advantages:
- Avoids name conflicts when generating things such as code for SDKs, server stubs etc
- Provides a simple way to refer to your various endpoints in your openapi spec, both for yourself and the consumers of your API.
- Provides additional consistency to your OpenAPI spec.
Here are some examples of good and bad operationIds:
## The below examples are all unique within the document and are avoiding use of anything but simple separators:
## The below examples are of operationIds that while different, are not unique within the document when treated case-insensitively and separators are removed (a common practice for code gen):
## The below examples generally cause issues for a lot of tooling:
operationId: "get pet by id"
operationId: "getPet byId"