0% found this document useful (0 votes)
2 views59 pages

REST API Complete Guide

The document is a comprehensive guide on REST API development, covering essential topics such as HTTP methods, request and response anatomy, authentication, and security practices. It provides practical examples in C++ and Java, along with corporate best practices for API design and testing. The guide is designed for both beginners and corporate professionals, emphasizing real-world applications and project walkthroughs.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views59 pages

REST API Complete Guide

The document is a comprehensive guide on REST API development, covering essential topics such as HTTP methods, request and response anatomy, authentication, and security practices. It provides practical examples in C++ and Java, along with corporate best practices for API design and testing. The guide is designed for both beginners and corporate professionals, emphasizing real-world applications and project walkthroughs.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

REST API REST API Complete Guide

REST API
Complete Developer Guide
From Zero to Corporate-Grade API Development in C++ & Java

Topics Covered

• What is REST & Why it matters

• All HTTP Methods in depth (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS)

• Request & Response anatomy

• Status codes, Headers, Authentication

• JSON / XML payloads, Pagination, Filtering

• REST API in C++ (libcurl, nlohmann/json, [Link])

• REST API in Java (HttpClient, Spring Boot, OkHttp, Retrofit)

• Corporate best-practices, Versioning, Rate-limiting, Logging

• Security (OAuth2, JWT, API Keys, HTTPS)

• Testing, Mocking, CI/CD integration

• Real-world project walkthroughs

Designed for beginners → corporate professionals

Page 1
REST API REST API Complete Guide

Table of Contents
1. What is an API? What is REST?
2. REST Constraints & Architectural Principles
3. HTTP Protocol Deep Dive
4. HTTP Methods — All 7 in Depth
■ GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
5. Request Anatomy — Headers, Body, Query Params, Path Params
6. Response Anatomy — Status Codes, Headers, Body
7. HTTP Status Codes — Complete Reference
8. Authentication & Authorization
■ API Keys, Basic Auth, Bearer Tokens, OAuth2, JWT
9. Data Formats — JSON, XML, Form Data
10. Advanced Concepts — Pagination, Filtering, Sorting
11. REST API Versioning Strategies
12. Rate Limiting & Throttling
13. REST API Security Best Practices
14. REST API in C++
■ libcurl, nlohmann/json, [Link], full project example
15. REST API in Java
■ HttpClient, OkHttp, Retrofit, Spring Boot REST Client
16. Corporate Best Practices
17. Testing REST APIs
18. Error Handling Patterns
19. Real-World Project — E-Commerce API
20. Quick Reference Card

Page 2
REST API REST API Complete Guide

Chapter 1 — What is an API? What is REST?

1.1 What is an API?


An API (Application Programming Interface) is a set of rules and protocols that allows different software
applications to communicate with each other. Think of it as a waiter in a restaurant — you (the client) tell the
waiter (API) what you want, the waiter goes to the kitchen (the server/database), and brings back what you
ordered (the response). You never go to the kitchen directly; the waiter is the interface.

In the corporate world, APIs power everything: your mobile banking app talks to the bank's server via APIs,
Amazon's checkout uses dozens of internal APIs, Uber's driver-tracking uses real-time APIs. APIs are the
backbone of modern software architecture.

Real-world API analogy:


• You open Google Maps on your phone
• Your phone (client) sends a request to Google's server via an API
• Google's server processes the request, queries its databases
• The server returns directions as a structured JSON response
• Your app displays the result — you never touched Google's database directly

1.2 Types of APIs


Type Description Use Case

REST Representational State Transfer — uses HTTP Web/mobile apps, microservices

SOAP XML-based messaging protocol Legacy enterprise, banking

GraphQL Query language for APIs (flexible) Complex data relationships

gRPC High-performance, uses Protocol Buffers Internal microservices, IoT

WebSocket Persistent bi-directional connection Real-time chat, live updates

1.3 What is REST?


REST (Representational State Transfer) is an architectural style for designing networked applications,
introduced by Roy Fielding in his 2000 doctoral dissertation. REST is not a protocol or a standard — it is a set
of architectural constraints. An API that follows REST constraints is called a RESTful API.

Page 3
REST API REST API Complete Guide

Why REST dominates in 2024:


• Simplicity — uses standard HTTP that every developer already knows
• Stateless — each request carries all necessary information; servers don't store session state
• Scalable — statelessness makes horizontal scaling trivial
• Language-agnostic — any language with an HTTP library can consume a REST API
• Cacheable — HTTP caching headers work out of the box
• Tooling — Postman, Swagger, curl, browser DevTools all work natively
• Industry standard — 83% of public APIs are RESTful (2023 RapidAPI survey)

Page 4
REST API REST API Complete Guide

Chapter 2 — REST Constraints &


Architectural Principles
REST defines 6 guiding constraints. An API must satisfy these to be called truly RESTful. Understanding
them is crucial in corporate environments where architecture reviews check compliance.

1. Client-Server Separation
The UI/client and data-storage/server are completely separate. This means your React frontend and your
Java Spring backend are independent — they evolve independently. The client only knows the API contract
(endpoints + data shapes), not the implementation.

2. Stateless
Each HTTP request from client to server must contain ALL information needed to understand the request.
The server stores NO session state between requests. Authentication tokens, filters, and parameters must be
resent every time. This enables horizontal scaling — any server can handle any request.

3. Cacheable
Responses must define themselves as cacheable or non-cacheable using HTTP headers like Cache-Control,
ETag, Last-Modified. Caching eliminates redundant calls, reduces server load, and speeds up client apps
dramatically. GET responses are typically cacheable; POST/DELETE are not.

4. Uniform Interface
The most critical constraint. REST defines 4 sub-constraints: resource identification via URIs; manipulation of
resources through representations; self-descriptive messages (Content-Type header tells the receiver how to
parse the body); HATEOAS (responses include links to related actions).

5. Layered System
A client cannot tell whether it is connected directly to the end server or to an intermediary (load balancer,
CDN, API gateway, caching proxy). Each layer only sees the adjacent layer. In AWS, an API Gateway sits in
front of Lambda functions — the client talks to the Gateway.

6. Code on Demand (Optional)


Servers can extend client functionality by sending executable code (e.g., JavaScript). This is optional and
rarely used in pure REST APIs. Web browsers downloading JavaScript from servers is the classic example.

Page 5
REST API REST API Complete Guide

HATEOAS Explained (Hypermedia As The Engine Of


Application State)
HATEOAS means that a REST response should include hyperlinks to related actions. A client doesn't need
to hardcode endpoints — it discovers them from the response. Example: after fetching an order, the
response includes links to cancel, pay, or track it.

// HATEOAS example response for GET /orders/1001


{
"orderId": 1001,
"status": "PENDING",
"total": 299.99,
"_links": {
"self": { "href": "/orders/1001" },
"pay": { "href": "/orders/1001/payment", "method": "POST" },
"cancel": { "href": "/orders/1001/cancel", "method": "DELETE" },
"track": { "href": "/shipments?order=1001" }
}
}

Page 6
REST API REST API Complete Guide

Chapter 3 — HTTP Protocol Deep Dive


REST APIs are built on top of HTTP (HyperText Transfer Protocol). To master REST, you must deeply
understand HTTP.

3.1 How HTTP Works — The Request-Response Cycle


• Client (browser/app) opens a TCP connection to the server (port 80 for HTTP, 443 for HTTPS)
• Client sends an HTTP Request message (method + URI + headers + optional body)
• Server processes the request (runs business logic, queries database)
• Server sends an HTTP Response message (status code + headers + body)
• Connection is closed (or kept alive for multiple requests via keep-alive)

3.2 HTTP Versions


Version Year Key Features Used In

HTTP/1.0 1996 One request per connection Legacy systems

HTTP/1.1 1997 Keep-alive, chunked transfer, pipelining Most REST APIs today

HTTP/2 2015 Multiplexing, header compression, server push Modern APIs, gRPC

HTTP/3 2022 UDP-based (QUIC), 0-RTT, better mobile perf Cutting-edge services

3.3 URL / URI Anatomy


Full URL example:
[Link]

■■ Scheme ■■ ■■■■ Host ■■■■■■■■■■■■■ ■■Port■■


https [Link] 443

■■■■ Path ■■■■■■■■■■■■■■■ ■■■■■■ Query String ■■■■■ ■■ Fragment ■■


/v2/users/42/orders status=pending&limit;=10 section

Breakdown:
Scheme → protocol (https)
Host → domain name
Port → 443 for HTTPS (default, often omitted)
Path → /v2 = version; /users = resource; /42 = path param; /orders = sub-reso
urce
Query → key=value pairs for filtering/pagination

Page 7
REST API REST API Complete Guide

Fragment → client-side anchor, NOT sent to server

3.4 REST Resource Naming — Corporate Best Practices


Resource names in URIs represent things (nouns), not actions (verbs). This is the single most common
mistake junior developers make.

Anti-Pattern (BAD ✗) RESTful (GOOD ✓) Why

/getUsers /users Verb in URL — HTTP method IS


the verb

/createUser /users (POST) Action implied by POST method

/deleteUser?id=5 /users/5 (DELETE) Resource ID in path, method =


action

/getUserOrders/5 /users/5/orders Nested resource, clean hierarchy

/Users /users Lowercase always

/user_orders /user-orders or /users/{id}/orders Use hyphens if needed, prefer


hierarchy

/getProductByName /products?name=iPhone Filtering via query params

Page 8
REST API REST API Complete Guide

Chapter 4 — HTTP Methods — All 7 in Depth


HTTP methods (also called verbs) tell the server what action to perform. Each method has specific
semantics, idempotency rules, and safety properties that you must follow in corporate APIs.

Method Idempotent? Safe? Has Request Body? Has Response Body?

GET Yes ✓ Yes ✓ No (optional) Yes

POST No ✗ No ✗ Yes Yes

PUT Yes ✓ No ✗ Yes Yes (optional)

PATCH No* ✗ No ✗ Yes Yes (optional)

DELETE Yes ✓ No ✗ No (optional) Yes (optional)

HEAD Yes ✓ Yes ✓ No No (headers only)

OPTIONS Yes ✓ Yes ✓ No Yes (Allow header)


* Idempotent: calling the same request N times produces the same result as calling it once. Safe: does not modify
server state.

4.1 GET — Retrieve Resources


GET is used to retrieve/read data. It must NEVER modify server state. GET requests are safe, idempotent,
and cacheable. No request body is used.

Use GET when:


• Fetching a list of resources
• Fetching a single resource by ID
• Searching/filtering resources
• Downloading files/images
• Loading data for display

GET Examples:
GET /users → fetch all users
GET /users/42 → fetch user with ID 42
GET /users/42/orders → fetch orders for user 42
GET /products?category=laptop&limit;=20&page;=2 → filtered + paginated
GET /products/search?q=macbook → search
GET /files/[Link] → download file

Page 9
REST API REST API Complete Guide

GET Request Structure:


GET /users/42 HTTP/1.1
Host: [Link]
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Accept: application/json
Accept-Language: en-US
Cache-Control: no-cache

[ NO REQUEST BODY ]

GET Success Response:


HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=300
ETag: "abc123"
X-Request-Id: req_9f3k2m

{
"id": 42,
"name": "Rahul Sharma",
"email": "rahul@[Link]",
"role": "engineer",
"createdAt": "2024-01-15T10:30:00Z"
}

GET Not Found Response:


HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": "NOT_FOUND",
"message": "User with id 42 does not exist",
"timestamp": "2024-11-20T08:15:00Z"
}

Page 10
REST API REST API Complete Guide

4.2 POST — Create Resources


POST is used to create a new resource on the server. It is NOT idempotent — calling it twice creates two
resources. POST can also be used for complex queries that don't fit GET (e.g., sending a large filter
payload).

Use POST when:


• Creating a new user, order, product
• Submitting a form
• Uploading a file
• Triggering an action (send email, process payment)
• Complex searches

POST Request Structure:


POST /users HTTP/1.1
Host: [Link]
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Content-Type: application/json
Accept: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

{
"name": "Priya Patel",
"email": "priya@[Link]",
"password": "SecurePass@123",
"role": "engineer",
"department": "backend"
}

POST Success Response (201 Created):


HTTP/1.1 201 Created
Content-Type: application/json
Location: /users/43

{
"id": 43,
"name": "Priya Patel",
"email": "priya@[Link]",
"role": "engineer",
"createdAt": "2024-11-20T09:00:00Z"

Page 11
REST API REST API Complete Guide

}
Corporate tip: Always return the Location header pointing to the newly created resource. Use Idempotency-Key to
prevent duplicate submissions (e.g., network retry).

POST Validation Error Response:


HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
"error": "VALIDATION_ERROR",
"message": "Request body has validation errors",
"details": [
{ "field": "email", "message": "Invalid email format" },
{ "field": "password", "message": "Must be at least 8 characters" }
]
}

Page 12
REST API REST API Complete Guide

4.3 PUT — Replace / Full Update


PUT is used to completely replace a resource. The client sends the entire updated resource — fields not
included will be deleted/set to null. PUT is idempotent: calling it 10 times with the same body produces the
same result as calling it once.

PUT vs PATCH comparison:


Aspect PUT PATCH

Updates Full resource replacement Partial update (only changed fields)

Idempotent Yes Depends on implementation

Body Complete resource required Only changed fields

Use when Replacing entire resource Updating one or two fields

PUT Request — Replace full user:


PUT /users/42 HTTP/1.1
Host: [Link]
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Content-Type: application/json

{
"name": "Rahul Kumar",
"email": "[Link]@[Link]",
"role": "senior-engineer",
"department": "platform",
"active": true
}

// ALL fields must be provided; missing fields = null/default

PUT Success Response:


HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 42,
"name": "Rahul Kumar",
"email": "[Link]@[Link]",
"role": "senior-engineer",
"updatedAt": "2024-11-20T10:00:00Z"
}

Page 13
REST API REST API Complete Guide

4.4 PATCH — Partial Update


PATCH is used to partially update a resource. Only the fields included in the request body are changed; all
other fields remain unchanged. This is the preferred method for most update operations in modern APIs.

PATCH Request — Update only email and role:


PATCH /users/42 HTTP/1.1
Host: [Link]
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...
Content-Type: application/json

{
"email": "[Link]@[Link]",
"role": "staff-engineer"
}

// Only email and role change; name, department etc. stay the same

Page 14
REST API REST API Complete Guide

4.5 DELETE — Remove Resources


DELETE is used to remove a resource. It is idempotent — deleting an already-deleted resource should
return 404 (not an error in the client's logic). Use soft-delete in production systems (mark as deleted, don't
actually remove from DB).

DELETE Request:
DELETE /users/42 HTTP/1.1
Host: [Link]
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9...

[ NO REQUEST BODY typically ]

Success Responses:
204 No Content → deleted successfully, no body
200 OK → deleted successfully with confirmation body
202 Accepted → deletion queued (async operation)

HTTP/1.1 204 No Content

// OR with body:
HTTP/1.1 200 OK
{ "message": "User 42 deleted successfully", "deletedAt": "2024-11-20T11:00:00Z" }

4.6 HEAD — Retrieve Headers Only


HEAD is identical to GET but the server returns ONLY headers — no response body. Used to check if a
resource exists, get content size before downloading, validate cache freshness.

HEAD /files/[Link] HTTP/1.1


Host: [Link]

Response (headers only, no body):


HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Length: 5242880
Last-Modified: Fri, 15 Nov 2024 10:00:00 GMT
ETag: "d8e8fca2dc0f896fd7cb4cb0031ba249"

// Client now knows: file exists, is 5MB, and when it was last modified
// Without downloading the entire file

4.7 OPTIONS — Discover Allowed Methods / CORS Preflight

Page 15
REST API REST API Complete Guide

OPTIONS returns the HTTP methods supported by a resource. Most importantly, browsers automatically
send an OPTIONS preflight request before cross-origin requests (CORS). Understanding OPTIONS is critical
for web API development.

OPTIONS /users/42 HTTP/1.1


Host: [Link]
Origin: [Link]
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: Authorization, Content-Type

Server Response:
HTTP/1.1 204 No Content
Allow: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
Access-Control-Allow-Origin: [Link]
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Headers: Authorization, Content-Type
Access-Control-Max-Age: 86400

Page 16
REST API REST API Complete Guide

Chapter 5 — Request Anatomy


Every HTTP request has the same structure. Understanding each component is essential for debugging APIs
in corporate environments.

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
REQUEST LINE
POST /v2/orders?dryRun=true HTTP/1.1
↑ ↑ ↑
Method URI+QueryString HTTP version
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
HEADERS
Host: [Link]
Authorization: Bearer <token>
Content-Type: application/json
Accept: application/json
Accept-Encoding: gzip, deflate
X-Request-Id: req_abc123xyz
X-Correlation-Id: corr_456def
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
BLANK LINE (separator)

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
BODY (only for POST/PUT/PATCH)
{ "productId": 55, "qty": 2, "address": "Mumbai" }
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

5.1 Request Headers — Complete Reference


Header Purpose Example Value

Host Target server hostname (required) [Link]

Authorization Authentication credentials Bearer eyJhbG...

Content-Type Format of the request body application/json

Accept Expected response format application/json

Accept-Encoding Accepted compression methods gzip, deflate, br

Accept-Language Preferred response language en-US, hi;q=0.8

Content-Length Size of request body in bytes 352

Page 17
REST API REST API Complete Guide

Header Purpose Example Value

Cookie Session cookies session=abc123

User-Agent Client application identifier MyApp/2.1 (Android)

X-Request-Id Unique ID per request (tracing) req_f3k2m9

X-Correlation-Id Links requests across microservices corr_tx_789

Idempotency-Key Prevents duplicate POST operations 550e8400-e29b...

Cache-Control Caching directives no-cache, no-store

If-None-Match Conditional GET using ETag "abc123"

If-Modified-Since Conditional GET by date Fri, 15 Nov 2024

5.2 Path Parameters vs Query Parameters vs Request Body


Type Location When to Use Example

Path Param In URL path Identifying a specific resource /users/{42}

Query Param After ? in URL Filtering, sorting, pagination ?status=active&page;=2

Request Body HTTP message Creating or updating data {"name":"Rahul"}


body

Header HTTP headers Auth, metadata, cross-cutting Authorization: Bearer ...

Page 18
REST API REST API Complete Guide

Chapter 6 — Response Anatomy


■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
STATUS LINE
HTTP/1.1 200 OK
↑ ↑ ↑
Version Code Reason phrase
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
RESPONSE HEADERS
Content-Type: application/json; charset=utf-8
Content-Length: 234
Cache-Control: public, max-age=300
ETag: "d8e8fca2dc0f896fd7cb4cb0031ba249"
X-Request-Id: req_abc123xyz
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1700000000
Strict-Transport-Security: max-age=31536000
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
BLANK LINE

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
RESPONSE BODY
{ "id": 42, "name": "Rahul", "email": "rahul@[Link]" }
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

6.1 Important Response Headers


Header Purpose Example

Content-Type Format of response body application/json; charset=utf-8

Content-Length Body size in bytes 1024

Location URL of newly created resource /users/43

Cache-Control How long to cache response max-age=3600

ETag Resource version fingerprint "abc123"

Last-Modified When resource was last changed Tue, 19 Nov 2024 10:00:00
GMT

X-RateLimit-Limit Total requests allowed per window 1000

Page 19
REST API REST API Complete Guide

Header Purpose Example

X-RateLimit-Remaining Requests left in current window 450

X-RateLimit-Reset Unix timestamp of window reset 1700000000

Retry-After Seconds to wait before retrying 60

X-Request-Id Server-assigned request trace ID req_9f3k2m

CORS headers Cross-Origin Resource Sharing control Access-Control-Allow-Origin: *

WWW-Authenticate Auth challenge on 401 Bearer realm="api"

Page 20
REST API REST API Complete Guide

Chapter 7 — HTTP Status Codes — Complete


Reference
Status codes are 3-digit numbers indicating the outcome of the HTTP request. Every corporate API must use
the correct status codes — wrong codes cause bugs in clients, monitoring failures, and incorrect retry logic.

1xx — Informational

Code Name When to Use

100 Continue Server received headers, client should proceed with body

101 Switching Protocols Server upgrades to WebSocket/HTTP2

2xx — Success

Code Name When to Use

200 OK Standard success — GET, PUT, PATCH responses

201 Created POST that created a resource; include Location header

202 Accepted Request accepted but processing async (job queued)

204 No Content Success with no body — DELETE, PATCH with no return

206 Partial Content Range request — streaming / download resume

3xx — Redirection

Code Name When to Use

301 Moved Permanently Resource URL changed forever; update your client

302 Found (Temporary) Temporary redirect; use Location header URL

304 Not Modified Cached response is still valid; no body sent

307 Temporary Redirect Like 302 but must keep HTTP method

308 Permanent Redirect Like 301 but must keep HTTP method

4xx — Client Errors


Code Name When to Use

400 Bad Request Malformed request syntax, invalid query params

Page 21
REST API REST API Complete Guide

Code Name When to Use

401 Unauthorized Missing or invalid authentication — must login

403 Forbidden Authenticated but lacks permission — do NOT expose why

404 Not Found Resource doesn't exist at this URI

405 Method Not Allowed HTTP method not supported for this endpoint

408 Request Timeout Client took too long to send request

409 Conflict Request conflicts with current state (duplicate email)

410 Gone Resource permanently deleted (stronger than 404)

415 Unsupported Media Content-Type not supported by server

422 Unprocessable Semantically invalid data (validation errors)

429 Too Many Requests Rate limit exceeded; check Retry-After header

5xx — Server Errors


Code Name When to Use

500 Internal Server Error Unhandled server exception — log and alert

501 Not Implemented Method exists but not implemented yet

502 Bad Gateway Upstream server returned invalid response

503 Service Unavailable Server down for maintenance or overloaded

504 Gateway Timeout Upstream server did not respond in time

Page 22
REST API REST API Complete Guide

Chapter 8 — Authentication & Authorization


Authentication = WHO are you? Authorization = WHAT are you allowed to do? REST APIs are stateless, so
credentials must be sent with every request. Here are all the major methods used in corporate APIs.

8.1 API Keys


Simple, static tokens issued to a client app. Best for server-to-server calls, webhooks, and internal services.
Never expose in browser-side code.

// API Key in Authorization header (preferred):


GET /data HTTP/1.1
Authorization: Api-Key sk_live_abc123xyz456def
// API Key in query string (avoid — logged in server logs):
GET /data?api_key=sk_live_abc123xyz456 HTTP/1.1

// API Key in custom header:


X-API-Key: sk_live_abc123xyz456def

8.2 Basic Authentication


Username and password encoded in Base64 and sent in Authorization header. ONLY use over HTTPS.
Rarely used in modern APIs — only for legacy or simple internal APIs.

// username:password → base64 encode


// admin:secret123 → YWRtaW46c2VjcmV0MTIz
GET /resource HTTP/1.1
Authorization: Basic YWRtaW46c2VjcmV0MTIz

8.3 Bearer Token / JWT Authentication


The most common pattern in modern APIs. The client logs in (POST /auth/login), receives a token, and
sends it in the Authorization header on all subsequent requests. JWT (JSON Web Token) is the most widely
used token format.

// Step 1: Login
POST /auth/login HTTP/1.1
Content-Type: application/json
{
"email": "user@[Link]",
"password": "mypassword"

Page 23
REST API REST API Complete Guide

// Step 2: Server returns token


HTTP/1.1 200 OK
{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "rt_eyJhbGciOiJSUzI1NiJ9...",
"expiresIn": 3600,
"tokenType": "Bearer"
}

// Step 3: Use token in requests


GET /users/me HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

JWT Structure:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9 ← HEADER (base64)
.eyJzdWIiOiI0MiIsInJvbGUiOiJhZG1pbiJ9 ← PAYLOAD (base64)
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ← SIGNATURE

Decoded Header: { alg: RS256, typ: JWT }


Decoded Payload: { sub: 42, role: admin, iat: 1700000000, exp: 1700003600 }

// Server validates signature with its private/public key


// No database lookup needed — token is self-contained!

8.4 OAuth 2.0 — Industry Standard for Delegated Access


OAuth 2.0 is used when your app needs to access resources on behalf of a user without knowing their
password. Used by Google, GitHub, Salesforce, and virtually every enterprise SSO system.

OAuth 2.0 Authorization Code Flow (most secure, used in web apps):

1. User clicks 'Login with Google'


2. Browser redirects to Google:
GET [Link]
?client_id=YOUR_APP_ID
&redirect;_uri=[Link]
&response;_type=code
&scope;=email+profile
&state;=random_csrf_token

3. User logs in at Google, grants permission


4. Google redirects back: /callback?code=AUTH_CODE&state;=...

5. Your server exchanges code for token:

Page 24
REST API REST API Complete Guide

POST [Link]
{ "code": AUTH_CODE, "client_id": ..., "client_secret": ...,
"redirect_uri": ..., "grant_type": "authorization_code" }

6. Google returns: { access_token, refresh_token, expires_in }

7. Use access_token to call Google APIs:


GET [Link]
Authorization: Bearer ACCESS_TOKEN

Page 25
REST API REST API Complete Guide

Chapter 9 — Data Formats — JSON, XML,


Form Data

9.1 JSON — JavaScript Object Notation (Dominant Format)


// JSON Data Types
{
"string": "Hello World",
"number": 42,
"float": 3.14,
"boolean": true,
"null": null,
"array": [1, 2, 3, "four"],
"nested": { "key": "value" },
"isoDate": "2024-11-20T10:30:00Z"
}

Corporate JSON API Response Standard:


// Single resource
{
"data": { "id": 42, "name": "Rahul", "email": "rahul@[Link]" },
"meta": { "requestId": "req_abc", "timestamp": "2024-11-20T10:00:00Z" }
}
// Collection / list
{
"data": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
],
"pagination": {
"page": 2, "limit": 20, "total": 150, "totalPages": 8,
"next": "/users?page=3", "prev": "/users?page=1"
},
"meta": { "requestId": "req_xyz", "timestamp": "..." }
}

// Error response
{
"error": { "code": "VALIDATION_ERROR", "message": "...",

Page 26
REST API REST API Complete Guide

"details": [...], "requestId": "req_abc" }


}

9.2 XML (Legacy Enterprise / SOAP)


POST /users HTTP/1.1
Content-Type: application/xml
Accept: application/xml

<?xml version="1.0" encoding="UTF-8"?>


<user>
<name>Rahul Sharma</name>
<email>rahul@[Link]</email>
<role>engineer</role>
<active>true</active>
</user>

9.3 Form Data (HTML Forms)


// application/x-www-form-urlencoded (simple key=value pairs)
POST /login HTTP/1.1
Content-Type: application/x-www-form-urlencoded

username=rahul&password;=Secret123&remember;=true

// multipart/form-data (file uploads)


POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----Boundary123

------Boundary123
Content-Disposition: form-data; name="title"

My Document
------Boundary123
Content-Disposition: form-data; name="file"; filename="[Link]"
Content-Type: application/pdf

[binary PDF data]


------Boundary123--

Page 27
REST API REST API Complete Guide

Chapter 10 — Pagination, Filtering, Sorting


Never return all records in one call. Corporate APIs always implement pagination to protect servers and give
clients control over data volume.

10.1 Pagination Strategies


Strategy Params Pros Cons

Page-based ?page=2&limit;=20 Simple, user-friendly Inconsistent with inserts

Offset-based ?offset=40&limit;=20 SQL native, precise Slow on large offsets

Cursor-based ?after=cursor_xyz Consistent, fast, infinite Less intuitive URL

Keyset ?after_id=1000 Very fast at scale Only for sorted data

// Page-based pagination
GET /products?page=3&limit;=20

Response:
{
"data": [...],
"pagination": {
"page": 3, "limit": 20, "total": 500, "totalPages": 25,
"hasNext": true, "hasPrev": true,
"next": "/products?page=4&limit;=20",
"prev": "/products?page=2&limit;=20"
}
}

// Cursor-based pagination (Twitter/Facebook style)


GET /posts?limit=10&after;=eyJpZCI6MTAwfQ

Response:
{
"data": [...],
"cursor": {
"next": "eyJpZCI6MTEwfQ",
"hasMore": true
}
}

10.2 Filtering, Sorting, Field Selection

Page 28
REST API REST API Complete Guide

// Filtering
GET /users?role=engineer&department;=backend&active;=true
GET /orders?status=pending&createdAfter;=2024-01-01&minTotal;=100

// Sorting
GET /products?sort=price■=asc
GET /products?sort=-price,+name // - for desc, + for asc

// Field selection (sparse fieldsets)


GET /users?fields=id,name,email // only return these fields

// Range queries
GET /products?price[gte]=100&price;[lte]=500

// Search
GET /products?search=wireless+headphones

// Combined (real-world example)


GET /orders
?status=completed
&customerId;=42
&createdAfter;=2024-01-01
&sort;=-createdAt
&page;=1&limit;=25
&fields;=id,total,status,createdAt

Page 29
REST API REST API Complete Guide

Chapter 11 — REST API Versioning Strategies


Versioning allows you to evolve APIs without breaking existing clients. This is critical in corporate
environments where multiple teams and clients depend on your API.

Strategy Example Pros Cons

URI Versioning /v1/users, /v2/users Visible, cacheable, easy to test URL change, not
REST-pure

Header API-Version: 2 Clean URLs Not visible, harder to


Versioning test

Query Param /users?version=2 Easy to add Pollutes query string

Accept Header Accept: application/[Link] REST-correct Complex, poor


pany.v2+json tooling support

URI versioning is the industry standard (used by Stripe, Twilio, GitHub).

// Version 1 — original
GET /v1/users/42
Response: { id: 42, name: 'Rahul Sharma' }

// Version 2 — breaking change (name split into firstName/lastName)


GET /v2/users/42
Response: { id: 42, firstName: 'Rahul', lastName: 'Sharma', displayName: 'Rahul Sharma'
}

// Both versions run simultaneously — clients migrate at their own pace


// Deprecate v1 after 12 months with Deprecation header:
Deprecation: Tue, 01 Jan 2026 00:00:00 GMT
Sunset: Tue, 01 Jul 2026 00:00:00 GMT
Link: /v2/users/42; rel='successor-version'

Page 30
REST API REST API Complete Guide

Chapter 12 — Rate Limiting & Throttling


Rate limiting protects your API from abuse, ensures fair use, and prevents server overload. Every production
API must implement rate limiting.

// Rate limit headers (send on every response):


X-RateLimit-Limit: 1000 // max requests per window
X-RateLimit-Remaining: 450 // requests left
X-RateLimit-Reset: 1700003600 // unix timestamp when window resets
X-RateLimit-Window: 3600 // window size in seconds

// When limit exceeded:


HTTP/1.1 429 Too Many Requests
Retry-After: 120
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0

{
"error": "RATE_LIMIT_EXCEEDED",
"message": "You have exceeded 1000 requests per hour",
"retryAfter": 120
}

Rate Limiting Strategies:

Algorithm Description Use Case

Fixed Window N requests per window (1000/hour) Simple, most common

Sliding Window Rolling N requests over last N seconds More accurate, no burst at
window edge

Token Bucket Tokens refill at rate R, burst allowed Allows short bursts, AWS uses
this

Leaky Bucket Requests processed at fixed rate, excess queued Smooth output rate

Page 31
REST API REST API Complete Guide

Chapter 13 — REST API Security Best


Practices
✦ Always use HTTPS
Never serve REST APIs over plain HTTP. Use TLS 1.2+. HTTP data is readable by anyone on the network.
Set HSTS header: Strict-Transport-Security: max-age=31536000; includeSubDomains

✦ Validate ALL input


Validate type, length, format, range of every input field. Never trust client data. Reject unexpected fields. Use
JSON Schema validation. Prevent SQL injection, XSS, XXE.

✦ Use proper auth on every endpoint


Every endpoint (except public ones) must verify the token. Check expiry, signature, and permissions. JWT:
verify signature with server's public key. Never decode without verifying.

✦ Implement authorization checks


Authentication = identity. Authorization = permission. Check that user 42 can only access their own data. Use
RBAC (Role-Based Access Control) or ABAC. Never rely on client-provided user IDs in body.

✦ Never expose sensitive data


Strip passwords, secrets, internal IDs from responses. Use field allowlisting, not denylisting. Mask credit card
numbers: show only last 4 digits.

✦ Use CORS correctly


Only allow known origins: Access-Control-Allow-Origin: [Link] Never use * in production for
authenticated APIs.

✦ Implement request signing (HMAC)


For server-to-server: sign request body with HMAC-SHA256 using shared secret. Prevents request
tampering and replay attacks. AWS Signature v4 is an example.

✦ Secure error messages


Never reveal stack traces, SQL errors, or internal paths in production error responses. Log details internally;
return generic error codes to clients.

✦ Token rotation & refresh

Page 32
REST API REST API Complete Guide

Short-lived access tokens (15 min - 1 hour) + long-lived refresh tokens. Invalidate refresh tokens on logout.
Rotate refresh tokens on use (token rotation).

✦ API Gateway security


Use an API Gateway (AWS API GW, Kong, Apigee) to handle auth, rate limiting, IP allowlisting, WAF (Web
Application Firewall), DDoS protection before requests hit your backend.

Page 33
REST API REST API Complete Guide

Chapter 14 — REST API in C++


C++ is used for high-performance REST clients in game backends, embedded systems, trading platforms,
and systems programming. The main libraries are libcurl (HTTP client) and nlohmann/json (JSON parsing).

14.1 Setting Up — Dependencies


// Ubuntu/Debian:
sudo apt-get install libcurl4-openssl-dev

// Install nlohmann/json (header-only):


// Download [Link] from [Link]
// Or via vcpkg: vcpkg install nlohmann-json
// Or via conan: conan install nlohmann_json/3.11.2

// [Link]:
cmake_minimum_required(VERSION 3.16)
project(RestApiClient)
set(CMAKE_CXX_STANDARD 17)
find_package(CURL REQUIRED)
add_executable(client [Link])
target_link_libraries(client CURL::libcurl)
target_include_directories(client PRIVATE ${CMAKE_SOURCE_DIR}/include)

14.2 HTTP GET Request


#include <iostream>
#include <string>
#include <curl/curl.h>
#include "[Link]"
using json = nlohmann::json;

// Callback to write response data into a string


static size_t WriteCallback(void* contents, size_t size,
size_t nmemb, std::string* output) {
output->append((char*)contents, size * nmemb);
return size * nmemb;
}

struct HttpResponse {
long statusCode;
std::string body;

Page 34
REST API REST API Complete Guide

bool success;
};

HttpResponse httpGet(const std::string& url,


const std::string& bearerToken = "") {
CURL* curl = curl_easy_init();
HttpResponse result{0, "", false};
if (!curl) return result;

std::string responseBody;
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Accept: application/json");
if (![Link]()) {
std::string authHeader = "Authorization: Bearer " + bearerToken;
headers = curl_slist_append(headers, authHeader.c_str());
}

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());


curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody;);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

CURLcode res = curl_easy_perform(curl);


if (res == CURLE_OK) {
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &[Link];);
[Link] = responseBody;
[Link] = ([Link] >= 200 && [Link] < 300);
} else {
std::cerr << "curl error: " << curl_easy_strerror(res) << std::endl;
}

curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return result;
}

int main() {
std::string token = "eyJhbGciOiJSUzI1NiJ9...";
auto resp = httpGet("[Link] token);
if ([Link]) {
json user = json::parse([Link]);
std::cout << "Name: " << user["name"] << std::endl;

Page 35
REST API REST API Complete Guide

std::cout << "Email: " << user["email"] << std::endl;


} else {
std::cerr << "Request failed: " << [Link] << std::endl;
}
}

14.3 HTTP POST Request


HttpResponse httpPost(const std::string& url,
const json& payload,
const std::string& bearerToken = "") {
CURL* curl = curl_easy_init();
HttpResponse result{0, "", false};
if (!curl) return result;

std::string responseBody;
std::string jsonStr = [Link]();

struct curl_slist* headers = nullptr;


headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "Accept: application/json");
if (![Link]()) {
headers = curl_slist_append(headers,
("Authorization: Bearer " + bearerToken).c_str());
}

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());


curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonStr.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)[Link]());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody;);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);

CURLcode res = curl_easy_perform(curl);


if (res == CURLE_OK) {
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &[Link];);
[Link] = responseBody;
[Link] = ([Link] >= 200 && [Link] < 300);
}

curl_slist_free_all(headers);
curl_easy_cleanup(curl);

Page 36
REST API REST API Complete Guide

return result;
}

// Usage:
int main() {
json newUser = {
{"name", "Priya Patel"},
{"email", "priya@[Link]"},
{"role", "engineer"}
};
auto resp = httpPost("[Link]
newUser, "my_token");
if ([Link] == 201) {
json created = json::parse([Link]);
std::cout << "Created user ID: " << created["id"] << std::endl;
}
}

14.4 HTTP PUT, PATCH, DELETE


// PUT — full update (similar to POST but with CURLOPT_CUSTOMREQUEST)
HttpResponse httpPut(const std::string& url, const json& payload,
const std::string& token) {
CURL* curl = curl_easy_init();
// ... (same setup as POST)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
// ... perform and return
}

// PATCH — partial update


HttpResponse httpPatch(const std::string& url, const json& payload,
const std::string& token) {
CURL* curl = curl_easy_init();
// ... setup
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PATCH");
// ...
}

// DELETE
HttpResponse httpDelete(const std::string& url,
const std::string& token) {
CURL* curl = curl_easy_init();

Page 37
REST API REST API Complete Guide

std::string responseBody;
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers,
("Authorization: Bearer " + token).c_str());

curl_easy_setopt(curl, CURLOPT_URL, url.c_str());


curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseBody;);

CURLcode res = curl_easy_perform(curl);


HttpResponse result{0, responseBody, false};
if (res == CURLE_OK) {
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &[Link];);
[Link] = ([Link] == 204 || [Link] == 200);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return result;
}

14.5 Complete C++ REST Client Class


// RestClient.h — reusable class for corporate projects
#pragma once
#include <string>
#include <map>
#include <curl/curl.h>
#include "[Link]"
using json = nlohmann::json;

class RestClient {
public:
explicit RestClient(const std::string& baseUrl,
const std::string& bearerToken = "");
~RestClient();

struct Response {
int statusCode;
json body;
bool ok;
std::string error;

Page 38
REST API REST API Complete Guide

};

Response get (const std::string& path);


Response post (const std::string& path, const json& body);
Response put (const std::string& path, const json& body);
Response patch (const std::string& path, const json& body);
Response del (const std::string& path);

void setHeader(const std::string& key, const std::string& value);


void setToken (const std::string& token);
void setTimeout(long seconds);

private:
std::string baseUrl_;
std::string token_;
long timeout_ = 30;
std::map<std::string, std::string> extraHeaders_;

Response perform(const std::string& method,


const std::string& path,
const json* body = nullptr);
static size_t writeCallback(void*, size_t, size_t, std::string*);
};

// Usage in corporate project:


int main() {
RestClient client("[Link] "Bearer_token_here");
[Link](10);

// GET user
auto user = [Link]("/users/42");
if ([Link]) std::cout << [Link]["name"] << std::endl;

// POST new order


json order = {{ "productId", 55 }, { "qty", 2 }};
auto created = [Link]("/orders", order);
if ([Link] == 201)
std::cout << "Order: " << [Link]["id"] << std::endl;

// PATCH update
auto patched = [Link]("/users/42", {{ "role", "lead" }});

// DELETE
auto deleted = [Link]("/users/99");
if ([Link] == 204)
std::cout << "Deleted successfully" << std::endl;
}

Page 39
REST API REST API Complete Guide

Chapter 15 — REST API in Java


Java is the dominant language for enterprise REST APIs. You'll use it on both sides: building REST servers
(Spring Boot) and consuming REST services (HttpClient, OkHttp, Retrofit, Feign).

15.1 Java 11+ HttpClient (Built-in, No Dependencies)


import [Link];
import [Link].*;
import [Link];
import [Link];
import [Link];
import [Link];

public class RestApiClient {

private final HttpClient client;


private final ObjectMapper mapper;
private final String baseUrl;
private final String bearerToken;

public RestApiClient(String baseUrl, String token) {


[Link] = baseUrl;
[Link] = token;
[Link] = new ObjectMapper();
[Link] = [Link]()
.connectTimeout([Link](10))
.followRedirects([Link])
.build();
}

// ■■ GET ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
public JsonNode get(String path) throws Exception {
HttpRequest request = [Link]()
.uri([Link](baseUrl + path))
.header("Authorization", "Bearer " + bearerToken)
.header("Accept", "application/json")
.timeout([Link](30))
.GET()
.build();

HttpResponse<String> response =
[Link](request, [Link]());

Page 40
REST API REST API Complete Guide

if ([Link]() == 200) {
return [Link]([Link]());
} else if ([Link]() == 404) {
throw new ResourceNotFoundException("Not found: " + path);
} else {
throw new ApiException([Link](), [Link]());
}
}

// ■■ POST ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
public JsonNode post(String path, Object body) throws Exception {
String json = [Link](body);

HttpRequest request = [Link]()


.uri([Link](baseUrl + path))
.header("Authorization", "Bearer " + bearerToken)
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST([Link](json))
.build();

HttpResponse<String> response =
[Link](request, [Link]());

if ([Link]() == 201 || [Link]() == 200) {


return [Link]([Link]());
}
throw new ApiException([Link](), [Link]());
}

// ■■ PUT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
public JsonNode put(String path, Object body) throws Exception {
String json = [Link](body);
HttpRequest request = [Link]()
.uri([Link](baseUrl + path))
.header("Authorization", "Bearer " + bearerToken)
.header("Content-Type", "application/json")
.PUT([Link](json))
.build();
HttpResponse<String> r = [Link](request, [Link]());
if ([Link]() == 200) return [Link]([Link]());
throw new ApiException([Link](), [Link]());
}
// ■■ PATCH ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

Page 41
REST API REST API Complete Guide

public JsonNode patch(String path, Object body) throws Exception {


String json = [Link](body);
HttpRequest request = [Link]()
.uri([Link](baseUrl + path))
.header("Authorization", "Bearer " + bearerToken)
.header("Content-Type", "application/json")
.method("PATCH", [Link](json))
.build();
HttpResponse<String> r = [Link](request, [Link]());
if ([Link]() == 200) return [Link]([Link]());
throw new ApiException([Link](), [Link]());
}

// ■■ DELETE ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
public boolean delete(String path) throws Exception {
HttpRequest request = [Link]()
.uri([Link](baseUrl + path))
.header("Authorization", "Bearer " + bearerToken)
.DELETE()
.build();
HttpResponse<String> r = [Link](request, [Link]());
return [Link]() == 204 || [Link]() == 200;
}
}

15.2 OkHttp (Industry Standard for Android / Kotlin)


// [Link]:
implementation '[Link].okhttp3:okhttp:4.12.0'
implementation '[Link].okhttp3:logging-interceptor:4.12.0'

import okhttp3.*;
import [Link];
import [Link];

public class OkHttpRestClient {

private static final MediaType JSON_TYPE =


[Link]("application/json; charset=utf-8");

private final OkHttpClient client;


private final String baseUrl;
private String bearerToken;
public OkHttpRestClient(String baseUrl, String token) {

Page 42
REST API REST API Complete Guide

[Link] = baseUrl;
[Link] = token;

// Logging interceptor for debugging (disable in production)


HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
[Link]([Link]);

[Link] = new [Link]()


.connectTimeout(10, [Link])
.readTimeout(30, [Link])
.writeTimeout(30, [Link])
.addInterceptor(logging)
// Auth interceptor — automatically adds token to all requests
.addInterceptor(chain -> {
Request original = [Link]();
[Link] builder = [Link]()
.header("Authorization", "Bearer " + bearerToken)
.header("Accept", "application/json");
return [Link]([Link]());
})
.build();
}

public String get(String path) throws IOException {


Request request = new [Link]()
.url(baseUrl + path)
.get()
.build();

try (Response response = [Link](request).execute()) {


if (![Link]())
throw new IOException("HTTP " + [Link]());
return [Link]().string();
}
}

public String post(String path, String jsonBody) throws IOException {


RequestBody body = [Link](jsonBody, JSON_TYPE);
Request request = new [Link]()
.url(baseUrl + path)
.post(body)
.build();
try (Response response = [Link](request).execute()) {
return [Link]().string();

Page 43
REST API REST API Complete Guide

}
}

// Async GET with callback (non-blocking, for Android UI):


public void getAsync(String path, Callback callback) {
Request request = new [Link]().url(baseUrl + path).build();
[Link](request).enqueue(callback);
}
}

15.3 Retrofit — Declarative REST Client (Android/Java)


// [Link]:
implementation '[Link].retrofit2:retrofit:2.9.0'
implementation '[Link].retrofit2:converter-gson:2.9.0'

// Step 1: Define API interface (type-safe, no URL strings in code)


public interface UserApiService {

@GET("users")
Call<List<User>> getUsers(
@Query("page") int page,
@Query("limit") int limit,
@Query("role") String role
);

@GET("users/{id}")
Call<User> getUser(@Path("id") int userId);
@POST("users")
Call<User> createUser(@Body CreateUserRequest request);

@PUT("users/{id}")
Call<User> updateUser(@Path("id") int id, @Body UpdateUserRequest req);

@PATCH("users/{id}")
Call<User> patchUser(@Path("id") int id,
@Body Map<String, Object> fields);

@DELETE("users/{id}")
Call<Void> deleteUser(@Path("id") int userId);

@GET("users/{id}/orders")
Call<List<Order>> getUserOrders(
@Path("id") int userId,
@Header("Authorization") String token
);
}

Page 44
REST API REST API Complete Guide

// Step 2: Build Retrofit instance


OkHttpClient okHttp = new [Link]()
.addInterceptor(chain -> {
Request req = [Link]().newBuilder()
.header("Authorization", "Bearer " + TOKEN)
.build();
return [Link](req);
}).build();

Retrofit retrofit = new [Link]()


.baseUrl("[Link]
.client(okHttp)
.addConverterFactory([Link]())
.build();
UserApiService api = [Link]([Link]);

// Step 3: Make calls


// Synchronous (background thread):
Response<User> response = [Link](42).execute();
if ([Link]()) {
User user = [Link]();
[Link]([Link]());
}

// Asynchronous (Android main thread safe):


[Link](1, 20, "engineer").enqueue(new Callback<List<User>>() {
@Override
public void onResponse(Call<List<User>> call, Response<List<User>> response) {
if ([Link]()) {
List<User> users = [Link]();
// update UI
}
}
@Override
public void onFailure(Call<List<User>> call, Throwable t) {
Log.e("API", "Failed: " + [Link]());
}
});

15.4 Spring Boot — Building a REST API Server


// [Link] dependencies:

Page 45
REST API REST API Complete Guide

<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

// [Link] — Model
@Entity
public class User {
@Id @GeneratedValue(strategy = [Link])
private Long id;
private String name;
private String email;
private String role;
// constructors, getters, setters
}

// [Link] — REST Controller


@RestController
@RequestMapping("/v1/users")
@Validated
public class UserController {

@Autowired
private UserService userService;

// GET all users


@GetMapping
public ResponseEntity<Page<User>> getAllUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(required = false) String role) {
Page<User> users = [Link](page, size, role);
return [Link](users);
}

// GET single user


@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return [Link](id)
.map(ResponseEntity::ok)
.orElse([Link]().build());
}

// POST create user


@PostMapping

Page 46
REST API REST API Complete Guide

public ResponseEntity<User> createUser(


@Valid @RequestBody CreateUserRequest req) {
User user = [Link](req);
URI location = [Link]("/v1/users/" + [Link]());
return [Link](location).body(user);
}

// PUT full update


@PutMapping("/{id}")
public ResponseEntity<User> updateUser(
@PathVariable Long id,
@Valid @RequestBody UpdateUserRequest req) {
return [Link]([Link](id, req));
}
// PATCH partial update
@PatchMapping("/{id}")
public ResponseEntity<User> patchUser(
@PathVariable Long id,
@RequestBody Map<String, Object> updates) {
return [Link]([Link](id, updates));
}

// DELETE
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
[Link](id);
return [Link]().build(); // 204
}
}

Page 47
REST API REST API Complete Guide

Chapter 16 — Corporate Best Practices


■ Use an API Gateway
All external traffic flows through an API Gateway (AWS API Gateway, Kong, Apigee). It handles auth, SSL
termination, rate limiting, logging, analytics, and routing before requests hit your microservices.

■ Always version your API


/v1/, /v2/. Never break existing clients. Deprecate old versions gracefully with 12+ months notice. Set
Deprecation and Sunset headers.

■ Consistent error response format


Every error must follow the same structure: {error: CODE, message: human_readable, details: [...], requestId:
...}. Document all error codes in your API spec.

■ Request tracing
Generate a unique X-Request-Id for every request. Log it with every log line. Return it in response headers.
Use X-Correlation-Id to trace across multiple microservices.

■ Structured logging
Log every request: method, path, status, duration, userId, requestId. Use JSON logs for log aggregation
(ELK stack, Splunk, Datadog).

■ API documentation with OpenAPI/Swagger


Every corporate API must have an OpenAPI 3.0 spec. Generates interactive documentation, client SDKs,
server stubs. Maintain it as code in your repo — never as a separate document.

■ Contract-first development
Write your OpenAPI spec BEFORE writing code. Generate server stubs and client SDKs from the spec.
Prevents mismatches between client and server.

■ Use connection pooling


Never create a new HTTP connection per request in production. Reuse connections via HTTP keep-alive and
connection pools. OkHttp and Java HttpClient handle this automatically.

■ Implement retry with exponential backoff


On 5xx errors and network failures, retry with increasing delays: 1s, 2s, 4s, 8s. Add jitter to prevent
thundering herd. Max 3-5 retries. Never retry on 4xx errors (client error, won't fix itself).

Page 48
REST API REST API Complete Guide

■ Circuit breaker pattern


Use Resilience4j (Java) or similar. If N% of requests fail, 'open' the circuit — fail fast instead of waiting for
timeout. Prevents cascading failures across microservices.

■ Idempotency keys for mutations


POST /orders with Idempotency-Key header. If network fails and client retries, the server recognizes the key
and returns the original response instead of creating a duplicate order.

■ Monitor API health


Track: p50/p95/p99 latency, error rate, requests/second. Set alerts on error rate > 1%, p99 > 2000ms. Use
/health and /metrics endpoints. Integrate with Prometheus + Grafana.

Page 49
REST API REST API Complete Guide

Chapter 17 — Testing REST APIs

17.1 Tools Overview


Tool Type Use Case

Postman GUI client Manual testing, collections, automation

curl CLI client Quick one-off tests, scripts, CI

Insomnia GUI client Lightweight alternative to Postman

JUnit + MockMvc Unit/Integration Java Spring Boot controller testing

REST Assured Integration (Java) BDD-style Java API testing

Pytest + requests Integration (Py) Python API test suite

k6 / JMeter Load testing Performance, stress, spike testing

Pact Contract testing Consumer-driven contract tests

WireMock Mocking Mock external APIs in tests

17.2 curl — Command Line Testing


# GET
curl -X GET [Link] \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Accept: application/json' \
-v # verbose — shows headers

# POST
curl -X POST [Link] \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Rahul","email":"r@[Link]","role":"engineer"}'

# PUT
curl -X PUT [Link] \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Rahul Kumar","email":"r@[Link]","role":"lead"}'

# PATCH
curl -X PATCH [Link] \

Page 50
REST API REST API Complete Guide

-H 'Authorization: Bearer YOUR_TOKEN' \


-H 'Content-Type: application/json' \
-d '{"role":"staff-engineer"}'

# DELETE
curl -X DELETE [Link] \
-H 'Authorization: Bearer YOUR_TOKEN' \
-w '\nHTTP Status: %{http_code}\n'

# Useful curl flags:


# -v verbose (show headers)
# -o file save response to file
# -w format write-out (print status code)
# -s silent (no progress bar)
# -k skip SSL verification (dev only!)
# --compressed accept gzip compression

17.3 Spring Boot — Integration Testing with MockMvc


@SpringBootTest
@AutoConfigureMockMvc
class UserControllerTest {

@Autowired MockMvc mockMvc;


@Autowired ObjectMapper mapper;

@Test
@WithMockUser(roles = "ADMIN")
void getUser_found_returns200() throws Exception {
[Link](get("/v1/users/42")
.header("Accept", "application/json"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(42))
.andExpect(jsonPath("$.name").isNotEmpty());
}

@Test
@WithMockUser(roles = "ADMIN")
void createUser_validBody_returns201() throws Exception {
CreateUserRequest req = new CreateUserRequest("Priya", "p@[Link]");
[Link](post("/v1/users")
.contentType(MediaType.APPLICATION_JSON)
.content([Link](req)))
.andExpect(status().isCreated())

Page 51
REST API REST API Complete Guide

.andExpect(header().exists("Location"))
.andExpect(jsonPath("$.id").isNumber());
}

@Test
@WithMockUser(roles = "ADMIN")
void getUser_notFound_returns404() throws Exception {
[Link](get("/v1/users/9999"))
.andExpect(status().isNotFound());
}
}

Page 52
REST API REST API Complete Guide

Chapter 18 — Error Handling Patterns


// Standard error response format (use consistently across ALL endpoints):
{
"error": {
"code": "VALIDATION_ERROR", // machine-readable code
"message": "Request validation failed", // human-readable
"details": [ // optional: field-level errors
{ "field": "email", "message": "Invalid email format" },
{ "field": "password", "message": "Must be 8+ chars" }
],
"requestId": "req_abc123", // for support tickets
"timestamp": "2024-11-20T10:00:00Z",
"path": "/v1/users",
"docs": "[Link]
}
}

// Spring Boot Global Exception Handler:


@RestControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler([Link])
@ResponseStatus(HttpStatus.UNPROCESSABLE_ENTITY)
public ErrorResponse handleValidation(MethodArgumentNotValidException ex) {
List<FieldError> errors = [Link]().getFieldErrors()
.stream().map(e -> new FieldError([Link](), [Link]()))
.collect(toList());
return [Link]()
.code("VALIDATION_ERROR")
.message("Request validation failed")
.details(errors).build();
}

@ExceptionHandler([Link])
@ResponseStatus(HttpStatus.NOT_FOUND)
public ErrorResponse handleNotFound(ResourceNotFoundException ex) {
return [Link]("NOT_FOUND", [Link]());
}

@ExceptionHandler([Link])
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)

Page 53
REST API REST API Complete Guide

public ErrorResponse handleAll(Exception ex, HttpServletRequest req) {


[Link]("Unhandled exception on {}: {}", [Link](), ex);
return [Link]("INTERNAL_ERROR",
"An unexpected error occurred. Request ID: " + getRequestId(req));
}
}

Page 54
REST API REST API Complete Guide

Chapter 19 — Real-World Project:


E-Commerce REST API
Let's design the complete REST API for an e-commerce platform, covering all resources, endpoints, auth,
and flows as you'd do it at a corporate company.

19.1 Resources & Endpoints


Method Endpoint Description

POST /v1/auth/login Login, get JWT token

POST /v1/auth/refresh Refresh access token

POST /v1/auth/logout Invalidate refresh token

GET /v1/users List users (admin only)

GET /v1/users/{id} Get user profile

POST /v1/users Register new user

PATCH /v1/users/{id} Update profile fields

DELETE /v1/users/{id} Deactivate account

GET /v1/products List products (filterable)

GET /v1/products/{id} Get product details

GET /v1/products/search?q=... Search products

POST /v1/products Create product (admin)

PUT /v1/products/{id} Replace product (admin)

PATCH /v1/products/{id} Update product fields (admin)

DELETE /v1/products/{id} Delete product (admin)

GET /v1/orders List user's orders

GET /v1/orders/{id} Get order details

POST /v1/orders Place new order

PATCH /v1/orders/{id}/cancel Cancel an order

GET /v1/users/{id}/orders Get orders for specific user

Page 55
REST API REST API Complete Guide

Method Endpoint Description

GET /v1/cart Get current user's cart

POST /v1/cart/items Add item to cart

PATCH /v1/cart/items/{itemId} Update item quantity

DELETE /v1/cart/items/{itemId} Remove item from cart

DELETE /v1/cart Clear entire cart

POST /v1/payments Process payment for order

GET /v1/payments/{id} Get payment status

GET /v1/products/{id}/reviews List product reviews

POST /v1/products/{id}/reviews Submit review

DELETE /v1/reviews/{id} Delete review

19.2 Complete Order Flow — API Call Sequence


Step 1: Login
POST /v1/auth/login
{ "email": "customer@[Link]", "password": "pass" }
→ 200 { accessToken, refreshToken, expiresIn }

Step 2: Browse products


GET /v1/products?category=electronics&maxPrice;=1000&sort;=-rating&page;=1
→ 200 { data: [...products], pagination: {...} }

Step 3: Add to cart


POST /v1/cart/items
{ "productId": 55, "quantity": 2 }
→ 200 { cart: { items: [...], subtotal: 599.98 } }

Step 4: Place order


POST /v1/orders
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
{ "cartId": "cart_123", "addressId": "addr_456", "paymentMethodId": "pm_789" }
→ 201 { orderId: 1001, status: PENDING, total: 649.98 }
Location: /v1/orders/1001

Step 5: Process payment


POST /v1/payments
{ "orderId": 1001, "amount": 649.98, "currency": "INR" }
→ 202 { paymentId: pay_abc, status: PROCESSING }

Page 56
REST API REST API Complete Guide

Step 6: Check order status


GET /v1/orders/1001
→ 200 { orderId: 1001, status: CONFIRMED, estimatedDelivery: ... }

Page 57
REST API REST API Complete Guide

Chapter 20 — Quick Reference Card

HTTP Methods Cheat Sheet


Method Action Success Code Idempotent Body?

GET Read/Retrieve 200 OK Yes No

POST Create 201 Created No Yes

PUT Full Replace 200 OK Yes Yes

PATCH Partial Update 200 OK No* Yes

DELETE Remove 204 No Content Yes No

HEAD Headers Only 200 OK Yes No

OPTIONS List Methods 204 No Content Yes No

Status Code Quick Reference


Code Meaning Code Meaning

200 OK — success 400 Bad Request

201 Created (POST success) 401 Unauthorized (no auth)

202 Accepted (async) 403 Forbidden (no permission)

204 No Content (DELETE ok) 404 Not Found

301 Moved Permanently 409 Conflict (duplicate)

304 Not Modified (cache hit) 422 Validation Error

307 Temporary Redirect 429 Rate Limit Exceeded

308 Permanent Redirect 500 Internal Server Error

— — 503 Service Unavailable

URL Design Rules


• Use nouns, not verbs: /users not /getUsers
• Plural names for collections: /users, /orders, /products
• Lowercase, hyphens only: /user-profiles not /UserProfiles

Page 58
REST API REST API Complete Guide

• Nest related resources: /users/{id}/orders


• Query params for filters: /users?role=admin&active;=true
• Version in path: /v1/users
• Resource ID in path: /users/42 not /users?id=42
• No trailing slashes: /users not /users/

Corporate API Checklist


✓ HTTPS only — no HTTP
✓ Auth on every protected endpoint
✓ Versioned API (/v1/)
✓ Consistent error format
✓ Pagination on all list endpoints
✓ X-Request-Id in every response
✓ Rate limiting implemented
✓ Input validation on all fields
✓ OpenAPI/Swagger documentation
✓ Health endpoint (/health)
✓ Metrics endpoint (/metrics or Prometheus)
✓ Structured logging with request IDs
✓ CORS configured correctly
✓ Location header on 201 responses
✓ Retry logic with exponential backoff in clients
✓ Connection pooling in HTTP clients
✓ Integration tests for all endpoints
✓ Security headers (HSTS, X-Content-Type-Options)

You now have a complete foundation in REST API design, implementation, and best
practices. Build great APIs — stateless, versioned, secure, and well-documented.

Page 59

You might also like