REST API Tutorial: Complete Guide for Beginners
Learn REST APIs from scratch — what they are, how they work, and how to use them with real code examples
What is a REST API?
A REST API (Representational State Transfer Application Programming Interface) is a standardized way for applications to communicate over the internet. When you check the weather on your phone, book a flight, or log into a website, your app is almost certainly talking to a REST API behind the scenes.
REST was defined by Roy Fielding in his 2000 doctoral dissertation. It became the dominant style for web APIs because it builds on existing web infrastructure (HTTP) and is simple to understand and implement.
The Restaurant Analogy
Think of a REST API like a restaurant:
- Menu = API Documentation: lists what you can order (available endpoints)
- Your order = HTTP Request: what you want and how you want it
- Waiter = API: takes your request to the kitchen and brings back the food
- Kitchen = Server/Database: does the actual work
- Food = HTTP Response: what you get back (usually JSON data)
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 1,
"name": "Jane Doe",
"email": "jane@example.com",
"role": "admin",
"created_at": "2026-01-15T10:30:00Z"
}
The 6 REST Constraints
Client-Server
The client (your app) and server (the API) are separate. The client doesn't need to know how data is stored; the server doesn't need to know how the UI works.
Stateless
Each request contains all information needed to process it. The server stores no client session state. This makes APIs easier to scale.
Cacheable
Responses can be cached by clients, CDNs, and proxies to improve performance. The server indicates what can be cached using HTTP headers.
Uniform Interface
All resources are accessed the same way using standard HTTP methods and URLs. This consistency is what makes REST APIs predictable.
Layered System
The API can have multiple layers (load balancers, caches, security gateways) that the client doesn't need to know about.
Code on Demand (Optional)
Servers can optionally send executable code to clients. Rarely used in practice, but allowed by the REST specification.
How REST APIs Work: Request & Response
Every REST API interaction is a request-response cycle. Your application sends an HTTP request; the API sends back an HTTP response.
Anatomy of an HTTP Request
- Method: what action to perform (GET, POST, PUT, DELETE)
- URL: which resource to act on (
/api/v1/users/123) - Headers: metadata about the request (Content-Type, Authorization, Accept)
- Body: data to send with POST, PUT, PATCH requests (usually JSON)
Anatomy of an HTTP Response
- Status code: did it succeed? (200 OK, 404 Not Found, 500 Error)
- Headers: metadata (Content-Type, Cache-Control, rate limit info)
- Body: the actual data returned (JSON in most REST APIs)
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGci...
Accept: application/json
{
"name": "John Doe",
"email": "john@example.com"
}
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/124
{
"id": 124,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2026-03-24T10:30:00Z"
}
Your First REST API Call
Let's make a real API call right now. We'll use JSONPlaceholder — a free public API for testing that returns fake but realistic data.
Try it with curl (Terminal)
# Run this in your terminal:
curl https://jsonplaceholder.typicode.com/users/1
# Expected response:
{
"id": 1,
"name": "Leanne Graham",
"username": "Bret",
"email": "Sincere@april.biz",
"address": {
"street": "Kulas Light",
"city": "Gwenborough",
"zipcode": "92998-3874"
},
"phone": "1-770-736-0988 x56442",
"website": "hildegard.org"
}
Try it with JavaScript fetch
// Works in any browser console or Node.js:
fetch('https://jsonplaceholder.typicode.com/users/1')
.then(response => {
console.log('Status:', response.status); // 200
return response.json();
})
.then(data => {
console.log('User:', data.name); // "Leanne Graham"
console.log('Email:', data.email);
})
.catch(error => {
console.error('Error:', error);
});
// Or with async/await (modern JavaScript):
async function getUser(id) {
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${id}`
);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const user = await response.json();
return user;
}
const user = await getUser(1);
console.log(user.name);
Create a Resource with POST
curl -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{
"title": "My First Post",
"body": "This is the post content",
"userId": 1
}'
# Response (201 Created):
{
"id": 101,
"title": "My First Post",
"body": "This is the post content",
"userId": 1
}
HTTP Methods — The REST Verbs
HTTP methods tell the server what action to perform. Each method has a specific purpose — using the right method makes your API predictable and follows REST conventions.
Read Data
Retrieve a resource or collection. Safe (no side effects) and idempotent (calling it multiple times returns the same result).
GET /api/users
GET /api/users/123
Create Data
Create a new resource. Returns 201 Created with the new resource in the body and a Location header pointing to it.
POST /api/users
POST /api/orders
Replace/Update
Replace a resource entirely (all fields). Idempotent — calling it multiple times produces the same result. Requires you to send the complete resource.
PUT /api/users/123
Partial Update
Update only the fields you specify. More efficient than PUT when you only need to change one or two fields.
PATCH /api/users/123
{"name": "New Name"}
Remove Data
Delete a resource. Returns 204 No Content on success (no body). Idempotent — deleting an already-deleted resource should also return a success response.
DELETE /api/users/123
💡 The Golden Rule of HTTP Methods
Use the method that matches your intent. The most common mistake is using POST for everything. If you're reading data, use GET. If you're removing data, use DELETE. This makes your API self-documenting and predictable.
See our complete HTTP Methods guide for detailed examples of each method.
HTTP Status Codes — What Responses Mean
Status codes tell you whether a request succeeded or failed — and why. Always check the status code before reading the response body.
2xx — Success
4xx — Client Errors (your mistake)
5xx — Server Errors (their mistake)
See our complete Status Codes reference for all HTTP codes with examples.
REST API Resources and URLs
In REST, everything is a resource — any noun that your application manages: users, orders, products, articles. Resources are identified by URLs (Uniform Resource Locators).
📚 Use Nouns, Not Verbs
POST /createUser
GET /getUsers
POST /users
GET /users
The HTTP method IS the verb. Don't repeat it in the URL.
📂 Collections and Individual Resources
GET /users
GET /users/123
Collections use the plural noun. Individual resources add the ID after a slash.
🔗 Nested Resources
GET /users/123/orders
GET /users/123/orders/456
Nest resources when one belongs to another. Limit nesting to 2 levels deep.
🔍 Query Parameters for Filtering
GET /users?status=active&sort=name&page=2
Use query parameters for filtering, sorting, searching, and pagination. Never put filter logic in the URL path.
Working with JSON
JSON (JavaScript Object Notation) is the standard data format for REST APIs. It's human-readable, lightweight, and supported natively in JavaScript and most programming languages.
JSON Data Types
- String:
"Hello World"— text in double quotes - Number:
42or3.14— no quotes - Boolean:
trueorfalse - Null:
null— explicit absence of value - Array:
[1, 2, 3]or["a", "b"] - Object:
{"key": "value"}— key-value pairs
Standard Response Envelope
Many APIs use a consistent "envelope" structure to wrap all responses:
{
"data": [
{"id": 1, "name": "Jane"},
{"id": 2, "name": "John"}
],
"meta": {
"total": 150,
"page": 1,
"per_page": 10
},
"links": {
"next": "/api/v1/users?page=2",
"prev": null
}
}
Parsing JSON in JavaScript
// Making an API request and handling JSON:
async function fetchUsers() {
const response = await fetch('/api/v1/users', {
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Accept': 'application/json'
}
});
// Always check for errors before parsing
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Request failed');
}
const data = await response.json();
console.log('Users:', data.data); // the array of users
console.log('Total:', data.meta.total);
return data.data;
}
// Sending JSON data (POST/PUT/PATCH):
async function createUser(userData) {
const response = await fetch('/api/v1/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // Required!
'Authorization': 'Bearer YOUR_TOKEN'
},
body: JSON.stringify(userData) // Convert object to JSON string
});
if (response.status === 201) {
const newUser = await response.json();
return newUser.data;
}
}
Authentication Basics
Most REST APIs require authentication — a way to prove who you are. Without it, anyone could read or modify any data. There are three main approaches.
API Keys — Simplest
A static secret string assigned to your application. Send it with every request. Simple to implement, best for server-to-server calls.
# In a header (preferred):
Authorization: Bearer sk_live_abc123xyz
# Never in the URL:
# ❌ /api/users?api_key=sk_live_abc123xyz
JWT Tokens — Most Common
JSON Web Tokens. After logging in, you receive a token that expires. Send it with each request. The server verifies it without a database lookup.
# Login to get a token:
POST /api/auth/login
{"email": "you@example.com", "password": "..."}
# Response:
{"access_token": "eyJhbGci...", "expires_in": 3600}
# Use the token:
Authorization: Bearer eyJhbGci...
OAuth 2.0 — Most Powerful
The industry standard for "Login with Google/GitHub" type flows. Allows users to grant your app limited access to their data on another service.
scope: read:users email profile
Used by Google, GitHub, Stripe, Slack, and virtually every major API.
See our complete Authentication guide for implementation details and security best practices.
REST API Design Principles
These core principles make REST APIs consistent, predictable, and easy to use. Whether you're building or consuming an API, understanding these principles helps.
Stateless Requests
Every request must include all information needed to process it. The server never remembers anything between requests — no server-side sessions.
Use HTTP Correctly
GET for reading, POST for creating, PUT/PATCH for updating, DELETE for removing. Use the right status codes: 200, 201, 204, 400, 401, 403, 404.
Version Your API
Include a version in your URL: /api/v1/users. This lets you make breaking changes in v2 without breaking clients on v1.
Consistent Naming
Use lowercase, hyphens for URLs (/user-profiles). Use consistent casing for JSON keys — choose camelCase or snake_case and stick to it.
Ready to design your own API? Read our REST API Design Guide for comprehensive best practices.
Next Steps: Your Learning Path
You now understand the fundamentals of REST APIs. Here's the recommended learning path to go deeper.
HTTP Methods Deep Dive
Learn the nuances of GET, POST, PUT, PATCH, DELETE — safe vs idempotent, request/response formats, and real-world examples.
Status Codes Reference
Master all HTTP status codes: when to use 201 vs 200, 422 vs 400, 401 vs 403, and how to handle each on the client side.
Authentication & Security
Implement JWT authentication, OAuth 2.0 flows, and API key management. Protect your API from common security vulnerabilities.
Best Practices
API design conventions, error handling patterns, pagination, versioning, and everything you need to build production-quality APIs.
Real-World Examples
See complete API implementations for Users, Products, Orders, File Uploads, Authentication, and Webhooks with full request/response examples.
Design Guide
The complete reference for building production-ready REST APIs: URL design, response structure, versioning, security, and the full design checklist.
Frequently Asked Questions
What is a REST API?
A REST API (Representational State Transfer API) is a standardized way for applications to communicate over HTTP. It uses standard HTTP methods (GET, POST, PUT, DELETE) to perform operations on resources identified by URLs, and returns data — usually in JSON format. REST is the dominant API style for web services today, used by companies like Twitter, Stripe, GitHub, and Google.
What is the difference between REST and RESTful?
REST is the architectural style defined by Roy Fielding in 2000. A RESTful API is one that follows the REST constraints: stateless, client-server, cacheable, uniform interface, layered system, and optional code on demand. In practice, the terms are used interchangeably — when someone says "REST API," they usually mean a RESTful API.
What format does a REST API use?
REST APIs can technically use any format, but JSON (JavaScript Object Notation) has become the standard. JSON is lightweight, human-readable, and natively supported in JavaScript. Older APIs sometimes use XML, and some specialized APIs use Protocol Buffers (gRPC), but for most modern REST APIs, assume JSON.
How is a REST API different from GraphQL?
REST APIs have multiple endpoints, each returning a fixed data structure. GraphQL has a single endpoint where the client specifies exactly what data it wants. REST is simpler and more widely supported. GraphQL is better for complex, nested data requirements and when you need to minimize over-fetching. See our REST vs GraphQL guide for a detailed comparison.