Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can a schema parameter's 'required' attribute be overridden? #1590

Closed
cmeeren opened this issue May 23, 2018 · 6 comments
Closed

Can a schema parameter's 'required' attribute be overridden? #1590

cmeeren opened this issue May 23, 2018 · 6 comments

Comments

@cmeeren
Copy link

cmeeren commented May 23, 2018

I have a common object defined in schemas referenced in a couple of endpoints. However, the specific set of required fields differ between the references. For example, one endpoint requires properties foo and bar, while another endpoint requires properties foo and qux.

Is it possible to override the required list when referencing a schema? Is there another fairly DRY way to accomplish this? (The only workaround I can think of is inlining the schema everywhere, which leads to duplication and possibility of inconsistencies.)

If it's not possible, could this be implemented?

@handrews
Copy link
Member

handrews commented May 23, 2018

Yes, since foo is required in both cases, have "required": ["foo"] in your re-usable schema under components, and then use allOf to reference the re-usable schema and also add "required": ["bar"] or "required": ["qux"] or whatever.

https://tools.ietf.org/html/draft-wright-json-schema-validation-01#section-6.26

@cmeeren
Copy link
Author

cmeeren commented May 24, 2018

Brilliant, thanks! I'll have to read up some more on the possibilities of allOf/anyOf.

@von-court
Copy link

von-court commented Aug 1, 2018

Even if the issue is closed, my question would have the same or similar title, so I decided to append it here.

I got a JSON schema which refers to other JSON schemas, which also refer to other JSON schemas and so on... so it's pretty nested.

=> Now, if I want to override the "required" attribute of one of the nested JSON schemas, would the following structure work, i.e. be valid?
And if not, is there another lean way to express what I want within the OpenAPI definition?

"allOf": [
    {
        "$ref": "offer.json"
    },
    {
        "properties": {
            "vehicleOffers": {
                "items": {
                    "properties": {
                        "vehicles": {
                            "items": {
                                "required": [
                                    "options"
                                ]
                            }
                        }
                    }
                }
            }
        }
    }
]

@handrews
Copy link
Member

handrews commented Aug 1, 2018

@emvau the schemas in an allOf are each evaluated separately, and must all pass. There is no "overriding" here, you just add constraints in each branch of the allOf. In practical terms for required, this just means that you can't use allOf to remove a requirement.

As for nesting, the 2nd schema under allOf in your example reads as:

  • if the instance is an object, then...
  • if it has a "vehicleOffers" property which is an array, then...
  • if an entry in the array is an object with a "vehicles" property which is itself an array, then...
  • if an entry in the "vehicles" array is an object, then it must have a property named "options"

The reason for all of the ifs is that properties and items do not force the instance to be of type object or array, respectively. They apply only if the instance is of the appropriate type. To force the types throughout, you need to set type (or maybe it is already set in the offer.json schema, in which case you do not need to re-set it in the other schema. This is type-related behavior covered in the JSON Schema specification.

Note that requiring "options" at the deepest level does not cause any higher level properties to be required. You would need to set required at each level to do that (and presumably "minItems": 1 on arrays if you want to ensure there is always at least one vehicle in a vehicle offer).

@von-court
Copy link

@handrews thanks for the very detailed explanation! Makes all sense to me and happily also confirms the way I tried to solve my problem with.

@shaoner
Copy link

shaoner commented Feb 26, 2021

just in case someone is looking for a solution to override a schema easily:

you can use swagger-cli and mix references

MySchema.yaml

type: object
properties:
  foo: 
    type: integer
  bar:
    type: integer
required:
  - foo
  - bar

src/spec.yaml

patch:      
  summary: Update something
  requestBody:
    content:                                     
      application/json:
        schema:
          type: object
          properties:
            $ref: ../components/schemas/MySchema.yaml#/properties
npx swagger-cli bundle --dereference -o ./out.yaml -t yaml src/spec.yaml

The reason for doing this is that it allows to have your schema properties only in a single file instead of dispatching properties everywhere (which make things complicated when adding or removing properties)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants