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

Last updated:

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)
GET https://api.example.com/users/1
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)
Complete Request
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"
}
Complete Response
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)

GET https://jsonplaceholder.typicode.com/users/1
# 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

POST https://jsonplaceholder.typicode.com/posts
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.

GET

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
POST

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
PUT

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
PATCH

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"}
DELETE

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

200 OK — Request succeeded. The body contains the requested data.
201 Created — Resource was created. The body contains the new resource.
204 No Content — Success, but no body (common for DELETE).

4xx — Client Errors (your mistake)

400 Bad Request — Invalid input. Check the error message for details.
401 Unauthorized — Missing or invalid authentication. Log in first.
403 Forbidden — Authenticated but not allowed. You don't have permission.
404 Not Found — Resource doesn't exist. Check the ID.
429 Too Many Requests — Rate limit hit. Wait and try again.

5xx — Server Errors (their mistake)

500 Internal Server Error — Something broke on the server. Try again later.
503 Service Unavailable — Server is down or overloaded. Try again later.

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

❌ Bad (verb in URL) POST /createUser GET /getUsers
✅ Good (noun + HTTP method) POST /users GET /users

The HTTP method IS the verb. Don't repeat it in the URL.

📂 Collections and Individual Resources

Collection GET /users
Individual resource GET /users/123

Collections use the plural noun. Individual resources add the ID after a slash.

🔗 Nested Resources

Orders for user 123 GET /users/123/orders
Specific order for user 123 GET /users/123/orders/456

Nest resources when one belongs to another. Limit nesting to 2 levels deep.

🔍 Query Parameters for Filtering

Filter + sort + paginate 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: 42 or 3.14 — no quotes
  • Boolean: true or false
  • 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:

GET /api/v1/users
{
  "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.

1

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
2

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...
3

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.

Step 1

HTTP Methods Deep Dive

Learn the nuances of GET, POST, PUT, PATCH, DELETE — safe vs idempotent, request/response formats, and real-world examples.

Step 2

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.

Step 3

Authentication & Security

Implement JWT authentication, OAuth 2.0 flows, and API key management. Protect your API from common security vulnerabilities.

Step 4

Best Practices

API design conventions, error handling patterns, pagination, versioning, and everything you need to build production-quality APIs.

Step 5

Real-World Examples

See complete API implementations for Users, Products, Orders, File Uploads, Authentication, and Webhooks with full request/response examples.

Advanced

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.