Web APIs
CRUD Operations
CRUD stands for Create, Read, Update, Delete. These four operations represent everything you can do with data in any system. When you post a photo to Instagram, that is Create. When you scroll through your feed, that is Read. When you edit your bio, that is Update. When you remove an old post, that is Delete.
The genius of REST architecture is how it maps these universal data operations to HTTP methods. POST creates new resources. GET reads existing ones. PUT and PATCH update resources in different ways. DELETE removes resources entirely.
But here is where most developers stumble. They think CRUD means just copying database operations into API endpoints. Wrong approach. CRUD in APIs is about designing intuitive interfaces that make sense to client applications, not exposing your database schema to the world.
Understanding CRUD Fundamentals
Every piece of data in your application follows a lifecycle. Resources get created when users sign up or upload content. They get read when other users browse or search. They get updated as information changes or users edit their content. Eventually, some resources get deleted when they are no longer needed.This lifecycle maps naturally to HTTP methods, but the mapping is not always obvious. Consider a user profile. Creating a profile uses POST, reading it uses GET, updating the email address uses PATCH. But what about deactivating an account? Some APIs use DELETE, others use PATCH to update a status field.
The key insight is that CRUD operations should match how clients think about resources, not how your database stores them. A client wants to "create a new project" or "update this task description." They should not need to think about foreign keys, junction tables, or database constraints.
The Four Core Operations
Create operations bring new resources into existence. When Slack creates a new workspace, Shopify adds a product to your store, or Twitter posts a new tweet, they are performing Create operations. These always use POST method because you are asking the server to process new data and assign it an identifier.Read operations retrieve existing resources without changing them. Every time you load a GitHub repository, check your bank balance through an app, or browse Netflix recommendations, you are triggering Read operations. GET method handles all reading, from single resources to filtered lists.
Update operations modify existing resources. But here is where it gets interesting — REST provides two different update approaches. PUT replaces the entire resource with new data. PATCH applies partial changes to specific fields. The choice between them depends on how much control you want to give clients.
Delete operations remove resources from the system. When you delete a photo from Google Photos, remove a contact from your phone, or cancel a subscription, the API performs a Delete operation. DELETE method signals permanent removal, though the actual implementation might just mark records as inactive.
| Operation | HTTP Method | Purpose | Example |
|---|---|---|---|
| Create | POST | Add new resource | POST /api/projects |
| Read | GET | Retrieve existing resource | GET /api/projects/123 |
| Update | PUT/PATCH | Modify existing resource | PATCH /api/projects/123 |
| Delete | DELETE | Remove resource | DELETE /api/projects/123 |
Create Operations (POST)
Creating resources is where most APIs start getting complex. The operation seems simple — accept some data, validate it, store it, return the created resource. But production systems need to handle duplicate submissions, validate business rules, trigger side effects, and maintain data consistency.POST requests carry the new resource data in the request body. Unlike GET requests that put everything in the URL, POST can handle large payloads with complex nested data structures. This makes POST perfect for creating resources with multiple fields, uploaded files, or related data.
The response to a successful Create operation should return HTTP status 201 Created, not 200 OK. Status 201 specifically indicates that a new resource was created, and clients often rely on this distinction. The response should include the full created resource with any server-generated fields like ID, timestamps, or computed values.
Validation happens at multiple levels during Create operations. Input validation checks data types, required fields, and format constraints. Business validation enforces domain rules like unique usernames or valid date ranges. Some validation requires database queries to check references or uniqueness constraints.
Error responses for failed Create operations typically return 400 Bad Request with detailed validation errors. The response body should explain exactly what went wrong and how to fix it. Generic error messages frustrate developers and slow down integration.
# APIForge Backend team creating a new developer project
POST /api/v1/projects HTTP/1.1
Host: api.apiforge.dev
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
{
"name": "Mobile Payment Gateway",
"description": "Secure payment processing for mobile apps",
"tech_stack": ["Node.js", "PostgreSQL", "Redis"],
"team_size": 4,
"deadline": "2024-06-15",
"priority": "high"
}Read Operations (GET)
Reading data is the most frequent operation in most APIs. Every page load, every refresh, every search triggers Read operations. GET requests should be fast, cacheable, and predictable because they form the backbone of user experience.GET operations never modify server state. This property, called idempotence, means clients can safely retry GET requests, browsers can cache responses, and CDNs can serve responses from edge locations. Breaking this rule by using GET to trigger side effects confuses caching systems and violates HTTP semantics.
Single resource reads return one specific item identified by its ID or unique key. Collection reads return multiple resources, usually with filtering, sorting, and pagination options. The URL structure should make this distinction clear — `/api/projects/123` for single resources, `/api/projects` for collections.
Response data should include everything clients need to display or work with the resource. But avoid returning sensitive data that only some users should see. Consider the requesting user's permissions and filter response fields accordingly. Some APIs return different field sets based on access level.
# APIForge Frontend team fetching project details for dashboard
GET /api/v1/projects/proj_7x9k2m8n4p1q HTTP/1.1
Host: api.apiforge.dev
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
If-None-Match: "etag-abc123def456"Collection reads often need additional parameters for filtering, sorting, and pagination. Query parameters handle these concerns cleanly. `GET /api/projects?status=active&sort=deadline` reads all active projects sorted by deadline. Keep query parameter names intuitive and document the supported options clearly.
Error handling for Read operations focuses on resource existence and access permissions. Return 404 Not Found when the resource does not exist. Return 403 Forbidden when the user lacks permission to read it. Avoid exposing whether resources exist when users should not know about them — use 404 for both cases.
Update Operations (PUT & PATCH)
Update operations split into two approaches with different semantics and use cases. PUT replaces the entire resource with new data. PATCH applies partial modifications to specific fields. The choice affects how clients prepare requests and how servers process them.PUT semantics require sending the complete resource representation. If a project resource has ten fields, PUT requests should include all ten fields, even unchanged ones. The server replaces the entire resource with the provided data. Missing fields get set to null or default values, which can cause data loss if clients are not careful.
PATCH semantics allow partial updates with just the fields that changed. A PATCH request might include only the project name and deadline, leaving other fields untouched. This approach reduces payload size and prevents accidental data loss, making it more popular for most update scenarios.
Response handling for updates typically returns the modified resource with 200 OK status. Some APIs return 204 No Content if the response body would just duplicate the request data. Include any server-computed fields like updated timestamps or version numbers in the response.
# APIForge Product team updating project priority and deadline
PATCH /api/v1/projects/proj_7x9k2m8n4p1q HTTP/1.1
Host: api.apiforge.dev
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
If-Match: "etag-xyz789ghi012"
{
"priority": "urgent",
"deadline": "2024-05-30T23:59:59Z",
"team_size": 6
}Optimistic locking prevents lost updates when multiple clients modify the same resource simultaneously. ETags provide a clean mechanism for this. Clients include the If-Match header with the ETag from their last read. The server processes the update only if the ETag matches, returning 412 Precondition Failed if another client modified the resource first.
Validation for updates checks both field-level constraints and business rules. Some fields might be read-only after creation. Others might have complex validation that depends on the resource's current state. Update operations should validate only the fields being changed, not require all validation to pass.
| Aspect | PUT | PATCH |
|---|---|---|
| Payload | Complete resource | Only changed fields |
| Missing fields | Set to null/default | Unchanged |
| Use case | Full replacement | Partial updates |
| Risk | Accidental data loss | Minimal |
Delete Operations (DELETE)
Deletion seems straightforward but raises complex questions about data permanence, cascading effects, and user intent. Real-world systems rarely delete data immediately. Instead, they mark resources as deleted, archive them, or require multi-step confirmation processes.Hard deletes permanently remove data from the system with no recovery option. Soft deletes mark resources as deleted while preserving the underlying data for potential recovery or audit purposes. The choice depends on business requirements, regulatory constraints, and user expectations.
DELETE operations should return appropriate status codes based on the outcome. Return 204 No Content for successful deletions with no response body. Return 200 OK if the response includes confirmation details or related information. Return 404 Not Found if the resource does not exist or was already deleted.
Cascading deletes affect related resources when a parent resource gets deleted. Deleting a project might also delete its tasks, files, and comments. Some APIs handle this automatically, others require explicit confirmation, and some block deletion until related resources are handled separately.
# APIForge Security team removing a completed security audit project
DELETE /api/v1/projects/proj_7x9k2m8n4p1q HTTP/1.1
Host: api.apiforge.dev
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
X-Confirmation-Token: delete_confirm_abc123def456Permission checks for Delete operations should be more restrictive than other operations. Consider requiring additional confirmation for destructive actions. Some systems require manager approval for deleting shared resources or implement cooling-off periods before permanent deletion.
Error responses for Delete operations should distinguish between different failure reasons. Return 403 Forbidden for insufficient permissions, 409 Conflict for resources that cannot be deleted due to dependencies, and 404 Not Found for resources that do not exist.
CRUD Best Practices
Production CRUD APIs need patterns that handle edge cases, performance requirements, and user experience concerns. These patterns separate hobby projects from systems that serve millions of users reliably.Idempotency keys prevent duplicate resource creation when clients retry failed requests. POST operations are not naturally idempotent, but you can make them behave that way by accepting an idempotency key in the request. If the same key appears twice, return the original resource instead of creating a duplicate.
Bulk operations allow clients to perform multiple CRUD operations in a single request. Creating ten resources with ten separate POST requests creates network overhead and consistency challenges. Bulk endpoints accept arrays of operations and process them efficiently, though they complicate error handling since some operations might succeed while others fail.
Versioning becomes critical when CRUD operations evolve over time. Adding optional fields is usually safe, but removing fields or changing validation rules can break existing clients. API versioning strategies help manage these changes while maintaining backward compatibility.
Audit trails track who performed which operations when. This becomes essential for compliance, debugging, and user accountability. Store enough context to understand what changed, who made the change, and why. Consider privacy requirements when deciding how much detail to log.
Response consistency across all CRUD operations improves client development experience. Use the same field names, date formats, and nested structures whether returning resources from CREATE, READ, or UPDATE operations. Clients should be able to use the same data structures for all operations.
Error message quality directly affects how quickly developers can integrate with your API. Provide specific error codes for different validation failures. Include the field name that caused the error and suggest how to fix it. Generic "bad request" messages waste everyone's time.
| Best Practice | What It Does | APIForge Use Case |
|---|---|---|
| Idempotency Keys | Prevent duplicate creation on retry | Avoid duplicate project creation when network fails |
| Optimistic Locking | Prevent conflicting updates | Handle multiple team members editing project details |
| Soft Deletion | Enable recovery of deleted resources | Allow project recovery within 30-day window |
| Bulk Operations | Process multiple resources efficiently | Import multiple team members in single request |
| Audit Logging | Track all data changes | Monitor security-sensitive project modifications |
Quiz
1. The APIForge Frontend team needs to update just the deadline and priority of a project without affecting other fields. What is the most appropriate approach?
2. When a CREATE operation successfully adds a new project to the APIForge system, what should the API response include?
3. The APIForge mobile app needs to create a new project, but the network connection is unreliable and might cause request timeouts. How should the app handle potential duplicate submissions?