REST API Request and Response Design
The data your API sends and receives is its handshake with the world. A clean, consistent JSON structure makes your API intuitive, easy to integrate, and straightforward to debug. This topic covers how to design great request and response bodies.
Why JSON?
JSON (JavaScript Object Notation) is the standard data format for REST APIs. It is text-based, human-readable, and supported natively in almost every programming language. While XML was common in older APIs (like SOAP), JSON has become the default for REST.
JSON vs XML – same data, different formats:
JSON: XML:
{ <product>
"id": 42, <id>42</id>
"name": "Laptop", <name>Laptop</name>
"price": 55000 <price>55000</price>
} </product>
JSON is shorter, cleaner, and easier to work with in code.
JSON Data Types
Type │ Example
────────────┼───────────────────────────────────
String │ "name": "Priya Sharma"
Number │ "age": 29
Boolean │ "isActive": true
Null │ "middleName": null
Array │ "tags": ["tech", "finance"]
Object │ "address": { "city": "Mumbai" }
Use the correct data type for each field. Do not send numbers as strings ("price": "55000") — it forces clients to convert them unnecessarily.
Naming Conventions in JSON
Use camelCase for all JSON field names. This matches the convention in JavaScript and most modern APIs.
✅ camelCase (recommended):
{
"firstName": "Rahul",
"lastName": "Verma",
"phoneNumber": "+91-9876543210",
"createdAt": "2024-06-01T10:00:00Z"
}
❌ Avoid snake_case:
{
"first_name": "Rahul",
"last_name": "Verma"
}
❌ Avoid PascalCase:
{
"FirstName": "Rahul",
"LastName": "Verma"
}
Pick one convention and apply it everywhere. Mixing naming styles is one of the fastest ways to confuse API consumers.
Designing a Good Response Structure
A single resource response should return the resource directly at the top level.
GET /products/42
Response:
{
"id": 42,
"name": "Wireless Keyboard",
"price": 1499,
"currency": "INR",
"inStock": true,
"createdAt": "2024-01-15T08:30:00Z"
}
A collection response should return an array along with metadata like total count and pagination info.
GET /products
Response:
{
"data": [
{ "id": 1, "name": "Mouse", "price": 599 },
{ "id": 2, "name": "Keyboard", "price": 1499 },
{ "id": 3, "name": "Monitor", "price": 12000 }
],
"total": 143,
"page": 1,
"pageSize": 20
}
Wrapping vs Not Wrapping Single Resources
Option 1 – Unwrapped (simpler, widely preferred):
{
"id": 42,
"name": "Laptop"
}
Option 2 – Wrapped in a "data" key:
{
"data": {
"id": 42,
"name": "Laptop"
}
}
Use Option 1 for simplicity.
Use Option 2 only if you also include metadata (like "meta" or "links") in the response.
Designing a Good Request Body
When a client sends data to create or update a resource, the request body should include only the fields that matter — not computed fields like id, createdAt, or updatedAt (the server generates those).
POST /products
Client sends:
{
"name": "Bluetooth Speaker",
"price": 2499,
"stock": 200,
"categoryId": 3
}
Server responds with the created resource:
{
"id": 88, ← generated by server
"name": "Bluetooth Speaker",
"price": 2499,
"stock": 200,
"categoryId": 3,
"createdAt": "2024-06-01T10:00:00Z" ← generated by server
}
Dates and Times
Always use ISO 8601 format for dates and timestamps. Never send dates as unformatted strings like "1st June 2024" or as Unix timestamps unless there is a specific reason.
✅ ISO 8601 (correct): "createdAt": "2024-06-01T10:30:00Z" ← UTC timezone "birthDate": "1995-04-22" ← date only ❌ Avoid these formats: "createdAt": "01/06/2024 10:30" ← ambiguous "createdAt": 1717230600 ← Unix timestamp (hard to read) "createdAt": "June 1, 2024" ← human text, not machine-friendly
Null vs Absent Fields
null means the field exists but has no value:
{
"middleName": null ← user has no middle name
}
Absent means the field was not included at all:
{
"firstName": "Rahul" ← middleName is not in the response
}
Best practice:
Include null for optional fields that exist in the schema.
Omit fields that are completely irrelevant for the current context.
Avoid These Common Response Mistakes
┌──────────────────────────────┬────────────────────────────────────────┐
│ Mistake │ Why it's a problem │
├──────────────────────────────┼────────────────────────────────────────┤
│ Returning HTML in an error │ Clients expect JSON — HTML breaks │
│ Wrapping every response │ "result": {"data": {"user": {...}}} │
│ in multiple layers │ is hard to navigate │
│ Changing field names │ clientName vs client_name — pick one │
│ inconsistently │ │
│ Including passwords or │ Never return sensitive data in any │
│ secrets in responses │ response │
│ Sending numbers as strings │ "price": "1499" forces type casting │
└──────────────────────────────┴────────────────────────────────────────┘
Key Points
- JSON is the standard format for REST API data
- Use camelCase for all field names
- Use correct data types — numbers as numbers, booleans as booleans
- Use ISO 8601 for all dates and timestamps
- Do not ask the client to send server-generated fields like id or createdAt
- Return null for optional fields with no value rather than omitting them
