FastAPI Basics • Lesson 20

Body - Updates

Learn how to update data using PUT for full replacement and PATCH for partial updates in FastAPI.

🎯 What You'll Learn

  • Implement full updates with PUT operations
  • Handle partial updates with PATCH operations
  • Use Pydantic's exclude_unset for partial data
  • Apply model copy with update parameter for partial updates

Body - Updates

🎯 What You'll Learn

  • Implement full updates with PUT operations
  • Handle partial updates with PATCH operations
  • Use Pydantic's exclude_unset for partial data
  • Apply model copy with update parameter for safe updates

📚 Theory

Data updates are a critical part of any API. FastAPI provides robust support for both full and partial updates using standard HTTP methods. Understanding the difference between PUT and PATCH is essential for building reliable APIs.

Full Updates with PUT

The HTTP PUT method is designed for complete resource replacement. When you use PUT, you're saying "replace the entire resource with this new data."

Example Scenario:

# Current item in database
{"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}

# PUT request body
{"name": "Barz", "price": 3, "description": None}

# Result after PUT (tax reverted to default!)
{"name": "Barz", "price": 3, "description": None, "tax": 10.5}

Critical Warning: Missing fields in PUT requests will use their model defaults, potentially overwriting valuable data. In the example above, the custom tax: 20.2 was lost and reverted to the default 10.5.

Partial Updates with PATCH

The HTTP PATCH method is designed for partial modifications. When you use PATCH, you're saying "only change these specific fields, leave everything else alone."

Example Scenario:

# Current item in database
{"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}

# PATCH request body (only price)
{"price": 25.99}

# Result after PATCH (other fields preserved!)
{"name": "Bar", "description": "The bartenders", "price": 25.99, "tax": 20.2}

Key Advantage: PATCH preserves existing data while only updating the fields you specify. This prevents accidental data loss.

When to Use Each Method

Use PUT when:

  • You have the complete, updated resource
  • You want to replace all fields intentionally
  • You're implementing "save" functionality where users edit all fields

Use PATCH when:

  • You only want to update specific fields
  • You're implementing incremental updates
  • You want to preserve existing data you don't have access to
  • You're building mobile apps with limited bandwidth

Real-World Considerations

PATCH Adoption: While PATCH is technically superior for partial updates, many development teams use only PUT for simplicity. FastAPI supports both approaches equally well, so choose what fits your team's needs.

API Design: Consider your client applications. Mobile apps often prefer PATCH to save bandwidth, while admin interfaces might use PUT for complete form submissions.

🔧 Key Concepts

Pydantic Integration

exclude_unset Parameter: The secret to safe partial updates lies in Pydantic's exclude_unset parameter:

# Only gets fields that were explicitly set in the request
update_data = item.dict(exclude_unset=True)

This excludes fields that weren't provided in the request, preventing default values from overwriting existing data.

Model Copying: Pydantic's .copy() method safely merges updates:

# Create updated model without mutating the original
updated_item = stored_item_model.copy(update=update_data)

JSON Encoding: Always use jsonable_encoder for database storage:

# Converts Pydantic models to JSON-compatible dictionaries
encoded_item = jsonable_encoder(updated_item)

Response Models

Always specify response_model=Item to ensure consistent API responses and automatic OpenAPI documentation generation.

💡 Best Practices

  • Use PUT for complete resource replacement
  • Use PATCH for partial updates to avoid data loss
  • Always validate that the resource exists before updating
  • Use exclude_unset=True to only get explicitly set fields
  • Handle 404 errors gracefully for non-existent resources
  • Use response_model to ensure consistent API responses

🔗 Additional Resources

💡 Hint

Use exclude_unset=True to only get fields that were actually set, then use .copy(update=...) to create updated model

Ready to Practice?

Now that you understand the theory, let's put it into practice with hands-on coding!

Start Interactive Lesson