cswork / libraryOpen practice workspace

Articles

OpenAPI Interview Questions: Schemas, Compatibility, and Generated Clients

Prepare OpenAPI interview questions with schema examples, a tested compatibility matrix, generated-client failure modes, and practical API release checks.

A team adds refunded to an order-status enum. The OpenAPI file validates, the server tests pass, and a newly generated SDK works. An older mobile app then fails to decode the response. Nothing in that sequence is contradictory: the team tested its new contract, not compatibility with the consumer already installed on a customer's phone.

Strong answers to OpenAPI interview questions separate three contracts: the schema accepted by a validator, the HTTP messages exchanged at runtime, and the programming interface exposed by a generated client. A change can preserve one while breaking another. Start with the consumer and the deployment direction before calling a change “additive.”

This article focuses on an order-contract review and the evidence needed to release it safely.

What does an OpenAPI validation pass actually prove?

It establishes the checks performed by that validator against its supported specification version. It does not prove that the running endpoint implements the description, that every generated client behaves alike, or that old consumers accept new output. Name the tool and version before expanding the claim.

The OpenAPI specification describes HTTP interfaces independently of implementation language. The examples here deliberately target OAS 3.1.2 and its JSON Schema foundation. The latest specification was 3.2.1 when checked on September 21, 2026; that does not imply every validator or generator supports it equally.

Distinguish document validation from payload validation. A valid document can describe a required string while the server returns an integer. A payload checker also needs the applicable operation, status, media type and schema. A JSON parser alone checks neither contract.

An interview-ready answer is: “I would validate the description, test representative wire messages, then run the consumer versions we still support. Those are separate gates.” That answer leaves room for behavioral guarantees such as authorization and idempotency, which a structural schema cannot establish by itself.

Are optional and nullable fields the same?

No. Presence and value are separate dimensions. The JSON Schema object reference explains that listing a property under properties does not require its presence. The enclosing object's required array does that. The null reference explains that an explicit null is a value, not an absent key.

Consider this OAS 3.1 schema fragment:

Order:
  type: object
  required: [id, status]
  properties:
    id:
      type: string
    status:
      type: string
      enum: [pending, paid]
    note:
      type: [string, "null"]
  additionalProperties: false

note may be absent, a string or null. status must be present and one of the two strings. Writing status: null cannot satisfy that enum. Do not copy a 3.0-style nullable assumption into a 3.1 schema without checking the dialect and tooling.

The distinction matters especially for updates. In a hypothetical order-edit endpoint, omission might mean “leave the note unchanged,” while null means “clear the note.” Those meanings are an application decision, not automatically supplied by this schema. State them explicitly and test the two requests separately.

Likewise, making the request body required and making a property required answer different questions. A client can send a body containing {}. The operation-level body requirement alone does not require id or status inside that object.

Review changes in the direction they travel

Assume the existing service accepts requests from old clients and returns responses to them. Ask whether previously accepted requests remain accepted, and whether newly possible responses remain understandable. The following is a worked review, not a universal compatibility policy.

Proposed changeOld client to new serverNew server to old clientEvidence to request
Require a new request fieldOld requests may now be rejectedNot the main issueReplay an old serialized request
Accept another request enum valueExisting values can still workNot automatically a response changeCheck server semantics and rollback
Return a new response enum valueRequests can remain unchangedOld decoder or business switch may failDecode the new value with the old SDK
Add an optional response propertyRequests can remain unchangedStrict unknown-field readers may reject itTest actual deserializer settings
Stop returning a required response fieldRequests can remain unchangedOld code may rely on its presenceDecode and exercise dependent behavior
Rename an operation identifierWire route can remain identicalRegenerated source interface may changeCompile a representative caller

This also exposes rollout direction. A new client sending the new request enum to an old server can fail even if old clients remain compatible with the new server. “Backward compatible” is too vague unless you specify which versions communicate.

Treat absence of traffic as different from proof of absence of consumers. An infrequently used integration might not appear in yesterday's logs. Combine telemetry with the supported-client inventory and an explicit deprecation policy before removing behavior.

Run a small old-schema versus new-schema probe

For the order example, create a new schema by adding refunded to the status enum and an optional string receipt property. Keep both schemas closed with additionalProperties: false. A local probe using Python jsonschema 4.26.0 and Draft202012Validator produced these results:

Order payload variationOld schemaNew schema
id and status: paid; note absentPassPass
Same order with note: nullPassPass
status absentFailFail
status: nullFailFail
status: refundedFailPass
status: paid plus receipt: r2FailPass

The core check is deliberately small:

from jsonschema import Draft202012Validator

payload = {"id": "o7", "status": "refunded"}
assert not Draft202012Validator(old_schema).is_valid(payload)
assert Draft202012Validator(new_schema).is_valid(payload)

Here old_schema and new_schema are Python dictionaries containing the two schema definitions. This is a JSON Schema subset test, not validation of the complete OpenAPI document. It also does not execute a generated SDK or a real order service.

The useful conclusion is narrow: two new outputs that satisfy the new schema violate the old closed contract. An old client might ignore unknown properties, but that would be a separate observed client behavior. Do not turn a schema test into an unperformed SDK test.

Why can generated clients break without an HTTP change?

A generator translates descriptions into language-specific types and methods. Changes in naming, generator version, templates or library options can alter that interface even when the method and URL remain stable. Review generated diffs alongside the specification diff.

The OpenAPI Generator usage documentation exposes separate validation and generation commands. The customization documentation documents configuration, naming and template controls. Record those inputs in the build so a regenerated SDK is reproducible rather than dependent on a developer's current defaults.

For a concrete implementation-dependent case, the Java generator options document enumUnknownDefaultCase. It can provide a fallback enum member for unknown values. Its existence is not a guarantee that a previously shipped SDK has that option, or that the application's business logic handles the fallback safely.

Imagine an order screen that treats every non-pending value as paid. A tolerant decoder prevents a parse error but can still display a refunded purchase incorrectly. Compatibility testing must reach the consumer behavior, not stop after object construction.

Separate two experiments: run the unchanged released SDK against new response fixtures, and regenerate an SDK from the new description and compile existing application source against it. The first examines deployed wire compatibility; the second examines an upgrade's source compatibility. Passing only the second hides the installed-client problem from the introduction.

How should you explain oneOf and discriminators?

The JSON Schema combination rules require exactly one matching branch for oneOf, versus at least one for anyOf. Do not describe oneOf as “pick whichever class is convenient.” A payload matching two branches fails that rule.

Suppose an order result is either a receipt or a rejection. Give each branch a required kind with a distinct constant, such as receipt or rejected, and require the branch-specific fields. Test one valid value per branch, an unknown kind, a missing kind and an ambiguous object.

In OAS 3.1.2, a discriminator can guide tooling, but it cannot change the schema's validation outcome. A mapping does not repair branches that overlap. Explain the constraints first, then how the chosen generator represents them. This avoids promising identical union support across languages and libraries.

If the interviewer asks about inheritance, distinguish reuse from substitutability. Combining required properties with allOf means all constraints apply; it is not permission to relax a parent's constraints. A smaller explicit response model can be easier to maintain than a clever hierarchy whose generated classes behave differently across SDKs.

What should the release gate contain?

Build a compact matrix around versions you actually support. For this order change, include the old released client with the new server, the new client with the new server, and the new client with the rollback server. Where the last combination is intentionally unsupported, constrain rollout so it cannot occur silently.

Use fixtures that challenge representation: omitted and null notes, unknown enum values, unknown fields, error bodies, and the chosen numeric and date encodings. For query parameters, compare the serialized URL as well as the in-memory argument. A list encoded with commas is not interchangeable with repeated keys unless the endpoint contract permits both.

Make release failures actionable. A document-validation error belongs to the description author; an old-client decoding failure needs a compatibility decision; a source compilation error needs an SDK migration or naming repair. Labeling all three “OpenAPI failed” sends the investigation to the wrong layer.

For the refunded-status change, a defensible plan is to ship and verify tolerant handling first, measure adoption where possible, then enable the new response value under a controlled rollout. If some supported consumers cannot change, preserve their contract or introduce an explicitly negotiated version. Do not simply suppress validation until the release turns green.

Practise defending the compatibility claim

Explain the old message, the changed rule and the consumer behavior you would observe.

Practice questionOpenAPI-focused follow-up
Validate JSON against a protobuf-like schemaSeparate missing values, nulls and type mismatches.
Reason About Nested JSON Schema ValidationProve that union branches match as intended.
Implement CRUD API and testsCompare the written contract with actual responses.
Debug and Harden a Ticketing Backend APIPreserve consumer behavior while repairing validation.
Implement paginated API ingestionTest a client across response and pagination changes.

Return to the backend engineer guide to connect contract decisions with storage and deployment design. Your strongest closing sentence is specific: “This change is compatible with these consumer versions, in this direction, and these tests are the evidence.”

Sources and Further Reading