
Python
REST (Representational State Transfer) APIs are the standard way applications communicate over the internet. They use HTTP to exchange data in a predictable, stateless manner. Understanding REST is essential for building modern web applications and integrating with external services.
A REST API is a set of rules that allows different applications to talk to each other over the web. It uses standard HTTP methods (GET, POST, PUT, DELETE) to perform operations on resources (data). Think of it like a menu at a restaurant — you make requests to the server, and it responds with the data you asked for.
import requests
# Making a simple GET request to a REST API
response = requests.get('https://jsonplaceholder.typicode.com/posts/1')
print(response.json()) # Print the response as JSON
# Output:
# {
# "userId": 1,
# "id": 1,
# "title": "sunt aut facere repellat provident...",
# "body": "quia et suscipit..."
# }REST APIs follow six architectural principles that make them reliable and scalable:
The client and server are separate entities that communicate through standardized interfaces. The client requests data, and the server provides it.
# Client-side code
import requests
# Client asks for data from the server
response = requests.get('https://api.example.com/users/123')
user_data = response.json()
print(f"User: {user_data['name']}")Each request contains all the information needed to understand and process it. The server doesn't store client context between requests.
# Each request is independent - no session state stored on server
# Request 1
response1 = requests.get('https://api.example.com/users/1')
# Request 2 - server doesn't remember Request 1
response2 = requests.get('https://api.example.com/users/1')All REST APIs use consistent, standardized methods and naming conventions that work the same way across different APIs.
# Standard uniform interface using HTTP methods
requests.get('https://api.example.com/users') # Retrieve users
requests.post('https://api.example.com/users') # Create user
requests.put('https://api.example.com/users/1') # Update user
requests.delete('https://api.example.com/users/1') # Delete userEverything in REST is a "resource" identified by a unique URL. Resources are nouns (users, posts, comments), not verbs (create, update).
# Resource-based URLs (correct REST style)
# /users → collection of users
# /users/1 → specific user with ID 1
# /users/1/posts → posts by user 1
response = requests.get('https://api.example.com/users/1')
response = requests.get('https://api.example.com/users/1/posts')
response = requests.get('https://api.example.com/posts/42')Responses can be cached to improve performance and reduce server load.
# This response can be cached by the browser/client
response = requests.get('https://api.example.com/users/1')
print(response.headers.get('Cache-Control')) # May return: max-age=3600Clients don't know if they're connected directly to the end server. There can be multiple layers (load balancers, caches, proxies) between them.
# You don't need to know the server architecture
# It might go through: Client → Load Balancer → Cache → API Server
response = requests.get('https://api.example.com/users')
# Still works the same from the client perspectiveREST APIs use standard HTTP methods to specify what action to perform on a resource:
Safe and idempotent. Doesn't change anything on the server.
# Get a list of all users
all_users = requests.get('https://api.example.com/users')
print(all_users.json())
# Get a specific user
user = requests.get('https://api.example.com/users/5')
print(user.json())
# Get with parameters
params = {'page': 2, 'limit': 10}
users_page_2 = requests.get('https://api.example.com/users', params=params)
print(users_page_2.json())Creates a new resource on the server.
# Create a new user
new_user = {
'name': 'John Doe',
'email': 'john@example.com',
'age': 28
}
response = requests.post('https://api.example.com/users', json=new_user)
created_user = response.json()
print(f"Created user with ID: {created_user['id']}")Replaces an entire resource with new data.
# Update user 5 completely
updated_data = {
'name': 'Jane Doe',
'email': 'jane@example.com',
'age': 30
}
response = requests.put('https://api.example.com/users/5', json=updated_data)
print(response.json())Deletes a resource from the server.
# Delete user with ID 5
response = requests.delete('https://api.example.com/users/5')
if response.status_code == 204: # 204 = No Content (success)
print("User deleted successfully")REST APIs typically return data in a consistent structure. Here are common patterns:
import requests
# Example 1: Single Resource Response
response = requests.get('https://jsonplaceholder.typicode.com/users/1')
user = response.json()
print(user)
# Output:
# {
# "id": 1,
# "name": "Leanne Graham",
# "email": "Sincere@april.biz",
# "address": {...},
# "phone": "1-770-736-8031",
# "website": "hildegard.org"
# }
# Example 2: Collection Response
response = requests.get('https://jsonplaceholder.typicode.com/users?_limit=2')
users = response.json()
print(users)
# Output: [
# {"id": 1, "name": "Leanne Graham", ...},
# {"id": 2, "name": "Ervin Howell", ...}
# ]
# Example 3: Response with Meta Information
response = requests.get('https://api.example.com/users')
data = response.json()
print(data)
# Output:
# {
# "data": [...users...],
# "meta": {
# "total": 100,
# "page": 1,
# "per_page": 10
# }
# }Understanding the architecture helps you work with any REST API:
# Complete example showing the architecture
import requests
from typing import Dict, List
class UserAPI:
"""Simple REST API client for user management"""
def __init__(self, base_url: str = 'https://api.example.com'):
self.base_url = base_url
def get_all_users(self) -> List[Dict]:
"""GET /users - Retrieve all users"""
response = requests.get(f'{self.base_url}/users')
return response.json()
def get_user(self, user_id: int) -> Dict:
"""GET /users/{id} - Retrieve specific user"""
response = requests.get(f'{self.base_url}/users/{user_id}')
return response.json()
def create_user(self, name: str, email: str) -> Dict:
"""POST /users - Create new user"""
data = {'name': name, 'email': email}
response = requests.post(f'{self.base_url}/users', json=data)
return response.json()
def update_user(self, user_id: int, name: str, email: str) -> Dict:
"""PUT /users/{id} - Update entire user"""
data = {'name': name, 'email': email}
response = requests.put(f'{self.base_url}/users/{user_id}', json=data)
return response.json()
def delete_user(self, user_id: int) -> bool:
"""DELETE /users/{id} - Delete user"""
response = requests.delete(f'{self.base_url}/users/{user_id}')
return response.status_code == 204
# Using the API client
api = UserAPI()
all_users = api.get_all_users()
user_1 = api.get_user(1)
new_user = api.create_user('Alice', 'alice@example.com')Try these free public APIs to understand REST in practice:
# JSONPlaceholder - Fake JSON API for testing
response = requests.get('https://jsonplaceholder.typicode.com/posts')
posts = response.json()
print(f"Retrieved {len(posts)} posts")
# OpenWeatherMap - Real weather data
weather = requests.get(
'https://api.openweathermap.org/data/2.5/weather',
params={'q': 'London', 'appid': 'YOUR_API_KEY'}
)
print(weather.json())
# GitHub API - No authentication needed for basic queries
github = requests.get('https://api.github.com/users/octocat')
user = github.json()
print(f"GitHub user: {user['login']}")| Concept | Remember |
|---|---|
| REST API | Set of rules for communication between applications using HTTP |
| Resources | Everything is a resource identified by unique URLs (nouns, not verbs) |
| HTTP Methods | GET (read), POST (create), PUT (update), DELETE (remove) |
| Stateless | Each request contains all needed info; server doesn't store client context |
| Responses | Usually return JSON data with status codes indicating success/failure |
| Client-Server | Client requests, server responds; they work independently |
Now that you understand REST API basics, let's explore HTTP requests in detail to master how data travels across the web.
Ready to practice? Try challenges or explore resources
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep • Build Real • Verify Skills • Launch Forward