Prefixing or not prefixing property names?
By Arnaud Lauret, November 8, 2022
Adding a prefix to a name should be carefully weighed because it impacts the overall design of an API, some code, or a specification and its usability for humans and machines. The discussion related to
responses properties in the early design of OpenAPI v4 is a perfect example of that concern.
Version 4 (aka. Moonwalk) of the OpenAPI Specification is in its early discussion stage. It breaks everything, and the direction taken is quite promising! This post takes its source in a discussion related to
In OpenAPI 3 (and 2), operations’ responses can only be set at the operation level (in
responses). Though reusable responses can be created (in
components.responses), that still means you have to define, for instance, the
500 responses key and reference the predefined responses (with a
$ref = '#/components/responses/<name>') for each operation. That’s a bit annoying.
openapi: "3.1.0" # ... paths: /resources: get: responses: 401: $ref: "#/components/responses/Unauthorized" components: responses: Unauthorized: description: Missing or invalid access token # ...
In OpenAPI v4, the new design would allow defining responses at API (
apiResponses), path (
pathResponses), and operation (
responses) levels. That way, the 401 and 500 responses could be set at the API level in
apiResponses once and for all operations.
The issue and solutions
Matthew Trask was faster than me to start a discussion and point there was something wrong with
pathResponse, and (just)
responses naming. “Confusing” and “verbose” were his words; I would add “inconsistent.”
No prefix at any level
As the three
responses describe the same thing (responses) but at different levels (API, path, operation), I expect them to be all named
responses. It’s the context/location that tells at which level they apply (parent property name or sibling properties giving a clue about the level).
I use that “avoiding prefix as much as possible” naming strategy because:
- Having the same name used for a “thing” favors consistency, understanding, and usability. It’s human-friendly but also (dumb-)machine-friendly: “whatever the level, no need to think, just look for
response” vs. “which level is this? then
- Having shorter names enhance usability and readability.
That is well and good, but what if we keep them named as they are?
The unexpected consequences of adding a prefix
Keeping a name such as
response implicitly defines a naming pattern that should be applied across all the specification:
So, if, for any reason, the
pathResponses would be kept that way, for the sake of consistency, I would argue that:
responseswhich is at the operation level should be renamed
parameterSchemaswhich appears at the path and operation levels should be respectively renames
contentSchemaproperties which appears on request and response should be renamed
- and so on …
So adding such a prefix may have consequences across the whole design, it’s like when throwing 💩 in a fan.
But why would someone do such a “terrible” mistake?
The OpenAPI Specification v4 is in the early stage, and the current naming is probably just a “typo,” or a consequence of “that looks clearer on the diagram.” Maybe it’s just because in current version 3 the property at response level already exists and is (just)
That can happen to anyone, that’s why requesting feedback, doing reviews (and defining guidelines) is important. That helps to fix simple mistakes that have lightly annoying to terrible consequences that you’ll have to live with for eons (well, until the next major version).
API design skills are useful
I love to see how what I’ve learned designing and reviewing hundreds if not thousands of API can be used in other disciplines like designing a format for instance. The concerns you have to take care of when designing APIs are not new and not only related to APIs. But API becoming first class citizen has put those concerns, such as consistency or user-experience, to the front. And now that’s a concern in everything I do.