Skip to main content

How to choose between OpenAPI and AsyncAPI for microservices

Symptom & Diagnostic Output

When polyglot microservice architectures emit both synchronous HTTP responses and asynchronous Kafka/AMQP events, CI/CD pipelines frequently fail during contract validation. The absence of a unified API Contract Fundamentals & Tool Selection strategy causes duplicated JSON Schema definitions that diverge across independent deployments. The failure typically manifests with the following diagnostic output:

ERROR [contract-validator]: SchemaValidationError: Expected synchronous response schema (OpenAPI 3.1), received async message envelope (AsyncAPI 2.6). Contract drift detected in shared payload definitions. Field mismatch: 'user_id' (integer) vs 'userId' (string). Exit code 1.

This error indicates that frontend teams consuming REST endpoints and backend services publishing domain events are operating on desynchronized type definitions. The validator halts execution because structural parity between sync and async contracts cannot be guaranteed.

Root Cause Analysis

The architectural split stems from treating request-response and event-driven communication as isolated contract domains. Engineering teams default to an OpenAPI Specification Deep Dive for HTTP routing but fail to map identical domain objects to AsyncAPI message payloads. Without a centralized schema registry, identical types (e.g., UserCreated, OrderUpdated) are manually redefined in both specifications. This manual duplication introduces type coercion mismatches, missing required fields in async payloads, and version skew that breaks downstream consumer tests.

Resolution Workflow

To resolve contract drift and enforce parity across sync/async boundaries, implement the following diagnostic and remediation steps:

  1. Extract Shared Domain Models: Centralize language-agnostic JSON Schema definitions in a dedicated repository. Define base types using draft-07 or draft-2020-12 with strict additionalProperties: false to prevent silent field additions.
  2. Configure OpenAPI References: Map components/schemas to $ref the centralized base types. Ensure type: object and required arrays match exactly across all HTTP response definitions.
  3. Map AsyncAPI Payloads: Bind identical base types to AsyncAPI components/messages via the payload field. Append contentType: application/json and enforce identical properties definitions to guarantee structural parity.
  4. Implement Cross-Spec Validation Hooks: Integrate @stoplight/spectral or asyncapi-cli validate into your CI pipeline. Patch the .spectral.yaml ruleset to cross-validate OpenAPI and AsyncAPI schemas against the central registry.
  5. Enforce Strict CI Parity Checks: Apply the following pipeline configuration to block deployments on schema divergence:
# ci/contract-validation.yml
validate_sync_async:
 image: stoplight/spectral:latest
 script: |
 spectral lint openapi.yaml --ruleset .spectral.yaml
 asyncapi validate asyncapi.yaml
 spectral lint openapi.yaml asyncapi.yaml --ruleset .cross-spec-rules.yaml

Cross-Spec Validation Configuration

Deploy the following Spectral ruleset to operationalize automated parity enforcement. The ruleset validates reference integrity and payload mapping consistency across both specifications:

# spectral-ruleset.yaml
rules:
 schema-parity-check:
 description: Ensure OpenAPI and AsyncAPI schemas reference identical base types
 severity: error
 given: $.components.schemas.*
 then:
 field: $ref
 function: pattern
 functionOptions:
 match: '^#/components/schemas/'
 async-payload-mapping:
 description: AsyncAPI message payloads must mirror OpenAPI response schemas
 severity: error
 given: $.components.messages.*.payload
 then:
 field: $ref
 function: pattern
 functionOptions:
 match: '^#/components/schemas/'

Enable strictMode: true in your JSON Schema validators. Enforce unevaluatedProperties: false (draft-2019-09+) to block silent field additions. Configure OpenAPI x-asyncapi extensions to explicitly link synchronous endpoints to their corresponding async message topics, enabling automated cross-spec validation during CI.

Prevention & Governance

Establish a schema-first governance policy where all microservice contracts originate from a single source of truth. Enforce automated drift detection by integrating schema diffing into PR checks. Mandate uniform JSON Schema versions across sync and async boundaries. Deploy contract testing frameworks (e.g., Pact, Schemathesis) to validate both HTTP and message broker payloads against the unified registry prior to deployment. Regularly audit spec generation toolchains to ensure they inherit from centralized type definitions, eliminating ad-hoc schema declarations.