Request & Response Formats
Understanding Data Formats in REST APIs
REST APIs need a common language to exchange data between clients and servers. While REST itself doesn't mandate a specific format, JSON has become the de facto standard due to its simplicity, readability, and universal support across programming languages.
JSON: The King of API Data Formats
JSON (JavaScript Object Notation) is lightweight, human-readable, and easy to parse. It's the standard for modern REST APIs.
JSON Basics:
{
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"age": 30,
"isActive": true,
"roles": ["user", "editor"],
"address": {
"street": "123 Main St",
"city": "New York",
"zipCode": "10001"
},
"metadata": null
}
JSON Data Types:
- String: "text in double quotes"
- Number: 123, 45.67 (no quotes)
- Boolean: true, false (lowercase, no quotes)
- Array: ["item1", "item2"]
- Object: {"key": "value"}
- Null: null (represents absence of value)
Structuring JSON Responses
Consistent response structure makes your API predictable and easy to use.
Single Resource Response:
GET /api/users/123
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": {
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-14T14:20:00Z"
}
}
Collection Response:
GET /api/users?page=1&limit=2
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": [
{
"id": 123,
"name": "John Doe",
"email": "john@example.com"
},
{
"id": 124,
"name": "Jane Smith",
"email": "jane@example.com"
}
],
"meta": {
"current_page": 1,
"per_page": 2,
"total": 150,
"total_pages": 75
},
"links": {
"first": "/api/users?page=1",
"prev": null,
"next": "/api/users?page=2",
"last": "/api/users?page=75"
}
}
Error Response:
POST /api/users
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request data failed validation",
"details": [
{
"field": "email",
"message": "Email is required",
"code": "REQUIRED_FIELD"
},
{
"field": "age",
"message": "Age must be at least 18",
"code": "MIN_VALUE"
}
]
}
}
JSON Naming Conventions
Choose a naming style and stick to it throughout your API.
camelCase (Recommended for JavaScript-heavy APIs):
{
"userId": 123,
"firstName": "John",
"lastName": "Doe",
"emailAddress": "john@example.com",
"isEmailVerified": true,
"createdAt": "2026-01-15T10:30:00Z"
}
snake_case (Common in Python/Ruby APIs):
{
"user_id": 123,
"first_name": "John",
"last_name": "Doe",
"email_address": "john@example.com",
"is_email_verified": true,
"created_at": "2026-01-15T10:30:00Z"
}
PascalCase (Rare in REST APIs):
{
"UserId": 123,
"FirstName": "John",
"LastName": "Doe"
}
Date and Time Formats
Always use ISO 8601 format for dates and times. It's unambiguous and universally supported.
ISO 8601 Examples:
// Date only
"2026-02-14"
// Date and time (UTC - recommended)
"2026-02-14T10:30:00Z"
// Date and time with timezone offset
"2026-02-14T10:30:00-05:00"
// Date and time with milliseconds
"2026-02-14T10:30:00.123Z"
Null vs. Missing Fields
Decide how to handle missing data and be consistent.
Option 1: Include Null Values
{
"id": 123,
"name": "John Doe",
"middleName": null,
"phone": null,
"bio": null
}
Pros:
✅ Explicit about missing data
✅ Client knows field exists
✅ Easier schema validation
Cons:
❌ Larger response size
❌ More verbose
Option 2: Omit Null Values
{
"id": 123,
"name": "John Doe"
}
Pros:
✅ Smaller response size
✅ Cleaner, less cluttered
Cons:
❌ Can't distinguish between null and undefined
❌ Client must handle missing keys
HTTP Headers: The Metadata Layer
Headers provide crucial information about requests and responses without cluttering the body.
Content-Type Header
Tells the server/client what format the data is in.
// Request
POST /api/users
Content-Type: application/json
{"name": "John Doe"}
// Response
HTTP/1.1 200 OK
Content-Type: application/json
{"id": 123, "name": "John Doe"}
Accept Header
Client tells server what formats it can handle.
// Client prefers JSON
GET /api/users
Accept: application/json
// Client can handle multiple formats (preference order)
GET /api/users
Accept: application/json, application/xml;q=0.9, */*;q=0.8
Common Content Types:
| Content-Type | Description | Usage |
|---|---|---|
| application/json | JSON data | 99% of REST APIs |
| application/xml | XML data | Legacy systems |
| application/x-www-form-urlencoded | Form data | HTML forms |
| multipart/form-data | File uploads | Images, documents |
| text/plain | Plain text | Simple responses |
| text/html | HTML document | API documentation |
Content Negotiation
Content negotiation allows the same endpoint to return different formats based on client preference.
Server-Driven Negotiation:
// Client requests JSON
GET /api/users/123
Accept: application/json
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{"id": 123, "name": "John Doe"}
// Client requests XML
GET /api/users/123
Accept: application/xml
Response:
HTTP/1.1 200 OK
Content-Type: application/xml
<user>
<id>123</id>
<name>John Doe</name>
</user>
Handling Unsupported Formats:
GET /api/users/123
Accept: application/pdf
Response:
HTTP/1.1 406 Not Acceptable
Content-Type: application/json
{
"error": {
"code": "UNSUPPORTED_MEDIA_TYPE",
"message": "Server cannot produce response in requested format",
"supported_formats": ["application/json", "application/xml"]
}
}
XML: The Alternative Format
While JSON dominates, some enterprise systems still use XML.
XML Example:
<?xml version="1.0" encoding="UTF-8"?>
<user>
<id>123</id>
<name>John Doe</name>
<email>john@example.com</email>
<roles>
<role>user</role>
<role>editor</role>
</roles>
<address>
<street>123 Main St</street>
<city>New York</city>
</address>
</user>
JSON vs. XML Comparison:
| Aspect | JSON | XML |
|---|---|---|
| Readability | Very readable | Verbose |
| Size | Smaller (30-50% less) | Larger |
| Parsing Speed | Faster | Slower |
| Data Types | Native types | Everything is text |
| Arrays | Native support | Repeated elements |
| Validation | JSON Schema | XSD, DTD |
| Comments | Not supported | Supported |
File Uploads: multipart/form-data
When uploading files, use multipart/form-data instead of JSON.
POST /api/users/123/avatar
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="avatar.jpg"
Content-Type: image/jpeg
[binary file data]
------WebKitFormBoundary
Content-Disposition: form-data; name="description"
New profile picture
------WebKitFormBoundary--
Response:
HTTP/1.1 201 Created
Content-Type: application/json
{
"data": {
"id": 456,
"filename": "avatar.jpg",
"size": 51234,
"url": "https://cdn.example.com/avatars/456.jpg",
"uploaded_at": "2026-02-14T10:30:00Z"
}
}
Compression: Reducing Bandwidth
Enable compression to reduce response sizes by 60-80%.
// Client accepts compressed response
GET /api/users
Accept-Encoding: gzip, deflate, br
// Server sends compressed response
HTTP/1.1 200 OK
Content-Type: application/json
Content-Encoding: gzip
Content-Length: 1234
[compressed data]
Character Encoding: UTF-8 Always
Always use UTF-8 encoding to support international characters.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"name": "José García",
"city": "São Paulo",
"greeting": "你好",
"message": "مرحبا"
}
Best Practices Checklist
- ✅ Use JSON as your primary format
- ✅ Always set Content-Type headers correctly
- ✅ Use ISO 8601 for all dates and times
- ✅ Be consistent with naming (camelCase or snake_case)
- ✅ Wrap responses in "data" object for flexibility
- ✅ Include pagination metadata for collections
- ✅ Provide detailed error messages with codes
- ✅ Support compression (gzip, brotli)
- ✅ Use UTF-8 encoding everywhere
- ✅ Return 406 for unsupported Accept types
Create proper JSON response structures for these scenarios:
- Successful user creation: User ID 789, name "Alice Johnson", email "alice@example.com", created today at 10:30 AM UTC
- Validation error: Email is invalid, password is too short (min 8 characters)
- Collection with pagination: 3 products out of 150 total, page 1 of 50, 3 items per page
Sample Solution for #1:
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/users/789
{
"data": {
"id": 789,
"name": "Alice Johnson",
"email": "alice@example.com",
"created_at": "2026-02-14T10:30:00Z"
}
}
Key Takeaways
- JSON is the standard format for modern REST APIs
- Always use Content-Type and Accept headers correctly
- ISO 8601 format for dates (UTC with Z suffix)
- Be consistent with naming conventions throughout your API
- Wrap responses in "data" object for future flexibility
- Include helpful metadata (pagination, timestamps)
- Support compression to reduce bandwidth
- Use UTF-8 encoding for international support