question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow requiring fields only on input or only on output

See original GitHub issue

Say we have an object like this:

person:
  required:
    - name
  properties:
    name:
      type: string

These objects are sent to the API via POSTs and read via GETs. We have many many client devices out there all reading and writing these objects, so when we put out a breaking change in a new version of the API, we have to support the old ones, at least temporarily. Now we add a new field, say age. We want this to be a required property, so we need a new API version. At /v1 we’ll have the old API and at /v2 we’ll have the new one. But now there’s a problem. Say a v1 client POSTs a person object. Now a v2 client attempts to fetch this data with a GET. The age data isn’t available. The API cannot construct a person object that fits the v2 spec. So do we make the age field optional in the v2 spec? No, because then we’re not validating client input. Our v2 client code might be failing to include the age property in some cases, and it’ll just fail silently, and we might not catch the bug before the code goes out into production.

The correct solution, as I see it, is for age to be required on input, but not on output. v2 clients should always include this new information, but since the API itself is having to relay information from v1 clients, it simply can’t always do that. My ideal syntax would be this (in the v2 spec):

person:
  required:
    always:
      - name
    write:
      - age
  properties:
    name:
      type: string
    age:
      type: number

There would similarly be a required.read property. If it’s not possible to implement this syntax in a backwards-compatible way, maybe something like required, requiredOnRead, requiredOnWrite.


(Warning: rambling ahead. Optional reading)

Just to provide further rationale: to me this isn’t a niche use-case, I think this is basically the tool which solves all of your API versioning woes. When we’re dealing with symmetrical APIs (clients read and write more or less the same type of data), basically when you break an API, you do it in one of three ways:

  1. You add a field (new clients will be sending more data).
  2. You remove a field (new clients will be sending less data).
  3. You change the data type of a field (new clients will be sending different data).

The way you handle these changes is in each case to create a new v2 spec and put the APIs on /v1 and /v2 (at least this is one way of handling it), in which case we can handle them in these ways:

  1. New clients are sending and expecting the age field, but old ones aren’t. The problems that can arise and the way to handle this with input-only required properties is detailed above.
  2. New clients are no longer sending the age field, but old clients expect it. This is going to break the solution no matter what. Old clients making a GET request to /person?id=12 are expecting to get an age, but the information isn’t available. Assuming age was a required property in the v1 spec (if it isn’t there’s no problem), there’s just no way around it: something’s going to break. No clever new OpenAPI feature can fix this, so we can forget about this case.
  3. Field F has changed from data type A to data type B. If it is not possible to translate type B into type A in a reasonable fashion (like if maybe the fields only got renamed) then we’re in case (2), above: information that old clients want is no longer available from new clients, we can’t do anything about it, and we forget this case. If it is not possible to translate type A into type B in a reasonable fashion, this means new clients are looking for information which old clients aren’t providing. This is the same as case (1), above: the solution is to make the field optional on output and required on input.

To be honest, I haven’t yet thought of a use case requiring making a field required on input but not on output, but for the same of symmetry it should probably be included.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
tedepsteincommented, Apr 15, 2019

@geajack, I think this is one of many cases where you’d need to define separate request and response schemas for each version, in order to fully define the data contract as you’ve described it.

Summarizing the combinations described in the Schema Object specification:

Read/Write Keyword Required Property in Request Property in Response
none (default) false optional optional
none (default) true required required
readOnly false disallowed optional
readOnly true disallowed required
writeOnly false optional disallowed
writeOnly true required disallowed

You’re looking for options that would make a property:

  • required in the request and optional in the response; or
  • optional in the request and required in the response

OpenAPI doesn’t provide a way to specify those semantics within a single schema.

0reactions
handrewscommented, Feb 24, 2020

It’s been more than six months since the last answer with no further discussions so I’m going to close this. Please re-open if needed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Require a value in a field - Microsoft Support
Set the field's Required property to Yes You can do this by opening the table in Design view. This method is easy and...
Read more >
HTML attribute: required - HTML: HyperText Markup Language
Because a read-only field cannot have a value, required does not have any effect on inputs with the readonly attribute also specified.
Read more >
Required Fields | Introduction to Accessibility - A11y-101
Before we start, let's have a look at the simplest input. We'll have no idea whether the input is mandatory or not. <label...
Read more >
Styling Form Inputs in CSS With :required, :optional, :valid and
When it comes to validating the content of input fields on the ... the required attribute, modern browsers will only set the input...
Read more >
How to perform form validation for a required field in HTML
1. Required attribute: If you want to make an input mandatory to be entered by the user, you can use the required attribute....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found