Where does required live in an OpenAPI schema object, and what does it actually guarantee?
answer
- Declared on the object, not the property
- An array of names, never a boolean
- Presence of the key, nothing more
- Null is still a value
- readOnly changes which direction it binds
basics
~20 sIn an OpenAPI schema, required is an array of property names declared on the object schema itself, not a boolean on each property. It only guarantees the key is present — a required property can still hold null if the schema allows null.
solid answer
~50 s`required` sits on the object schema alongside `properties` and lists the names of properties that must be present: `required: [id, email]`. It is not a flag you set inside a property's own schema — writing `required: true` under a property does nothing in a Schema Object, and that mistake comes from the Parameter Object and Request Body Object, where `required` genuinely *is* a boolean. What it asserts is key presence only. A required property whose schema permits null — `nullable: true` in 3.0, or `type: [string, "null"]` in 3.1 — validates fine with an explicit `null` value. So required and non-null are two separate decisions, and generated code reflects that: a required nullable field usually becomes a non-optional parameter holding a nullable type. One more subtlety: a property marked `readOnly: true` that also appears in `required` is required in responses only, never in requests.
code
yaml · 17 linescomponents:
schemas:
Account:
type: object
required: [id, email, closedAt]
properties:
id:
type: string
readOnly: true # required in responses only
email:
type: string
closedAt:
type: string
format: date-time
nullable: true # present, but may be null (OpenAPI 3.0)
nickname:
type: string # optional: key may be absentgo deeper
Recall the array form on the object schema and be able to write it correctly the first time; know that required: true inside a property is a no-op.
Explain that required asserts key presence only, and walk the four required/nullable combinations and what each means to a consumer.
Show the compatibility judgment: required-ness maps to generated-code nullability, so adding a required response field or removing one is a client-breaking change even when the server is happy.
Own the convention across teams — how PATCH semantics are expressed, whether shared schemas use readOnly/writeOnly or split request and response models, and what the compatibility rules are.
## The shape everyone gets wrong first In a Schema Object, requiredness is declared at the level of the *containing object*, not the property: ``` type: object properties: id: { type: string } nickname: { type: string } required: [id] ``` The common error is writing `required: true` inside the `id` property's schema. In a Schema Object that key is meaningless — it is not part of the JSON Schema vocabulary for a property — and most validators ignore it silently, so the document looks fine and enforces nothing. The confusion is understandable, because OpenAPI *does* use a boolean `required` in two other places: the Parameter Object (`required: true`, and it MUST be true for a path parameter) and the Request Body Object. Those are not Schema Objects. Inside a schema, requiredness is always the array form. ## What required asserts Exactly one thing: the named key is present in the object. It says nothing about the value beyond what the property's own schema says. The consequence that trips people up is null. If a property's schema permits null, then `{"id": null}` satisfies a `required: [id]` constraint — the key is there. Permitting null looks different by version: OpenAPI 3.0 uses the OpenAPI-specific `nullable: true` keyword; OpenAPI 3.1, aligned with JSON Schema 2020-12, uses a type array such as `type: ["string", "null"]`. So four combinations exist and all are meaningful: - required, not nullable → key must be present and hold a real value. - required, nullable → key must be present but may be explicitly null ("the caller must tell us, and 'nothing' is a valid answer"). - optional, not nullable → key may be absent; if present it holds a real value. - optional, nullable → key may be absent or explicitly null. This is usually a modelling smell, because absent and null then mean the same thing to the consumer and generated code cannot distinguish them without extra machinery. That third and fourth distinction matters most in PATCH payloads, where "field omitted" (leave it alone) and "field set to null" (clear it) are genuinely different instructions. ## required and readOnly / writeOnly OpenAPI adds `readOnly` and `writeOnly` to the schema vocabulary. The specification states that if a property is `readOnly: true` and appears in `required`, the requirement applies to the response only — a client must not send it, and a server must return it. `writeOnly: true` is the mirror image: required on the request, absent from the response. This is how one schema serves both directions for a resource with a server-assigned `id` or a write-only `password`. ## What generators do with it Code generators map required-ness directly onto the target language's nullability or optionality: - Required, non-nullable → a non-optional constructor parameter or field. - Optional → a nullable field, an `Optional`, or a field with a default, depending on the generator. So `required` is not merely documentation: it decides whether a consumer's code compiles when a field is missing. Under-declaring required fields produces SDKs full of optionals that callers must unwrap defensively; over-declaring them makes an additive server change a breaking client change, because a field the server stops sending now fails deserialization. ## Two smaller gotchas **Listing a name that has no property.** `required: [phone]` with no `phone` in `properties` is legal JSON Schema — it demands a key whose value is unconstrained. It is almost always a typo, and a good linter flags it. **required with composition.** When a schema is assembled from `allOf` branches, the `required` array in one branch refers to property names in the combined instance, not only to properties declared in that same branch. A branch can therefore require a property that a sibling branch declares. ## The interview answer in one line Required is an array on the object, it means "key present", and it is orthogonal to whether the value may be null.
- Why does writing required: true inside a property's schema do nothing?Because the array form is the Schema Object's vocabulary for requiredness, and an unknown boolean `required` inside a schema is simply not a JSON Schema assertion. The boolean form belongs to the Parameter Object and Request Body Object, which are not schemas — hence the confusion.
- How do you model a PATCH field where omitted and null mean different things?Make the property optional (not listed in `required`) and explicitly nullable, then document that absence means "leave unchanged" and null means "clear". Be aware many generated clients cannot distinguish the two without a tri-state wrapper, so some teams use an explicit action field instead.
- What happens if a property is both readOnly and listed in required?The requirement applies to responses only. The server must include it, the client must not send it, and generated request models normally omit the field entirely. It is the standard way to model a server-assigned identifier with a single shared schema.
saying these in an interview costs you the question
- Writes required: true inside a property schema
- Says required implies the value cannot be null
- Thinks required must list every declared property
- Treats required as documentation with no codegen effect
- Requires a readOnly server-assigned id on requests