Category: HTTP Methods
Description
POST requests should be used for creating new resources, not GET or other methods.
What It Checks
This rule validates that resource creation operations use the POST HTTP method:
- Detects endpoints with "create" semantics
- Checks that they use POST (not GET, PUT, or others)
- Ensures proper REST method usage
Why It Matters
Using POST for creation is a core REST principle:
- Idempotency: POST is non-idempotent, matching create semantics
- HTTP standards: POST is defined for creating subordinate resources
- Client expectations: Developers expect POST for creation
- Caching: GET requests may be cached, inappropriate for mutations
Examples
Good ✅
paths:
/users:
post: # ✅ Correct method for creation
summary: Create a new user
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
email:
type: string
responses:
'201':
description: User created successfully
/orders:
post: # ✅ POST for creating orders
summary: Create an order
responses:
'201':
description: Order created
Bad ❌
paths:
/users/create:
get: # ❌ Using GET for creation
summary: Create a new user
parameters:
- name: name
in: query
- name: email
in: query
responses:
'200':
description: User created
/users:
put: # ❌ PUT should be for updates
summary: Create a user
requestBody:
required: true
responses:
'200':
description: Created
HTTP Method Semantics
| Method | Purpose | Idempotent | Use Case |
|---|---|---|---|
| POST | Create new resource | No | Creating a new user, order, etc. |
| PUT | Replace entire resource | Yes | Updating all fields of a resource |
| PATCH | Partial update | No | Updating specific fields |
| GET | Retrieve resource | Yes | Reading data (never for creation!) |
| DELETE | Remove resource | Yes | Deleting a resource |
Common Violations
1. GET for Create
# Bad - GET should never create resources
GET /users/create?name=John&[email protected]
# Good
POST /users
Content-Type: application/json
{
"name": "John",
"email": "[email protected]"
}
2. PUT for Create (without known ID)
# Bad - PUT requires knowing the full URI
PUT /users
{ "name": "John" }
# Good - POST lets server assign ID
POST /users
{ "name": "John" }
# Returns: Location: /users/12345
When to Use PUT vs POST
POST (for create)
- Server assigns resource ID
- Client doesn't know final URI
- Creating subordinate resources
POST /articles
{ "title": "New Article" }
→ Returns 201 with Location: /articles/789
PUT (for upsert with known ID)
- Client specifies exact URI
- Replaces entire resource
- Idempotent operation
PUT /articles/specific-slug
{ "title": "Article", "content": "..." }
→ Creates or replaces the article at this exact URI
Configuration
This rule has no configuration options.
How to Fix
-
Change GET to POST for creation:
# Before GET /users/create?name=John # After POST /users Body: { "name": "John" } -
Use POST instead of PUT for new resources:
# Before PUT /orders # Creating new order # After POST /orders -
Return 201 Created with Location header:
responses: '201': description: Resource created headers: Location: schema: type: string example: /users/12345
Best Practices
- Return 201 Created: Not 200 OK
- Include Location header: URI of the newly created resource
- Return the created resource: In the response body
- Use request body: Not query parameters for creation data
POST /users
Content-Type: application/json
{ "name": "Alice", "email": "[email protected]" }
Response:
201 Created
Location: /users/67890
Content-Type: application/json
{
"id": "67890",
"name": "Alice",
"email": "[email protected]",
"createdAt": "2025-12-22T10:30:00Z"
}
Related Rules
- Rule 34: Code 201 Create - Response status code for creation
- Rule 19: Location on Create - Location header requirement
- Rule 5: GET/POST Tunneling - Preventing GET misuse