DEV Community

Cover image for OpenAPI Flaws - Required field
Vladimir Sapronov
Vladimir Sapronov

Posted on • Updated on

OpenAPI Flaws - Required field

Let's consider the OpenAPI (aka swagger) sample (also on the cover image):

Person:
  type: object
  properties:
    first_name:
      type: string
    middle_name:
      type: string
    last_name:
      type: string
Enter fullscreen mode Exit fullscreen mode

Is everything fine with it? What do you think? Is it designed well? How hard could it be to design a decent JSON Schema?


Before we proceed. There's an obsession going on around APIs. There are a number of engineers advocating for it. And this is great! Formats of OpenAPI, JSON Schema etc are not so great though. I would like to write about this.

I published this as a thread in my Twitter, follow me there if you are interested in what I write about.


Required in Schemas

The schema from above is not good. It validates successfully following JSON objects.

{}   // empty object

{
  "first_name": "Vladimir"   // only first_name is provided
}

{
  "last_name": "Sapronov"    // only last_name is provided
}
Enter fullscreen mode Exit fullscreen mode

It’s because all properties in JSON schema are not required by default. And since it’s JavaScript-centric, it makes a lot of sense. Everything is non-required in JS, especially when it comes to types.

Here’s the corrected schema:

Person:
  required:            # you need to specify this!!!
    - first_name
    - last_name
  type: object
  properties:
    first_name:
      type: string
    middle_name:                   
      type: string
    last_name:
      type: string
Enter fullscreen mode Exit fullscreen mode

And here’s why it is sub-optimal: most object properties are required in real life. I would argue the ratio is around 80% required VS 20% optional. So it absolutely makes sense to design the spec syntax towards what is more common.

In any code (which is the other side of any API) non-required properties force you to verify if the property was supplied. So it bloats your code with a lot of if and null coalescing (??) operators. You should make as many properties required as you can.

Finally it’s just a bad design. Even if there was a need to force everyone to explicitly declare their properties as required: why is this not a part of the property definition. Instead it hangs out there at the top of the schema. Which is forcing developers to repeat most of the field names twice. Eeeew!

I have noticed that many developers are just not aware of this required field of the object schema and omit it which leads to all their properties being optional.

It's pretty easy to fix the design of JSON Schema. Here's one option:

requiredByDefault: true   # makes all properties
                          # required by default
...
Person:
  type: object
  properties:
    first_name:
      type: string
    middle_name:                   
      type: string
      required: false     # if some property is not required
    last_name:            # it should be specified explicitly
      type: string
Enter fullscreen mode Exit fullscreen mode

Required in Operations

Parameters of operations also might be either required or not. Let's consider the operation below:

/fancy:
  get:
    operationId: fancy
    parameters:
      - in: query
        name: person
        required: true     # <- What is this?!

        schema:
          type: string
Enter fullscreen mode Exit fullscreen mode

Have you noticed how the required field is placed in the OpenAPI endpoint parameter? It’s within the parameter definition and it’s a boolean flag. So within the one specification format, the same thing is designed in two different ways: the required flag outside of a property definition and the required flag inside of a parameter definition.

# operation parameter
      - in: query
        name: person
        required: true     # <- Part of parameter definition

# schema property
  required:
    - first_name           # <- Outside of property definition
  properties:
    first_name:
      type: string

Enter fullscreen mode Exit fullscreen mode

At this point, it's obvious that required should be part of the parameter/property definition. The parameter design is a bit better but OpenAPI didn’t propagate the approach to JSON Schema properties.

The one common thing is that required is false by default for both: parameter and property. This is opposite to common sense programming logic: if you declare a param it is required by default unless you explicitly made it optional. There are no parameters in programming which are optional by default.

There was a ring bell to OpenAPI designers about this required being false by default. Path params can’t be optional. OpenAPI docs say: “If the parameter location is path, this property is REQUIRED and its value MUST be true.” Required by default would eliminate this.

The fix with requiredByDefault that was mentioned above would also work just fine for operations making all parameters required by default.

This story about required flag design is just a small example of OpenAPI design inconsistencies. More of those inconsistencies in this series...

Top comments (1)

Collapse
 
apimike profile image
Mike Rozner

Great article! Have you considered Cherrybomb the openAPI validation CLI - github integrate it right in your CI and validate your APIs.