HTTP Method Mapping Guidelines
Precise HTTP verb assignment is the foundation of predictable API contracts, deterministic SDK generation, and reliable client retry logic. This guide establishes strict verb-to-operation mappings aligned with RFC 9110, provides CI/CD enforcement workflows, and details type-safe client scaffolding patterns for platform teams and API architects.
Core HTTP Semantics & API Contract Alignment
Establishing deterministic mappings between HTTP methods and backend operations eliminates ambiguity before spec generation. Align routing rules with foundational architectural principles documented in API Design Fundamentals & Architecture to guarantee consistent contract definitions across microservices.
RFC 9110 defines strict safety and idempotency guarantees that must be enforced at the contract layer:
GET/HEAD: Safe, cacheable, idempotent. No side effects.POST: Unsafe, non-idempotent. Resource creation or command execution.PUT: Unsafe, idempotent. Full resource replacement.PATCH: Unsafe, non-idempotent (unless explicitly constrained). Partial modification.DELETE: Unsafe, idempotent. Resource removal.
Spec Implementation: OpenAPI 3.1 operationId Convention
paths:
/users:
post:
operationId: createUser
summary: Create a new user resource
/users/{id}:
get:
operationId: getUser
put:
operationId: replaceUser
patch:
operationId: patchUser
delete:
operationId: deleteUser
Enforce operationId consistency to prevent codegen collisions. Each verb must map to a single, unambiguous controller action or service method.
Resource-Centric Method Assignment
HTTP methods must operate on noun-based resource paths, not verb-embedded endpoints. Reference Resource Modeling Best Practices to enforce entity boundaries, collection semantics, and strict path parameter scoping.
Collection vs. Item Routing Rules:
/users(Collection):GET(list),POST(create)/users/{id}(Item):GET(read),PUT(replace),PATCH(modify),DELETE(remove)
Anti-Pattern Mitigation:
- ❌
POST /createUser→ Violates resource-centric routing. UsePOST /users. - ❌
GET /deleteUser/{id}→ Breaks HTTP safety guarantees. UseDELETE /users/{id}. - ❌
POST /users/{id}/update→ Redundant verb in path. UsePUT /users/{id}orPATCH /users/{id}.
Common Pitfall: Generating SDK methods with ambiguous names (e.g., update() for both PUT and PATCH) leads to type collisions and incorrect payload serialization. Enforce distinct operationId values to drive explicit replace() vs updatePartial() client methods.
Spec Validation & CI/CD Enforcement
Automate method compliance using Spectral rules, OpenAPI linting, and pipeline gates. Integrate caching directives and stateless routing validation as outlined in Statelessness & Caching Strategies to prevent unsafe method generation in downstream SDKs and API gateways.
Spectral Rule Configuration (.spectral.json)
{
"rules": {
"http-method-allowed": {
"description": "Only standard CRUD verbs are permitted on resource paths",
"severity": "error",
"given": "$.paths[*][*]",
"then": {
"field": "operationId",
"function": "pattern",
"functionOptions": {
"match": "^(get|create|replace|patch|delete|list|search)[A-Z][a-zA-Z]+$"
}
}
},
"mutation-content-type-required": {
"description": "POST/PUT/PATCH must declare application/json",
"severity": "error",
"given": "$.paths[?(@property.match(/^(post|put|patch)$/i))].requestBody.content",
"then": {
"function": "schema",
"functionOptions": {
"schema": { "type": "object", "required": ["application/json"] }
}
}
}
}
}
CI Pipeline Gate (GitHub Actions)
- name: Validate OpenAPI Contract
run: |
npm install -g @stoplight/spectral-cli
spectral lint openapi.yaml --ruleset .spectral.json --format github-actions
if [ $? -ne 0 ]; then
echo "::error::HTTP method mapping validation failed. Fix spec before proceeding to SDK generation."
exit 1
fi
405 Method Not Allowed Enforcement Explicitly declare supported verbs in error responses to prevent client retry storms:
responses:
'405':
description: Method Not Allowed
headers:
Allow:
schema:
type: string
example: "GET, POST, PUT, PATCH, DELETE"
x-supported-methods: ["GET", "POST", "PUT", "PATCH", "DELETE"]
Common Pitfall: Failing to enforce Content-Type: application/json on mutation methods in CI causes 415 Unsupported Media Type in production. The Spectral rule above blocks non-compliant specs at merge.
Partial Updates & Idempotency Workflows
Define strict boundaries for mutation operations to enable retry-safe client generation. Apply decision matrices from When to use PUT vs PATCH for partial updates to configure middleware, validate request schemas, and generate type-safe method signatures.
Idempotency Key Extension Require explicit idempotency headers for non-idempotent mutations to guarantee safe retries:
parameters:
- name: X-Idempotency-Key
in: header
required: true
schema:
type: string
format: uuid
description: Client-generated UUID to guarantee exactly-once processing for POST/PATCH
Client Generation Configurations
| Generator | Configuration / Pattern |
|---|---|
| TypeScript SDK | api.users.create(), api.users.replace(), api.users.updatePartial() with strict type inference from OpenAPI schemas. |
| Python (OpenAPI Generator) | method_mapping: {POST: 'create', PUT: 'replace', PATCH: 'update'} in config.yaml to prevent method collision. |
| Kiota | Retry policy injection: auto-retry only on idempotent verbs (GET, PUT, DELETE). Bypass POST/PATCH unless X-Idempotency-Key is present. |
| Axios/Fetch Wrapper | Automatic If-None-Match and Cache-Control attachment for GET/HEAD. Explicitly stripped for mutation methods to prevent stale cache writes. |
Common Pitfalls:
- Using
POSTfor idempotent data retrieval breaks HTTP cache semantics and CDN edge routing. - Omitting
x-http-method-overridehandling in strict enterprise proxies causes405errors on legacy clients tunnelingPUT/DELETEthroughPOST. - Ignoring
Allowheader responses causes generated clients to enter infinite retry loops on unsupported verbs.
Frequently Asked Questions
How do I enforce HTTP method mapping in CI/CD pipelines?
Use Spectral or OpenAPI linting rules to validate operationId naming, verb-to-path alignment, and required headers. Fail builds on non-compliant specs before triggering client generation or deployment.
Which HTTP methods should trigger automatic retries in generated SDKs?
Only idempotent methods (GET, HEAD, PUT, DELETE) should be auto-retried. POST and PATCH require explicit idempotency keys or manual retry logic to prevent duplicate side effects.
How do I map PATCH vs PUT in OpenAPI for type-safe client generation?
Define separate operations with distinct operationId values and request schemas. Use x-method extensions if needed, and configure generators to output separate replace() and updatePartial() methods with strict TypeScript/Python typing.
What CI checks prevent N+1 query patterns in generated clients?
Enforce ?include= or GraphQL-style query parameters in specs, validate response schema depth limits, and run static analysis on generated client code to flag unbatched sequential calls across related resources.