API roadmap
API Fundamentals
What is an API?
API stands for Application Programming Interface. It is a contract that defines how one software component can request data or behavior from another component.
Server
Contract
Basic API communication
Think of an API like a restaurant contract
You are the client. The menu describes what can be requested. The waiter carries your request to the kitchen. The kitchen contains the internal implementation. You normally do not need to know how the kitchen prepares the result—you need to know what you can order and what you will receive.
API Architecture
Major API styles
API is a broad concept. REST and GraphQL are two common approaches, but production systems also use RPC, gRPC, SOAP, WebSockets and webhooks.
REST
Resource-oriented API style commonly built on HTTP methods, URLs and representations such as JSON.
Good fit: Public APIs, CRUD services, microservices, mobile/web backends and general HTTP services.
GraphQL
A typed query language where clients specify the fields they need from a schema.
Good fit: Complex frontend data requirements, multiple related resources and rapidly changing clients.
RPC
Treats the API as a collection of remote operations such as createInvoice or calculatePrice.
Good fit: Action-heavy internal services where operations are more natural than resources.
gRPC
High-performance RPC commonly using Protocol Buffers and HTTP/2.
Good fit: Low-latency service-to-service communication and strongly typed internal systems.
SOAP
XML-based messaging protocol with formal contracts and enterprise-oriented standards.
Good fit: Legacy enterprise systems and environments requiring established WS-* standards.
WebSocket
Persistent bidirectional connection between client and server.
Good fit: Chat, multiplayer systems, collaboration, trading dashboards and realtime communication.
Webhook
Server-to-server callback where one system pushes an event to another system.
Good fit: Payment updates, Git events, order events, email delivery events and asynchronous integrations.
Public API
Private / Internal API
Partner API
Composite API
HTTP
HTTP foundation
Most web APIs communicate over HTTP. Understanding HTTP is therefore fundamental to understanding REST APIs.
URL
Method
Headers
Body
Anatomy of a URL
| Part | Example | Meaning |
|---|---|---|
| Scheme | https | Protocol used for communication. |
| Host | api.example.com | Domain containing the API. |
| Base path | /api/v1 | Common prefix, sometimes containing API version. |
| Resource | /users | Collection being addressed. |
| Resource ID | /42 | A specific resource inside the collection. |
| Query string | ?include=orders | Optional query parameters modifying the request. |
HTTP Messages
Request and response lifecycle
Every API interaction has two major messages: a request produced by the client and a response produced by the server.
Client → server
HTTP Request
GET /api/v1/users/42?include=orders HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer <access-token>
X-Request-ID: req_f8270Server → client
HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: private, max-age=60
ETag: "user-42-v8"
X-Request-ID: req_f8270
{
"data": {
"id": 42,
"name": "Aman",
"email": "[email protected]"
}
}Detailed request lifecycle
Request contains
- HTTP method
- URL / path
- Query parameters
- Headers
- Cookies when applicable
- Optional request body
Response contains
- Status code
- Response headers
- Optional response body
- Cache instructions
- Correlation or request ID
- Structured error details on failure
HTTP Semantics
HTTP methods
Use methods according to their defined semantics. The method should communicate what the client wants to do with the target resource.
| Method | Purpose | Example | Safe | Idempotent | Common success |
|---|---|---|---|---|---|
| GET | Read a resource or collection. Should not intentionally change application state. | GET /api/v1/users/42 | Yes | Yes | 200 OK |
| POST | Create a resource or execute an operation. Can be made retry-safe with an idempotency key. | POST /api/v1/orders | No | No* | 201 Created |
| PUT | Replace the complete representation of a resource. Repeated identical requests should have the same intended effect. | PUT /api/v1/users/42 | No | Yes | 200 / 204 |
| PATCH | Partially update a resource. Updates selected fields instead of replacing the complete resource. | PATCH /api/v1/users/42 | No | Depends | 200 / 204 |
| DELETE | Remove a resource. Deleting an already deleted resource should not create another effect. | DELETE /api/v1/users/42 | No | Yes | 204 No Content |
| HEAD | Get headers that a GET request would return. Useful for metadata and availability checks. | HEAD /api/v1/books/100 | Yes | Yes | 200 OK |
| OPTIONS | Discover communication options for a resource. Frequently appears in browser CORS preflight requests. | OPTIONS /api/v1/users | Yes | Yes | 200 / 204 |
Safe method
Idempotent method
Create a user
HTTP
POST /api/v1/users
Content-Type: application/json
Authorization: Bearer <access-token>
{
"name": "Aman",
"email": "[email protected]"
}Successful creation
HTTP
HTTP/1.1 201 Created
Location: /api/v1/users/42
Content-Type: application/json
{
"data": {
"id": 42,
"name": "Aman",
"email": "[email protected]",
"createdAt": "2026-09-30T10:30:00Z"
}
}HTTP Response
HTTP status codes
Status codes allow a client to understand the broad result of a request without parsing application-specific response text.
1xx — Informational
The request is still being processed or the protocol is changing.
2xx — Success
The server successfully processed the request.
3xx — Redirection
The client may need another request or can reuse a cached representation.
4xx — Client Error
Something about the request, authentication, permissions or requested resource is invalid.
5xx — Server Error
The server or an upstream dependency failed while serving a valid request.
| Code | Use it when |
|---|---|
| 200 OK | Request succeeded and a normal response representation is returned. |
| 201 Created | A new resource was successfully created. |
| 202 Accepted | Request was accepted for asynchronous processing but processing is not complete. |
| 204 No Content | Operation succeeded and no response body is necessary. |
| 304 Not Modified | Conditional request indicates the cached representation is still valid. |
| 400 Bad Request | The request is malformed or cannot be understood according to the API contract. |
| 401 Unauthorized | Authentication credentials are missing or invalid. |
| 403 Forbidden | The caller is authenticated but does not have permission for the operation. |
| 404 Not Found | The requested resource cannot be found. |
| 409 Conflict | The request conflicts with the current state of the resource. |
| 422 Unprocessable Content | The request syntax may be valid but the content cannot be processed semantically. |
| 429 Too Many Requests | The caller has exceeded an enforced request limit. |
| 500 Internal Server Error | An unexpected server-side failure occurred. |
| 502 Bad Gateway | A gateway/proxy received an invalid response from an upstream service. |
| 503 Service Unavailable | The service cannot currently handle the request. |
| 504 Gateway Timeout | A gateway/proxy did not receive a timely response from an upstream service. |
REST
What is REST?
REST stands for Representational State Transfer. It is an architectural style for distributed systems rather than a programming language, framework or wire protocol.
In a typical HTTP REST API, the server exposes resources such as users, products or orders. The client identifies resources using URIs and interacts with them through standardized HTTP semantics.
REST constraints
Client–Server
UI/client concerns and server/data concerns are separated. Either side can evolve independently as long as the contract remains compatible.
Stateless
Every request should contain the information needed to process it. The server should not depend on conversational client session state between requests.
Cacheable
Responses should communicate whether they may be cached. Correct caching can reduce latency, server load and bandwidth.
Uniform Interface
Resources use consistent identifiers and standard interaction semantics so clients do not need resource-specific transport behavior.
Layered System
The client does not need to know whether it communicates directly with the origin server, an API gateway, proxy, CDN or another intermediary.
Code on Demand
An optional REST constraint allowing a server to extend client functionality by transferring executable code.
REST resource model
REST API vs RESTful API
In everyday engineering conversation, the terms are often used interchangeably. “RESTful” generally emphasizes that the API follows REST principles consistently rather than merely using HTTP and JSON.
REST Design
How to design REST resources
Start with the domain resources, not controller method names. HTTP already provides operation semantics.
Avoid
GET /getAllUsersPrefer
GET /usersThe HTTP method already communicates the action.
Avoid
POST /createUserPrefer
POST /usersModel the endpoint as a resource rather than a CRUD verb.
Avoid
GET /deleteUser?id=42Prefer
DELETE /users/42GET should not be used to request destructive operations.
Avoid
/user/42/ordersPrefer
/users/42/ordersUse consistent resource naming conventions.
Avoid
/api/users/getById/42Prefer
/api/v1/users/42Resource path + HTTP method is generally enough.
Collections
/usersRepresents a collection of user resources.
Single resource
/users/42Represents the user whose identifier is 42.
Nested resource
/users/42/ordersRepresents orders scoped to a particular user.
Sub-resource
/orders/9001/itemsRepresents items associated with order 9001.
Request Design
Path, query, header and body parameters
Path parameter
Here, 42 is part of resource identity.
Query parameter
Header
Request body
Easy rule
Use a path parameter when the value identifies which resource you mean. Use a query parameter when it modifies selection, filtering, searching, sorting, pagination or representation.
Contract Design
Designing consistent API responses
Single resource
{
"data": {
"id": 42,
"name": "Aman"
}
}Collection
{
"data": [
{ "id": 41, "name": "Riya" },
{ "id": 42, "name": "Aman" }
],
"pagination": {
"page": 1,
"limit": 20
}
}- Use stable field names and predictable types.
- Do not change a field from string to object without considering compatibility.
- Avoid returning HTTP 200 for every failure and hiding error semantics only inside JSON.
- Include correlation/request identifiers when they help support and debugging.
Reliability
API error handling
A useful error should tell the caller what category of failure occurred, give a stable machine-readable code and provide enough context to correct the request without leaking sensitive internals.
Structured error response
JSON
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request contains invalid fields.",
"requestId": "req_f8270",
"details": [
{
"field": "email",
"message": "A valid email address is required."
}
]
}
}Bad error
{ "error": "Something went wrong" }The client cannot programmatically understand the failure.
Better error
Never expose
- • Database passwords
- • Access tokens
- • Private keys
- • Internal stack traces to public clients
- • Raw SQL containing sensitive values
- • Internal infrastructure secrets
Scalability
API pagination
Never return an unbounded collection when that collection can grow significantly.
Offset / page pagination
HTTP + JSON
GET /api/v1/products?page=3&limit=20
{
"data": [...],
"pagination": {
"page": 3,
"limit": 20,
"totalItems": 242,
"totalPages": 13,
"hasNext": true,
"hasPrevious": true
}
}Easy for users to understand and jump between pages, but large offsets can become expensive and changing datasets can cause duplicate or skipped items.
Cursor pagination
HTTP + JSON
GET /api/v1/feed?limit=20&after=eyJpZCI6OTg3fQ
{
"data": [...],
"pageInfo": {
"nextCursor": "eyJpZCI6MTAwN30",
"hasNextPage": true
}
}Better suited to large or frequently changing feeds because the cursor points to a position in an ordered dataset rather than a numeric offset.
Jump to page
Easy
Usually not supported directly
Large datasets
Can degrade with large offsets
Usually better
Changing data
May skip/duplicate rows
Usually more stable with correct ordering
Implementation
Simple
More design work
Collections
Filtering, sorting, searching and field selection
One possible query design
HTTP
GET /api/v1/products
?category=books
&minPrice=100
&maxPrice=1000
&sort=-createdAt
&fields=id,title,price
&search=system+designFiltering
?status=PAID¤cy=INRSorting
?sort=-createdAt,priceA minus prefix can represent descending order if documented by your API.
Search
?search=system+designSparse field selection
?fields=id,title,priceCan reduce response size when clients only need selected fields.
Compatibility
API versioning
Versioning gives you a controlled path for breaking contract changes. Not every change requires a new API version.
URI versioning
/api/v1/usersVery visible and easy for clients and documentation.
Header versioning
API-Version: 2026-09-01Keeps URLs clean but is less obvious when inspecting links.
Media type versioning
Accept: application/vnd.app.v2+jsonVersion information is expressed through content negotiation.
Often backward-compatible
- Adding an optional response field
- Adding a new endpoint
- Adding an optional request parameter
Potentially breaking
- Removing a field
- Changing a field type
- Renaming a field
- Changing meaning of an existing field
- Making an optional request field mandatory
Distributed Systems
Idempotency and safe retries
Networks fail in uncomfortable places. A client might not know whether the server processed a request because the connection disappeared before the response arrived.
Why duplicate payments can happen
POST with idempotency key
HTTP
POST /api/v1/payments
Idempotency-Key: pay_01928475
Content-Type: application/json
{
"orderId": "ORD-8429",
"amount": 19900,
"currency": "INR"
}Idempotency-key flow
A production implementation usually associates the idempotency key with the caller and request, stores the outcome for a defined lifetime, and protects concurrent requests using atomic operations or transactional guarantees.
Security
API authentication
Authentication answers: Who is making this request?
API key
HTTP
GET /api/v1/weather
X-API-Key: sk_live_xxxxxxxxxBearer token / JWT
HTTP
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
GET /api/v1/profileSession / cookie
OAuth 2.0
Bearer-token request
Security
API security checklist
Use HTTPS
Protect credentials and application data in transit using TLS.
Validate input
Treat all client input as untrusted and enforce size, type, range and format constraints.
Authorize every protected resource
Do not assume knowing a resource ID means the caller may access it.
Rate limit sensitive operations
Protect login, OTP, password reset and expensive endpoints from abuse.
Protect secrets
Do not hardcode API secrets in frontend bundles or commit them to source control.
Short-lived credentials
Limit the damage from compromised credentials where your authentication model allows it.
Audit important actions
Record security-relevant changes with actor, target, timestamp and request context.
Limit response data
Do not expose sensitive fields merely because they exist in the database model.
Control payload sizes
Bound uploads, JSON depth, query complexity and other resource-intensive input.
Secure dependencies
Patch frameworks, libraries, gateways and infrastructure components.
Browser Security
CORS
Cross-Origin Resource Sharing is an HTTP-header mechanism used by browsers to decide whether frontend JavaScript from one origin may access resources from another origin.
Typical preflight
Origin
Example response headers
Access-Control-Allow-Origin: https://www.targettrek.in Access-Control-Allow-Methods: GET, POST Access-Control-Allow-Headers: Content-Type, Authorization
CORS is primarily a browser-enforced mechanism. It is not a replacement for authentication or authorization. Your backend must still enforce who is allowed to access protected data.
Performance
API caching
Caching avoids repeating work when a previously generated representation can still be reused.
Cache lookup
Conditional request with ETag
HTTP
GET /api/v1/books/42
If-None-Match: "book-42-v12"
# If unchanged:
HTTP/1.1 304 Not Modified
ETag: "book-42-v12"
# If changed:
HTTP/1.1 200 OK
ETag: "book-42-v13"
Content-Type: application/json
{
"id": 42,
"title": "System Design"
}Cache-Control
ETag
304 Not Modified
CDN / shared cache
Reliability
Rate limiting
Rate limiting controls how frequently a caller may perform requests. It protects capacity, fairness, costs and sensitive endpoints.
Fixed window
Sliding window
Token bucket
Leaky bucket
Rate limit response
HTTP
HTTP/1.1 429 Too Many Requests
Retry-After: 30
RateLimit-Limit: 100
RateLimit-Remaining: 0
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Retry later."
}
}Distributed rate limiting
GraphQL
GraphQL API
GraphQL exposes a typed schema and lets clients select the fields they need. A GraphQL server commonly exposes operations through queries, mutations and subscriptions.
Query
Similar in intent to data-fetching operations.
Mutation
Subscription
GraphQL execution flow
Schema
GraphQL SDL
type User {
id: ID!
name: String!
email: String!
orders(first: Int, after: String): OrderConnection!
}
type Order {
id: ID!
total: Float!
status: OrderStatus!
}
type Query {
user(id: ID!): User
users(first: Int, after: String): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): User!
}
type Subscription {
orderStatusChanged(orderId: ID!): Order!
}Query
GraphQL
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
orders(first: 3) {
nodes {
id
total
status
}
}
}
}Query response
JSON
{
"data": {
"user": {
"id": "42",
"name": "Aman",
"email": "[email protected]",
"orders": {
"nodes": [
{
"id": "ORD-101",
"total": 199,
"status": "PAID"
}
]
}
}
}
}Mutation
GraphQL
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
id
name
email
}
}Why GraphQL can be useful
Field selection
id, name, orders, reducing unnecessary fields in the representation.Relationship traversal
Typed schema
Client flexibility
GraphQL challenges
N+1 problem
Query complexity
Authorization
Caching
Comparison
REST vs GraphQL
Neither technology is universally superior. Choose based on API consumers, data relationships, caching needs, operational complexity and team experience.
Primary model
Resources identified through URIs.
Typed graph exposed through a schema.
Data selection
Server defines each endpoint representation.
Client selects requested fields.
Endpoints
Typically multiple resource URLs.
Commonly a GraphQL endpoint handling many operations.
Caching
Works naturally with HTTP GET semantics and URL-addressable resources.
Often requires more application/client-aware caching design.
Related data
May require multiple endpoints or purpose-built representations.
Relationships can be expressed inside one query.
Complexity controls
Endpoint cost is usually easier to reason about.
Arbitrary client queries can require depth and complexity limits.
Good fit
Straightforward resource APIs, public APIs, HTTP-centric services and cacheable resources.
Rich applications with complex and changing data-fetching requirements.
Event Integrations
Webhooks
A webhook reverses the usual polling relationship: instead of repeatedly asking whether something changed, the provider sends an HTTP request when an event happens.
Payment webhook example
Webhook delivery
HTTP + JSON
POST /webhooks/payment
X-Webhook-Id: evt_18273
X-Webhook-Timestamp: 1790767200
X-Webhook-Signature: sha256=...
{
"id": "evt_18273",
"type": "payment.success",
"data": {
"orderId": "ORD-8429",
"paymentId": "PAY-2901"
}
}Verify authenticity
Expect retries
Acknowledge quickly
Observe failures
Direction
Consumer repeatedly asks provider.
Provider pushes event to consumer.
Latency
Depends on polling interval.
Can be near-real-time.
Waste
Many requests may return no change.
Traffic occurs primarily for events.
Complexity
Simple consumer model.
Requires public callback, security and retry handling.
Beyond REST
RPC, gRPC, SOAP and WebSockets
RPC
Remote Procedure Call APIs model operations rather than resources.
gRPC
service UserService {
rpc GetUser(GetUserRequest)
returns (UserResponse);
}SOAP
WebSocket
Realtime communication
Documentation
OpenAPI and Swagger
OpenAPI defines a machine-readable description format for HTTP APIs. Tooling can use that contract for documentation, validation, client generation, server stubs and testing.
OpenAPI
Swagger
OpenAPI example
YAML
openapi: 3.2.0
info:
title: Target Trek Learning API
version: 1.0.0
description: Example API used for learning REST concepts.
servers:
- url: https://api.example.com
paths:
/api/v1/users/{userId}:
get:
summary: Get a user
operationId: getUser
parameters:
- name: userId
in: path
required: true
schema:
type: integer
responses:
"200":
description: User found
content:
application/json:
schema:
$ref: "#/components/schemas/User"
"404":
description: User not found
components:
schemas:
User:
type: object
required:
- id
- name
properties:
id:
type: integer
name:
type: string
email:
type: stringAPI-first workflow
System Design
API Gateway
An API Gateway can provide a managed entry point between external clients and backend services.
Typical API gateway request path
Common responsibilities
- Authentication integration
- Authorization policy enforcement
- Rate limiting
- Routing
- Request/response transformation
- Observability metadata
Gateway vs load balancer
A load balancer primarily distributes traffic among available backends.
An API gateway commonly understands more application/API concerns such as routes, authentication, quotas and API policies.
Real architectures frequently contain both.
Production
API observability
When an API fails in production, you need enough information to answer what failed, where, for whom and why.
Logs
Metrics
Distributed tracing
Useful API metrics
Trace example
Quality
API testing strategy
Unit tests
Integration tests
Contract tests
End-to-end tests
Load tests
Security tests
Test more than the happy path
Testing with cURL
Bash
curl --request POST \
--url https://api.example.com/api/v1/users \
--header "Authorization: Bearer <token>" \
--header "Content-Type: application/json" \
--data '{
"name": "Aman",
"email": "[email protected]"
}'Calling an API from frontend
JavaScript
const response = await fetch(
"https://api.example.com/api/v1/users/42",
{
method: "GET",
headers: {
Accept: "application/json",
Authorization: `Bearer ${accessToken}`,
},
}
);
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const result = await response.json();
console.log(result);Backend
Putting everything together
A production API is more than a controller connected directly to a database. Each layer solves a different concern.
Production API architecture
Inside the service
Controller
Service layer
Repository / DAO
DTO / API model
REST controller example
Java / Spring Boot
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUser(
@PathVariable Long id
) {
UserResponse user = userService.getById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity<UserResponse> createUser(
@Valid @RequestBody CreateUserRequest request
) {
UserResponse created = userService.create(request);
URI location = URI.create(
"/api/v1/users/" + created.id()
);
return ResponseEntity
.created(location)
.body(created);
}
}Concurrent updates
Two clients may read the same resource and attempt to update it at nearly the same time. Depending on the domain, you may use database transactions, optimistic locking/version fields, conditional requests, pessimistic locks or application-specific conflict handling.
Client A reads version = 8 Client B reads version = 8 Client A updates resource -> version = 9 Client B tries: UPDATE users SET name = 'New Name', version = 9 WHERE id = 42 AND version = 8 0 rows updated -> conflict detected
Timeouts, retries and circuit breakers
Timeout
Retry
Circuit breaker
Retry with exponential backoff
Interview Preparation
Important API interview questions
Use these questions to test whether you understand the concepts rather than only memorizing definitions.
What is an API and why is an API contract important?
What is REST and what makes an API RESTful?
REST vs REST API vs RESTful API — are they exactly the same thing?
What is the difference between URI and URL?
GET vs POST vs PUT vs PATCH?
Why is GET considered safe?
What does idempotent mean?
Is POST idempotent?
Why is DELETE considered idempotent?
What is the difference between 401 and 403?
When should you return 400, 409 or 422?
When should an API return 200 vs 201 vs 202 vs 204?
What are path parameters and query parameters?
Offset pagination vs cursor pagination?
How would you version an API?
What is an idempotency key and why do payment APIs use one?
JWT vs session authentication?
Authentication vs authorization?
OAuth 2.0 vs OpenID Connect?
What is CORS and why does the browser enforce it?
What is a CORS preflight request?
What is rate limiting?
Token bucket vs fixed window vs sliding window?
What does Cache-Control do?
What are ETag and If-None-Match?
What is GraphQL?
GraphQL query vs mutation vs subscription?
REST vs GraphQL — when would you use each?
What is the N+1 problem in GraphQL?
What is an API Gateway?
API Gateway vs Load Balancer?
What are webhooks?
Webhook vs polling?
How do you secure a webhook?
What is OpenAPI?
OpenAPI vs Swagger?
How would you design a production-ready payment API?
How do you safely retry failed API calls?
How do you handle concurrent updates?
How would you observe and debug an API in production?
Revision
Production API design checklist
Final mental model
Good APIs are contracts, not just URLs
A strong API combines clear resource or operation design, predictable request/response contracts, correct transport semantics, authentication, authorization, validation, idempotency, scalability, observability and documentation. REST, GraphQL and gRPC are tools; good engineering comes from understanding the trade-offs and failure modes behind them.
Frequently asked questions
What is an API?
An API is a defined interface that allows software systems to communicate through an agreed contract of operations, inputs, outputs and behavior.
What is a REST API?
A REST API is an API designed around REST architectural ideas, usually exposing resources over HTTP and using standard HTTP semantics.
What is a RESTful API?
RESTful commonly describes an API that follows REST constraints and models interactions consistently around resources.
What is the difference between PUT and PATCH?
PUT conventionally represents replacement of the resource representation, while PATCH applies partial modifications.
What is GraphQL?
GraphQL is a query language and execution model for APIs where a schema defines available types and clients request selected fields.
What is API idempotency?
An operation is idempotent when making the same request repeatedly has the same intended server-side effect as making it once.