Skip to content
Back to Interview Guides
Interview Guide

25 Advanced OpenAPI (Swagger) Interview Questions for Experienced Developers

· 14 min read
OpenAPI (Swagger) Q&A Component

Jump to Category

Schema & Components API Design & Structure
️ Security Definitions Tooling & API Lifecycle
✨ Advanced Concepts

Schema & Components

1. What is the purpose of the `components` object in an OpenAPI 3.x specification?

The `components` object is a core feature for creating reusable definitions. It acts as a central “library” within your specification for objects that can be referenced from multiple places. This promotes the DRY (Don’t Repeat Yourself) principle.

You can define reusable:

  • `schemas`: For request/response bodies and data models.
  • `parameters`: For common query or header parameters.
  • `securitySchemes`: For authentication methods.
  • `responses`: For standard API responses (e.g., a `404 Not Found`).
  • `requestBodies`, `headers`, `links`, and `callbacks`.

These components are then referenced throughout the specification using a `$ref` pointer, like `’$ref’: ‘#/components/schemas/User’`.

Read the documentation on Components.

2. Explain how to model polymorphism using `oneOf`, `anyOf`, and `allOf`.

These keywords allow you to combine and extend schemas to model complex or polymorphic data structures:

  • `oneOf`: The data must be valid against **exactly one** of the specified sub-schemas. This is used for mutually exclusive options (e.g., a notification can be an `EmailNotification` or a `SmsNotification`, but not both).
  • `anyOf`: The data must be valid against **one or more** of the specified sub-schemas. This is a more flexible “or” condition.
  • `allOf`: The data must be valid against **all** of the specified sub-schemas. This is used to combine multiple schemas, often for implementing inheritance where a model extends a base model.
Explore `oneOf`, `anyOf`, `allOf` in the documentation.

3. What is the `discriminator` object and how does it work with polymorphic schemas?

The `discriminator` is an advanced feature used with `oneOf` or `anyOf` to help tools and code generators determine which specific schema is being used based on a field’s value. It provides a hint for deserialization.

You specify a `propertyName` (e.g., `petType`) in the base schema. Then, in the `mapping`, you map specific values of that property (e.g., `”dog”`, `”cat”`) to the corresponding schema definitions (`’#/components/schemas/Dog’`). This allows a parser to look at the `petType` field in the incoming JSON and know instantly which schema to use to validate and deserialize the rest of the object.

Read the guide on Polymorphism and Discriminators.

4. How do you define a file upload in an OpenAPI specification?

File uploads are typically handled using a `multipart/form-data` request body. In your operation’s `requestBody` definition:

  1. Set the content type to `multipart/form-data`.
  2. Define a schema with `type: object`.
  3. In the `properties` of that object, define a property for the file. The type of this property should be `string` with a `format` of `binary` or `base64`, depending on how the file is encoded.

This tells tooling that the endpoint expects a multipart request containing file data.

Learn about describing file uploads.

5. What is the difference between `format` and `pattern` in a schema?

  • `format`: Provides additional semantic meaning to a primitive type. It doesn’t strictly enforce validation in all tools but gives hints about the data’s nature. Examples include `date-time`, `uuid`, `email`, or `byte` (for base64-encoded strings).
  • `pattern`: A regular expression that the value of a string type *must* match for the schema to be valid. This is a strict validation constraint. For example, you could use a pattern to enforce that a string must be a specific format, like a semantic version number (`^\d+\.\d+\.\d+$`).

API Design & Structure

6. What are the key differences between OpenAPI 2.0 (Swagger) and OpenAPI 3.0?

OpenAPI 3.0 was a major release that introduced significant structural improvements:

  • Component-based Structure: OAS 3.0 introduced the `components` object, creating a much cleaner way to define reusable schemas, parameters, and responses compared to OAS 2.0’s separate `definitions`, `parameters`, etc.
  • Request Bodies: The `body` and `formData` parameters from 2.0 were replaced with a more flexible `requestBody` object, which allows for different content types.
  • Callbacks and Links: Added formal support for describing webhooks (`callbacks`) and hypermedia controls (`links`).
  • Security Schemes: The security definitions were overhauled to be more flexible and better align with standards like OAuth 2.0.
Read a summary of what’s new in OpenAPI 3.0.

7. How would you structure a very large OpenAPI definition to keep it maintainable?

You should split the specification into multiple files. The main `openapi.yaml` file would define the top-level info and then use `$ref` pointers to reference external files for different parts of the specification.

A common structure is to have separate directories for:

  • `paths/`: Each file contains the definition for a specific API path (e.g., `users.yaml`, `products.yaml`).
  • `components/schemas/`: Each file defines a reusable data model schema.
  • `components/responses/`: Each file defines a reusable response.

This makes the project much easier to navigate and allows multiple developers to work on different parts of the API specification simultaneously without merge conflicts.

8. What are callbacks and how do you define them in OpenAPI?

Callbacks are used to describe asynchronous, out-of-band requests that your service will make to another service. They are used to model webhooks. You define a `callbacks` object on an operation that initiates the callback.

Inside, you define a named callback event (e.g., `onDataReceived`). The definition for this event looks just like a standard path item object, describing the request that your service will make to the client’s webhook URL (which is typically provided in the initial request).

Read the documentation on Callbacks.

9. What is the `links` object used for?

The `links` object is used to describe relationships between API operations and implement HATEOAS (Hypermedia as the Engine of Application State). It allows you to describe how a value from one API response can be used as a parameter in a subsequent API call.

For example, after a `POST /users` request, you could define a link named `GetUserById` that describes how the `id` from the response body can be used to populate the `userId` parameter in a `GET /users/{userId}` request. This makes your API more self-descriptive.

10. How do you handle API versioning in an OpenAPI specification?

There are several strategies, and OpenAPI can support them all:

  • URL Path Versioning (most common): The version is part of the URL path, e.g., `/api/v1/users`. In OpenAPI, you would simply include `/v1` in all your defined paths.
  • Header Versioning: The version is specified in a custom request header (e.g., `Api-Version: 1.0`). You would define this as a required header parameter on all your operations.
  • Query Parameter Versioning: The version is a query parameter (e.g., `?version=1`). You would define this as a query parameter.

Typically, each major version of an API will have its own separate OpenAPI specification file.

Security Definitions

11. Describe how to define an OAuth2 security scheme with multiple scopes.

You define this in the `components.securitySchemes` object.

  1. Create a security scheme with `type: oauth2`.
  2. Define the `flows` object. For an Authorization Code flow, you would specify the `authorizationUrl`, `tokenUrl`, and a `scopes` object.
  3. The `scopes` object is a map of scope names (e.g., `read:pets`) to a short description of the permission.

Then, in an operation’s `security` requirement, you specify the scopes needed for that operation: `- petstore_auth: [“write:pets”, “read:pets”]`.

Read the documentation on OAuth2 Authentication.

12. How do you specify that an endpoint can be accessed by either an API Key OR an OAuth2 token?

You can define multiple security requirements in an operation’s `security` array. Each item in the array is a map of security schemes. If you want to specify an “OR” relationship, you place each scheme in a separate map within the array.

Example: security:
  - oauth2_scheme: ["read:users"]
  - apikey_scheme: []

This indicates that the client must satisfy the requirements of *either* `oauth2_scheme` OR `apikey_scheme`.

13. What is the difference between `securitySchemes` and a `security` requirement?

  • `securitySchemes`: This is where you **define** the security methods your API supports. It’s a “library” of available schemes, located in the `components` object. It describes *how* to authenticate (e.g., “this API supports bearer tokens”).
  • `security`: This is where you **apply** one or more of those defined schemes to a specific operation or globally to the entire API. It specifies *that* an operation is secured and which scopes are required.

14. How do you define OpenID Connect authentication?

You define a security scheme with `type: openIdConnect`. The key piece of information you must provide is the `openIdConnectUrl`, which points to the OIDC Discovery document (`/.well-known/openid-configuration`). This document contains all the metadata that clients and tools need to know about the provider, including the locations of the authorization and token endpoints, and the supported scopes and claims.

Tooling & API Lifecycle

15. What is contract testing and how does OpenAPI enable it?

**Contract testing** is a method for verifying that two separate systems (like an API provider and a consumer) are compatible with each other without performing a full end-to-end integration test. It focuses on checking that the “contract”—the agreed-upon format of requests and responses—is being honored by both sides.

OpenAPI enables this by acting as that formal, machine-readable contract. Tools can use the OpenAPI spec to:

  • Automatically generate mock servers for consumer tests.
  • Validate that the responses from the real provider match the schemas defined in the spec.
  • Check that a consumer’s requests conform to the provider’s expectations.
Learn more about Contract Testing.

16. Describe a design-first vs. a code-first approach to API development.

  • Design-First: You begin by creating the OpenAPI specification. This specification serves as the contract and single source of truth. Frontend and backend teams can work in parallel against this contract, using mock servers and code generators. This approach is generally recommended as it encourages better planning and collaboration.
  • Code-First: You begin by writing the application code (e.g., controllers and models). The OpenAPI specification is then generated automatically from annotations or comments in your source code. This can be faster for initial development but risks the documentation becoming an afterthought and can lead to a less coherent API design.

17. What is the purpose of an API linter?

An API linter is a tool that automatically checks an OpenAPI specification against a set of configurable rules and best practices. It helps enforce consistency and quality across all of your organization’s APIs.

For example, a linter can enforce rules like:

  • All paths must use kebab-case.
  • All operations must have a `summary` and an `operationId`.
  • All parameters must have an `example`.
  • All 4xx/5xx responses must conform to a standard error schema.

This is typically run as a step in a CI pipeline.

18. What are the pros and cons of using code generators from an OpenAPI spec?

Pros:

  • Speed: Quickly bootstrap client SDKs, server stubs, and data models, reducing boilerplate code.
  • Consistency: Ensures that the client and server code are always in sync with the API contract.
  • Language Support: Generate code for dozens of different languages from a single specification.

Cons:

  • Code Quality: The generated code can sometimes be non-idiomatic or difficult to customize.
  • Customization Overhead: Modifying the generation templates can be complex.
  • Tooling Lock-in: You become dependent on the specific code generation tool and its quirks.

Advanced Concepts

19. How does OpenAPI differ from specifications like gRPC or AsyncAPI?

They describe different types of APIs:

  • OpenAPI: Specifically designed for describing synchronous, request-response RESTful (or REST-like) HTTP APIs.
  • gRPC: Uses Protocol Buffers to define services and messages for Remote Procedure Call (RPC) APIs. It’s for high-performance, contract-based internal communication, not typically for public-facing APIs.
  • AsyncAPI: Inspired by OpenAPI, but designed for describing asynchronous, event-driven architectures. It describes message brokers, channels, and events, rather than HTTP endpoints. It’s for systems that use protocols like AMQP (RabbitMQ) or MQTT.

20. What is a “tag” used for in an OpenAPI spec?

Tags are used for logically grouping operations together. You can assign one or more tags to an operation. API documentation tools like Swagger UI use these tags to group the displayed endpoints into collapsible sections (e.g., “Users”, “Products”). This makes the documentation much easier for consumers to navigate.

21. How would you document an API that uses server-sent events (SSE)?

This is a challenge as OpenAPI is primarily for request-response. A common approach is to document the initial endpoint that establishes the SSE connection. You would describe the response’s content type as `text/event-stream`. The schema for this response can’t fully describe the stream, so you would use the `description` field to extensively document the different types of events that can be sent over the stream, including their format and meaning. For a fully machine-readable contract, you would need to use a different specification like AsyncAPI alongside OpenAPI.

22. What does it mean if a parameter is defined as `style: form` and `explode: true`?

These keywords describe how an array or object parameter is serialized in the URL’s query string.

  • `style: form`: Indicates a form-style query parameter (e.g., `key=value`).
  • `explode: true`: For an array, this means each element gets its own key (e.g., `id=1&id=2&id=3`). If `explode` were `false`, it would be `id=1,2,3`.

So for an array parameter named `id` with value `[1, 2, 3]`, this combination would result in the query string `?id=1&id=2&id=3`.

23. Can you reference a schema component from an external file? If so, how?

Yes. The `$ref` keyword can point to external files. Instead of an internal pointer like `#/components/schemas/User`, you would use a relative file path or a URL.

Example: `$ref: ‘./schemas/User.yaml’`. If the external file is also an OpenAPI document, you can point to a specific component within it: `$ref: ‘./shared-components.yaml#/components/schemas/Error’`. This is the core mechanism that enables splitting a large specification into multiple manageable files.

24. What is the purpose of the `servers` object?

The `servers` object allows you to specify one or more base URLs for your API. This is useful for defining different environments, such as development, staging, and production. API documentation tools can then provide a dropdown for users to select which server they want to send test requests to. You can also use variables within the server URL to handle things like different regions (e.g., `{region}.api.example.com`).

25. What is the `deprecated` keyword used for?

The boolean `deprecated` keyword can be applied to an operation or a specific field within a schema. When set to `true`, it signals to API consumers that the element should no longer be used and may be removed in a future version. API documentation tools will typically render deprecated elements differently (e.g., with a strikethrough) to warn developers. This is a key part of managing an API’s lifecycle gracefully without breaking existing clients.

Skip the interview marathon.

We pre-vet senior engineers across Asia using these exact questions and more. Get matched in 24 hours, $0 upfront.

Get Pre-Vetted Talent
WhatsApp