CRUD Operations Mapping to HTTP Methods
Introduction
Almost every software application works with data. A user is created, a product is displayed, an order is updated, a payment method is removed, or a customer profile is changed. Although business systems can be complex, most data operations eventually come back to four basic actions: create new data, read existing data, update existing data, and delete existing data. These four actions are collectively called CRUD operations.
REST APIs map CRUD operations to standard HTTP methods. Instead of creating a separate action-based URL for every operation, RESTful design uses resource-oriented URIs and lets the HTTP method describe the operation. The same resource path can support different behavior depending on whether the client sends GET, POST, PUT, PATCH, or DELETE. This makes APIs more predictable, easier to document, and easier to test.
For example, the URI /users represents the user collection. A GET request to /users retrieves users. A POST request to /users creates a user. The URI /users/101 represents one user. A GET request retrieves that user, PUT replaces the user, PATCH partially updates the user, and DELETE removes or deactivates the user according to the business rule. The URI identifies the resource; the HTTP method identifies the action.
For API testers, CRUD mapping is one of the most fundamental skills. It affects test case design, status code validation, header validation, request body validation, response body validation, database verification, negative testing, idempotency checks, and automation structure. A tester who understands CRUD mapping can quickly identify whether an endpoint is designed clearly or whether it uses methods and URIs inconsistently.
What Is CRUD?
CRUD stands for Create, Read, Update, and Delete. These are the four basic operations performed on data in most applications. Create adds a new record or resource. Read retrieves an existing resource or collection. Update modifies an existing resource. Delete removes, deactivates, archives, or otherwise eliminates a resource depending on the system's business rules.
A simple definition is this: CRUD is a set of four basic data operations that are commonly mapped to HTTP methods in REST APIs. In database terminology, CRUD often refers to inserting, selecting, updating, and deleting records. In API terminology, CRUD refers to creating, retrieving, modifying, and deleting resources through API endpoints.
CRUD is not limited to simple database tables. A resource may represent a user, customer, product, order, invoice, document, support ticket, employee, booking, payment method, learning page, or report. Whether the backend uses a relational database, NoSQL store, file storage, or multiple services, the API can still expose resource operations using CRUD-style behavior.
CRUD and HTTP Methods
In REST APIs, CRUD operations are usually mapped to HTTP methods in a standard way. Create maps to POST. Read maps to GET. Update maps to PUT or PATCH. Delete maps to DELETE. This mapping is not only a naming convention; it tells clients and infrastructure what kind of operation is happening.
The common mapping is:
Create - POST
Read - GET
Update - PUT or PATCH
Delete - DELETE
Using standard methods gives the API a uniform interface. Clients do not need to learn custom action words for every resource. Testers can build reusable expectations. Developers can document APIs consistently. Gateways, caches, security tools, and monitoring systems can interpret behavior more easily because HTTP methods already have defined meanings.
For example, GET is expected to retrieve data without changing server state. POST commonly creates a new resource under a collection. PUT is commonly used for full replacement of a resource. PATCH is used for partial modification. DELETE is used to remove or deactivate a resource. When APIs follow these conventions, consumers can reason about behavior before reading every implementation detail.
Sample Resource: Users
Assume an API exposes a user resource through /users. This resource collection can support multiple CRUD operations. The collection URI /users can be used to retrieve all users or create a new user. The individual resource URI /users/101 can be used to retrieve, replace, partially update, or delete user 101.
This is the basic REST pattern:
GET /users
POST /users
GET /users/101
PUT /users/101
PATCH /users/101
DELETE /users/101
Notice that the URI does not contain action names such as /getUsers, /createUser, or /deleteUser. The method communicates the action. The path communicates the resource. This separation is the foundation of CRUD mapping in RESTful APIs.
Create Operation with POST
Create means adding a new resource to the system. In REST APIs, create is commonly performed with POST on a collection URI. For example, to create a user, the client sends:
POST /users HTTP/1.1
Content-Type: application/json
{
"name": "John",
"email": "john@example.com"
}
The server validates the request, creates the user, assigns an identifier, saves the resource, and returns a response. A common successful response is:
HTTP/1.1 201 Created
Location: /users/101
Content-Type: application/json
{
"id": 101,
"name": "John",
"email": "john@example.com"
}
The 201 Created status code indicates that a new resource was created. The Location header points to the newly created resource if the API contract requires it. The response body may include the created resource, a summary, or no body depending on the design.
For API testers, POST validation includes checking required fields, optional fields, duplicate handling, validation errors, authentication, authorization, response status, Location header, response body, database state, and whether a subsequent GET can retrieve the new resource. Negative tests should include missing required fields, invalid email formats, duplicate records, unsupported Content-Type, unauthorized callers, and malformed JSON.
Read Operation with GET
Read means retrieving data from the server. In REST APIs, GET is used to read one resource or a collection of resources. To retrieve all users, a client may call:
GET /users
The response may be a list:
[
{
"id": 100,
"name": "Alice"
},
{
"id": 101,
"name": "John"
}
]
To retrieve one user, the client calls:
GET /users/101
The server returns a representation of that user if it exists and the caller is authorized. GET should not change server data. It may update logs, metrics, or cache metadata as part of infrastructure, but it should not perform business state changes such as deleting a user or submitting a payment.
API testers should validate that GET returns the correct resource, correct list, correct filters, correct pagination, correct status code, correct content type, and appropriate cache headers. Negative tests should include non-existing ids, invalid ids, unauthorized access, forbidden resources, unsupported query values, and attempts to use GET for state-changing behavior.
Update Operation with PUT
PUT is commonly used to replace an existing resource. In a full replacement model, the client sends the complete representation of the resource, and the server replaces the existing representation with the submitted one. For example:
PUT /users/101
Content-Type: application/json
{
"name": "John Smith",
"email": "johnsmith@example.com"
}
The response may be:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 101,
"name": "John Smith",
"email": "johnsmith@example.com"
}
Some APIs return 204 No Content after a successful PUT if no response body is needed. The exact status should follow the API contract. The key idea is that PUT is normally used for replacing the resource, not only updating one field.
Testers should pay close attention to how unspecified fields are handled. If PUT represents full replacement, missing fields may be cleared, defaulted, or rejected. If the API treats PUT like partial update, that should be documented, because it differs from the common expectation. PUT testing should validate full replacement behavior, required fields, validation rules, id consistency, unauthorized updates, and whether a subsequent GET reflects the new state.
Update Operation with PATCH
PATCH is used for partial updates. Instead of sending the full resource, the client sends only the fields that need to change. For example:
PATCH /users/101
Content-Type: application/json
{
"email": "newemail@example.com"
}
The server updates only the email field and leaves the name and other fields unchanged. A response may return the updated resource:
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 101,
"name": "John",
"email": "newemail@example.com"
}
PATCH is useful when clients need to modify a small part of a resource without sending everything. It reduces payload size and avoids accidental overwrites when the client does not own every field. However, PATCH behavior must be clearly documented. Some APIs use simple partial JSON objects. Others use formal patch formats.
API testers should verify that only specified fields change, unspecified fields remain unchanged, invalid fields are rejected, read-only fields cannot be modified, null values behave according to the contract, and authorization rules are enforced. PATCH testing is especially important because partial update rules can be subtle.
Delete Operation with DELETE
Delete means removing a resource, deactivating it, archiving it, or marking it as deleted depending on business rules. In REST APIs, DELETE is used on an individual resource URI:
DELETE /users/101
A common successful response is:
HTTP/1.1 204 No Content
Some APIs return 200 OK with a response body, especially when they want to return deletion status or the deleted resource summary. Others may use soft delete, where the resource is not physically removed from the database but is no longer active or visible in normal queries.
Testers should validate the delete result according to the contract. After DELETE, a subsequent GET may return 404 Not Found, 410 Gone, an inactive resource, or a forbidden response depending on design. Testers should also verify authorization, repeated DELETE behavior, deletion of non-existing resources, business constraints, audit requirements, and whether related resources are handled correctly.
Complete CRUD Flow
A complete CRUD flow often begins by creating a resource, reading it, updating it, partially updating it, and then deleting it. For a user resource, the flow may look like this:
POST /users
GET /users/101
PUT /users/101
PATCH /users/101
DELETE /users/101
This flow is useful in automation because it validates the lifecycle of a resource. The POST creates test data. The first GET confirms the resource exists. PUT verifies full replacement. PATCH verifies partial update. DELETE verifies removal or deactivation. A final GET can verify the expected post-delete behavior.
However, complete CRUD flows should be used thoughtfully. They are valuable for integration and end-to-end API validation, but individual endpoint tests should also exist. If one long flow fails, it may be harder to diagnose the exact broken behavior. A balanced suite includes focused endpoint tests and selected lifecycle flows.
HTTP Status Codes for CRUD
HTTP status codes communicate the result of a CRUD operation. POST that creates a resource commonly returns 201 Created. GET commonly returns 200 OK. PUT and PATCH commonly return 200 OK with a response body or 204 No Content without a body. DELETE commonly returns 204 No Content or 200 OK depending on the contract.
Negative status codes are equally important. Invalid request data may return 400 Bad Request. Missing authentication may return 401 Unauthorized. Insufficient permission may return 403 Forbidden. A non-existing resource may return 404 Not Found. Duplicate creation may return 409 Conflict. Unsupported media type may return 415 Unsupported Media Type. Server defects may return 500-level errors, though client mistakes should not normally produce 500 responses.
API testers should not assert only 200 for everything. Correct status codes help clients understand the result and respond properly. A CRUD API that returns 200 OK for validation errors, authorization failures, and server failures forces clients to parse custom body flags and weakens HTTP semantics.
CRUD in Real-World Applications
In an e-commerce application, customers read products with GET, add items to a cart with POST, update item quantity with PATCH, and remove items with DELETE. Product administrators may create products with POST, replace full product details with PUT, adjust inventory fields with PATCH, and deactivate products with DELETE.
In a banking application, users read accounts and transactions with GET, create beneficiaries with POST, update profile or notification preferences with PATCH, and delete beneficiaries with DELETE. Some operations, such as money transfer, may be modeled as creating a transfer resource using POST rather than directly updating an account balance.
In a streaming application, users read movies with GET, add watchlist items with POST, update profile settings with PATCH, and remove watchlist items with DELETE. In a code-hosting platform, users read repositories with GET, create repositories with POST, update repository metadata with PATCH, and delete repositories with DELETE if authorized.
POST Validation in API Testing
POST validation should confirm that resources are created correctly and safely. A valid request should produce the expected status, usually 201 Created for resource creation, and should return the created resource or required metadata. If the API requires a Location header, verify it points to the new resource. Then retrieve the resource and confirm the persisted state.
Negative POST tests should include missing required fields, invalid data types, invalid formats, duplicate data, unauthorized users, forbidden roles, unsupported Content-Type, malformed JSON, extra fields, boundary values, and business-rule violations. If creating a user requires a unique email, duplicate email should return a meaningful conflict or validation error. If creating an order requires a non-empty cart, an empty cart should be rejected.
POST is not always idempotent. Sending the same create request twice may create two resources unless the API uses idempotency keys. Payment and order APIs often use idempotency keys to prevent duplicate operations. Testers should verify this behavior where the API contract includes it.
GET Validation in API Testing
GET validation should confirm that the API retrieves correct data without modifying business state. For individual resources, validate the id, important fields, schema, authorization, and not-found behavior. For collections, validate filtering, searching, sorting, pagination, empty results, maximum limits, and response metadata.
GET requests often use query parameters, so testers should validate combinations carefully. A product search may include category, price range, availability, sort order, page, and size. A transaction list may include date range, account id, type, and pagination. Each filter should work alone and in meaningful combinations.
Caching can also affect GET. Public stable resources may include cache headers. Sensitive private resources should avoid unsafe caching. Testers should inspect response headers, not only the body. GET is the method most closely associated with caching, so cache behavior is part of GET validation.
PUT Validation in API Testing
PUT validation should focus on full replacement behavior. If the API contract says PUT replaces the entire resource, tests should send a complete resource and verify every updatable field. They should also test what happens when fields are missing. Are they cleared, defaulted, preserved, or rejected? The answer should be documented.
Testers should verify id consistency. If the path says /users/101 but the body contains "id": 202, the API should handle the mismatch predictably. Many APIs reject such requests. Others ignore the body id and use the path id. The contract should define behavior.
PUT may be idempotent when designed correctly. Sending the same PUT request multiple times should leave the resource in the same final state. Testers can repeat a PUT and verify that it does not create duplicates or produce unexpected changes.
PATCH Validation in API Testing
PATCH validation should focus on partial update behavior. Only specified fields should change. Unspecified fields should remain unchanged. Read-only fields such as id, created date, calculated status, or system-managed values should not be modified unless explicitly allowed.
PATCH tests should include valid single-field updates, multiple-field updates, invalid fields, null values, empty strings, boundary values, wrong data types, unauthorized fields, and conflicting updates. If the API supports formal JSON Patch or Merge Patch, testers should validate the specific patch format and error behavior.
PATCH can be trickier than PUT because partial updates may interact with business rules. Changing a shipping address may be allowed before dispatch but not after shipment. Changing an email may require verification. Changing a payment method may be blocked after order confirmation. Testers should combine method validation with business rules.
DELETE Validation in API Testing
DELETE validation should confirm that the resource is removed, deactivated, or made unavailable according to the contract. A successful DELETE may return 204 No Content, 200 OK, or another documented status. The response body may be empty or may include a message, depending on design.
After deletion, testers should verify the follow-up behavior. Does GET return 404? Does the resource appear as inactive? Is it excluded from normal lists? Can it be restored? Are related resources affected? Does the audit log record the deletion? These questions depend on business rules.
Repeated DELETE behavior should also be tested. If the same DELETE is sent twice, the API may return 404 on the second call, or it may return 204 if deletion is treated idempotently. Both can be valid if documented. Unauthorized delete attempts should be rejected, especially for sensitive resources.
PUT vs PATCH
PUT and PATCH are both update methods, but they have different meanings. PUT is commonly used for full replacement. PATCH is used for partial update. If a user resource has name, email, city, and status, a PUT request usually sends the complete replacement representation. A PATCH request may send only the email field to update just that value.
This distinction matters in testing. If a PUT request omits a field, should the server clear it or reject the request? If a PATCH request omits a field, it should usually remain unchanged. If an API treats both methods exactly the same, the documentation should say so, but that design may confuse clients expecting standard semantics.
Interviewers often ask this difference because it reveals whether the candidate understands REST beyond basic GET and POST. A clear answer is that PUT replaces the resource while PATCH updates part of it.
Idempotency and CRUD Methods
Idempotency means making the same request once or multiple times has the same final effect on server state. GET is safe and idempotent when used correctly because it retrieves data without changing business state. PUT is generally idempotent because replacing a resource with the same representation repeatedly leaves the same final state. DELETE is often idempotent in final effect because the resource remains deleted after repeated requests, though status codes may vary. PATCH can be idempotent or non-idempotent depending on patch semantics. POST is commonly not idempotent because repeating a create request may create multiple resources.
Idempotency matters for retries. Networks fail, clients time out, and gateways retry requests. If a payment POST is retried without protection, it may create duplicate charges. APIs often use idempotency keys for sensitive create operations. Testers should understand which CRUD methods are safe to retry and which require duplicate-prevention logic.
Testing idempotency involves repeating the same request and verifying the final resource state. This is especially important for PUT, DELETE, payment creation, order submission, and APIs that support retry behavior.
URI Design for CRUD
CRUD mapping works best with resource-oriented URIs. Use nouns, not verbs. Use plural names for collections. Use path parameters for individual resource identity. Use query parameters for filtering and pagination. Avoid action names such as /createUser, /updateUser, and /deleteUser.
Good CRUD URI design looks like this:
POST /users
GET /users
GET /users/101
PUT /users/101
PATCH /users/101
DELETE /users/101
Bad design often embeds operations in the URI:
/getUsers
/createUser
/updateUser
/deleteUser
Testing should identify whether the API follows a consistent resource model. If method usage and URI naming are inconsistent, automation becomes harder and clients need extra documentation to understand basic operations.
CRUD and Database Verification
CRUD operations often affect persistent data, so testers sometimes verify database state. After POST, a new record should exist. After PUT or PATCH, the right fields should change. After DELETE, the record may be removed, marked inactive, archived, or hidden from normal reads. Database verification can be useful, but it should be used carefully.
The API contract is the primary behavior visible to clients. Direct database checks can confirm backend state, but they can also make tests tightly coupled to internal implementation. In some systems, the API writes to multiple services, queues, caches, or eventually consistent stores. A direct table check may not represent the complete behavior.
A practical approach is to verify through the API first, then use database checks for critical backend validation where appropriate. For example, create a user with POST, retrieve it with GET, update it with PATCH, retrieve again, delete it, and confirm the documented post-delete behavior. Use database checks when the risk justifies the coupling.
Test Data and Cleanup Strategy for CRUD APIs
CRUD testing depends heavily on reliable test data. A POST test needs data that can be created without colliding with existing records. A GET test needs a known resource. A PUT or PATCH test needs a resource that can be changed safely. A DELETE test needs a resource that can be removed without affecting other tests or real users. Poor test data management is one of the main reasons CRUD automation becomes flaky.
A good strategy is to create data explicitly for the test, capture the generated resource id, use that id for read and update checks, and clean up when the test finishes. If the API supports soft delete, cleanup may mark the resource inactive. If the API supports hard delete, cleanup may remove it. In shared environments, test data should be clearly identifiable, isolated, and safe to remove.
Parallel execution makes isolation even more important. Two tests should not update or delete the same user, product, or order unless that shared behavior is intentional. Unique names, timestamps, generated emails, tenant-specific test accounts, and dedicated test fixtures can prevent accidental collisions. Cleanup should run even when a test fails, but reports should still preserve enough information to debug the failed request.
Common CRUD Mistakes
A common mistake is using GET to modify data. For example, GET /deleteUser/101 is wrong because GET should not perform destructive business operations. This can cause caching problems, crawler risks, and unexpected side effects.
Another mistake is using POST for every operation. Some APIs use POST for read, update, delete, search, and action endpoints because it feels simple to implement. This removes the clarity of HTTP methods and makes client behavior less predictable. POST has legitimate uses, but it should not replace method semantics without reason.
Teams also confuse PUT and PATCH. PUT is commonly full replacement. PATCH is partial update. If this distinction is ignored, clients may accidentally overwrite fields or fail to update only intended values.
Using verbs in URIs is another common issue. /createUser, /updateUser, and /deleteUser duplicate action information that should come from HTTP methods. Resource-oriented naming keeps APIs cleaner.
Best Practices
Use POST for creating resources. Use GET for retrieving resources. Use PUT for full replacement. Use PATCH for partial updates. Use DELETE for resource removal, deactivation, or deletion according to the business contract. Return appropriate HTTP status codes and response headers.
Keep URIs resource-oriented rather than action-oriented. Use /users and /users/101, not /getUsers or /deleteUser. Document request and response schemas, status codes, headers, idempotency behavior, and error responses for each method.
Test positive and negative scenarios for every CRUD operation. Validate authentication, authorization, input validation, response schema, status code, headers, persisted state, and follow-up reads. Include boundary cases and error cases, not only happy paths.
Interview-Ready Explanation
CRUD operations represent the four basic operations performed on resources: Create, Read, Update, and Delete. In REST APIs, these operations are mapped to standard HTTP methods. POST is used to create a new resource, GET retrieves one or more resources, PUT replaces an existing resource, PATCH partially updates an existing resource, and DELETE removes or deactivates a resource.
The URI should represent the resource, while the HTTP method represents the action. For example, POST /users creates a user, GET /users/101 retrieves user 101, PUT /users/101 replaces user 101, PATCH /users/101 updates selected fields, and DELETE /users/101 deletes user 101.
In API testing, CRUD mapping is validated by checking method behavior, status codes, request bodies, response bodies, headers, database or persisted state where appropriate, negative scenarios, authorization, and follow-up reads. Correct CRUD mapping makes REST APIs predictable, consistent, and easier to test and consume.
Key Takeaway
CRUD mapping is the foundation of many REST APIs. Create maps to POST, Read maps to GET, Update maps to PUT or PATCH, and Delete maps to DELETE. This standardized mapping allows the same resource URI to support different operations based on the HTTP method.
For API testers, the practical rule is to validate the complete behavior of each method, not just whether the endpoint returns a success code. Check status codes, headers, request payloads, response payloads, persistence, authorization, negative cases, idempotency, and follow-up state. Strong CRUD testing confirms that an API is both functional and RESTful.