REST Lens
← Back to All Rules
Rule 53

Create/Update Return

Category: Response Design

Description

Create and update operations (POST, PUT, PATCH) must return the created or modified resource in the response body to provide immediate feedback to API consumers.

What It Checks

This rule validates that POST, PUT, and PATCH operations return meaningful content in their successful (2xx) responses. It specifically checks:

  • All POST, PUT, and PATCH operations in the API specification
  • Successful responses (status codes starting with "2")
  • Response content types of application/json or application/xml
  • That the response schema contains properties (non-empty object)

The rule ensures that clients receive either the complete resource representation or at least an identifier after modification operations, rather than an empty response.

Why It Matters

Returning the modified resource provides essential benefits for API consumers:

  • Immediate feedback: Clients instantly see the result of their operation without requiring a follow-up GET request
  • Server-generated values: Clients receive any server-computed fields (timestamps, auto-generated IDs, defaults, calculated values)
  • Validation confirmation: Clients can verify that their data was processed correctly, including any transformations or normalizations
  • Reduced round trips: Eliminates the need for a separate GET request to fetch the created/updated resource, improving performance and reducing latency

Examples

Good ✅

paths:
  /users:
    post:
      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
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  email:
                    type: string
                  createdAt:
                    type: string
                    format: date-time
                  updatedAt:
                    type: string
                    format: date-time

  /users/{userId}:
    put:
      summary: Update a user
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                email:
                  type: string
      responses:
        '200':
          description: User updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  email:
                    type: string
                  updatedAt:
                    type: string
                    format: date-time

    patch:
      summary: Partially update a user
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
      responses:
        '200':
          description: User updated successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  name:
                    type: string
                  email:
                    type: string
                  updatedAt:
                    type: string
                    format: date-time

Bad ❌

paths:
  /users:
    post:
      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
          # No response body - violation!

  /users/{userId}:
    put:
      summary: Update a user
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
      responses:
        '200':
          description: User updated
          content:
            application/json:
              schema:
                type: object
                # Empty object - violation!

    patch:
      summary: Partially update a user
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                bio:
                  type: string
      responses:
        '204':
          description: No content
          # 204 with no body - violation!

Configuration

This rule has no configuration options. It is either enabled or disabled.

How to Fix

  1. Add response schemas to POST operations:

    # Before
    responses:
      '201':
        description: Created
    
    # After
    responses:
      '201':
        description: Created
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
    
  2. Add response schemas to PUT operations:

    # Before
    responses:
      '200':
        description: Updated
    
    # After
    responses:
      '200':
        description: Updated
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
    
  3. Add response schemas to PATCH operations:

    # Before
    responses:
      '204':
        description: No content
    
    # After
    responses:
      '200':
        description: Updated
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/User'
    
  4. Include server-generated fields in the response schema:

    • id: Auto-generated identifier
    • createdAt: Creation timestamp
    • updatedAt: Last modification timestamp
    • Computed or calculated fields
    • Default values applied by the server
  5. Ensure the response schema is not empty:

    • Define at least the id field if returning minimal data
    • Include all fields from the request plus server-generated fields for complete representation
    • Use schema references ($ref) to maintain consistency with GET operations

Related Rules

  • Rule 19: Location on Create - Create operations should include a Location header
  • Rule 34: Code 201 Create - POST operations should return 201 status code
  • Rule 35: Code 204 Empty - 204 No Content should only be used when no response body is appropriate