Skip to content

API Gateway

The API Gateway is the single boundary we own around our resources. It is our service, running in our infrastructure, enforcing our policy. Consumers talk only to the gateway. Our resources live behind it.

Responsibilities

The gateway handles everything that crosses the boundary:

  • Authentication — Verifies consumer identity (API key, mTLS) and vendor identity (JWT, OAuth)
  • Authorization — Enforces per-consumer scoped permissions
  • Rate Limiting — Protects resources from overload, per-consumer and per-resource
  • Retries & Circuit Breakers — Handles transient failures, prevents cascading breakdowns
  • Error Translation — Maps vendor-specific errors to a uniform contract
  • Observability — Traces, logs, and metrics for every call
  • Webhooks — Routes inbound from resources and outbound to consumers
  • Idempotency — Deduplicates writes using idempotency keys

Internal Structure

gateway/
├── connectors/          # Resource-specific adapters
│   ├── salesforce/      # SF client, JWT auth, field mappings
│   ├── payments/        # Payment provider client
│   ├── partners/        # Dining, hotels, etc.
│   └── databases/       # Direct DB access
├── auth/                # Consumer auth (API key, mTLS)
├── ratelimit/           # Per-consumer, per-resource limits
├── retry/               # Bounded retry, circuit breaker
├── webhooks/
│   ├── inbound/         # Resources → gateway
│   └── outbound/        # Gateway → consumers
├── observability/       # Tracing, logging, metrics
├── schemas/             # JSON schemas for validation
└── test/
    ├── unit/
    └── integration/

Why We Own It

The gateway is the air gap between consumers and our vendor relationships. Without it:

  • Consumers would need direct access to Salesforce, partner APIs, payment providers
  • Vendor credentials would be scattered across consumer processes
  • Error handling, retries, and rate limits would be duplicated per consumer
  • Observability would be fragmented across vendors

With the gateway, consumers get one stable contract. We own the vendor relationship, the credential management, and the operational concerns.

Request Flow

  1. Consumer sends request to gateway
  2. Gateway authenticates the consumer
  3. Gateway checks rate limits
  4. Gateway routes to the appropriate connector
  5. Connector authenticates to the vendor
  6. Connector makes the vendor call
  7. Gateway handles errors, retries, circuit breakers
  8. Gateway logs and traces the call
  9. Gateway returns the response to the consumer

Connectors

Each resource has a connector that encapsulates:

  • Vendor-specific authentication
  • API translation (our contract ↔ vendor API)
  • Error mapping (vendor errors → our error categories)
  • Rate limit tracking (vendor quotas)

Connectors are independent. The Salesforce connector can evolve without affecting the partner or payment connectors. See Authentication for vendor auth patterns.

Stateless Design

The gateway is stateless after authentication. Any request can hit any replica. The JWT token cache lives in Redis so replicas share tokens. This makes horizontal scaling trivial.

What the Gateway Does Not Do

  • It does not contain business logic. It routes and protects.
  • It does not store data. It proxies to our resources.
  • It does not make decisions about content. It enforces policy.
  • It does not expose vendor implementations. Consumers see our contract.

See Design Principles for the non-negotiable rules that govern the boundary.

Marchay Platform Documentation