Use supporting tools and destination pages to turn an article into a concrete next step.
Practice frameworks, question banks, and checklists in one place.
Test whether your resume matches the role you want.
Review hiring patterns, salary ranges, and work culture.
Read real candidate stories before your next round.
Our blog is written for students, freshers, and early-career professionals. We aim for useful, readable guidance first, but we still expect articles to cite primary regulations, university guidance, or employer-side evidence wherever the advice depends on facts rather than opinion.
Reviewed by
Sproutern Editorial Team
Career editors and quality reviewers working from our public editorial policy
Last reviewed
March 6, 2026
Freshness checks are recorded on pages where the update is material to the reader.
Update cadence
Evergreen articles are reviewed at least quarterly; time-sensitive posts move sooner
Time-sensitive topics move faster when rules, deadlines, or market signals change.
We publish articles only after checking whether the advice depends on a policy, a market signal, or first-hand experience. If a section depends on an official rule, we look for the original source. If it depends on experience, we label it as practical guidance instead of hard fact.
Not every article uses the same dataset, but the editorial expectation is consistent: cite the primary rule, employer guidance, or research owner wherever it materially affects the reader.
Blog articles are expected to cite the original policy, handbook, or employer guidance before we publish practical takeaways.
Used for labor-market, education, and future-of-work context when broader data is needed.
Used for resume, interview, internship, and early-career hiring patterns where employer-side evidence matters.
Added reviewer and methodology disclosure to major blog surfaces
The blog section now clearly shows review context, source expectations, and correction workflow alongside major article experiences.
Reader feedback loop
Writers and editors monitor feedback for factual issues, unclear advice, and stale references that should be refreshed.
Learn REST API fundamentals from scratch. Understand HTTP methods, status codes, authentication, and how to design, consume, and build RESTful APIs step by step.
APIs power the modern internet. Every time you use a mobile app, check the weather, or make an online payment, you're interacting with APIs. Understanding APIs is essential for any developer, and REST is the most common API architecture.
This comprehensive tutorial explains REST APIs from scratch—what they are, how they work, and how to build and consume them.
API (Application Programming Interface) is a way for different software applications to communicate with each other. It defines the rules and protocols for how applications request and exchange data.
Real-World Analogy: Think of a restaurant:
You don't need to know how the kitchen works—the waiter handles the communication.
| Use Case | Example |
|---|---|
| Mobile apps | App fetches data from server |
| Third-party integration | Login with Google |
| Microservices | Services communicate |
| Automation | Scripts interact with systems |
| Data sharing | Weather data for websites |
REST (Representational State Transfer) is an architectural style for designing networked applications. It's not a protocol or standard—it's a set of constraints and principles.
| Principle | Explanation |
|---|---|
| Stateless | Each request contains all info needed; no server-side sessions |
| Client-Server | Separation of concerns; client and server evolve independently |
| Uniform Interface | Standard way to interact with resources |
| Cacheable | Responses can be cached for performance |
| Layered System | Client doesn't know if it's connected to end server or intermediary |
A RESTful API is an API that follows REST principles. It uses:
REST APIs use HTTP methods to indicate the action:
| Method | Action | Example |
|---|---|---|
| GET | Retrieve data | Get all users |
| POST | Create new data | Create a new user |
| PUT | Update/replace data | Update user completely |
| PATCH | Partial update | Update user's email only |
| DELETE | Remove data | Delete a user |
| CRUD | HTTP Method | Example |
|---|---|---|
| Create | POST | POST /users |
| Read | GET | GET /users or GET /users/123 |
| Update | PUT/PATCH | PUT /users/123 |
| Delete | DELETE | DELETE /users/123 |
| Code Range | Category | Common Codes |
|---|---|---|
| 1xx | Informational | 100 Continue |
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirection | 301 Moved, 304 Not Modified |
| 4xx | Client Error | 400 Bad Request, 401 Unauthorized, 404 Not Found |
| 5xx | Server Error | 500 Internal Error, 503 Service Unavailable |
Common Status Codes:
| Code | Meaning | When Used |
|---|---|---|
| 200 | OK | Successful GET, PUT |
| 201 | Created | Successful POST (new resource) |
| 204 | No Content | Successful DELETE |
| 400 | Bad Request | Invalid request data |
| 401 | Unauthorized | Authentication required |
| 403 | Forbidden | Not allowed even with auth |
| 404 | Not Found | Resource doesn't exist |
| 500 | Server Error | Something broke on server |
RESTful URLs are resource-based:
https://api.example.com/v1/users/123/orders
Breakdown:
https:// - Protocolapi.example.com - Domain/v1 - API version/users - Resource (collection)/123 - Resource ID (specific user)/orders - Sub-resource (user's orders)| Good ✓ | Bad ✗ |
|---|---|
/users | /getUsers |
/users/123 | /user?id=123 |
/users/123/orders | /getUserOrders |
/products | /product-list |
Rules:
GET Request (Retrieve):
GET /api/users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer <token>
Accept: application/json
POST Request (Create):
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "John Doe",
"email": "john@example.com",
"age": 25
}
Success Response:
{
"status": "success",
"data": {
"id": 123,
"name": "John Doe",
"email": "john@example.com",
"age": 25,
"created_at": "2024-01-15T10:30:00Z"
}
}
Error Response:
{
"status": "error",
"message": "User not found",
"code": "USER_NOT_FOUND"
}
Most common format for REST APIs:
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"roles": ["user", "admin"],
"profile": {
"bio": "Developer",
"location": "India"
},
"active": true
}
JSON Data Types: | Type | Example | |------|---------| | String | "hello" | | Number | 42,
3.14 | | Boolean | true, false | | Null | null | | Array | [1, 2, 3] | | Object |
{"key": "value"} |
Common HTTP headers:
| Header | Purpose | Example |
|---|---|---|
Content-Type | Format of request body | application/json |
Accept | Expected response format | application/json |
Authorization | Authentication | Bearer token123 |
Cache-Control | Caching behavior | no-cache |
GET Request:
fetch('https://api.example.com/users')
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error('Error:', error));
With async/await:
async function getUsers() {
try {
const response = await fetch('https://api.example.com/users');
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
POST Request:
async function createUser(userData) {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer token123',
},
body: JSON.stringify(userData),
});
return response.json();
}
// Usage
createUser({ name: 'John', email: 'john@example.com' });
GET Request:
import requests
response = requests.get('https://api.example.com/users')
data = response.json()
print(data)
POST Request:
import requests
user_data = {
'name': 'John',
'email': 'john@example.com'
}
response = requests.post(
'https://api.example.com/users',
json=user_data,
headers={'Authorization': 'Bearer token123'}
)
print(response.status_code)
print(response.json())
GET:
curl https://api.example.com/users
POST:
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
Setup:
npm init -y
npm install express
Basic API:
const express = require('express');
const app = express();
app.use(express.json());
// In-memory data store
let users = [
{ id: 1, name: 'John', email: 'john@example.com' },
{ id: 2, name: 'Jane', email: 'jane@example.com' },
];
// GET all users
app.get('/api/users', (req, res) => {
res.json(users);
});
// GET single user
app.get('/api/users/:id', (req, res) => {
const user = users.find((u) => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.json(user);
});
// POST create user
app.post('/api/users', (req, res) => {
const user = {
id: users.length + 1,
name: req.body.name,
email: req.body.email,
};
users.push(user);
res.status(201).json(user);
});
// PUT update user
app.put('/api/users/:id', (req, res) => {
const user = users.find((u) => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
user.name = req.body.name;
user.email = req.body.email;
res.json(user);
});
// DELETE user
app.delete('/api/users/:id', (req, res) => {
const index = users.findIndex((u) => u.id === parseInt(req.params.id));
if (index === -1) {
return res.status(404).json({ message: 'User not found' });
}
users.splice(index, 1);
res.status(204).send();
});
app.listen(3000, () => console.log('Server running on port 3000'));
from flask import Flask, jsonify, request
app = Flask(__name__)
users = [
{'id': 1, 'name': 'John', 'email': 'john@example.com'},
{'id': 2, 'name': 'Jane', 'email': 'jane@example.com'}
]
@app.route('/api/users', methods=['GET'])
def get_users():
return jsonify(users)
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
user = next((u for u in users if u['id'] == user_id), None)
if not user:
return jsonify({'message': 'User not found'}), 404
return jsonify(user)
@app.route('/api/users', methods=['POST'])
def create_user():
user = {
'id': len(users) + 1,
'name': request.json['name'],
'email': request.json['email']
}
users.append(user)
return jsonify(user), 201
if __name__ == '__main__':
app.run(debug=True)
| Method | How It Works | Use Case |
|---|---|---|
| API Key | Static key in header/query | Simple apps |
| Basic Auth | Base64-encoded username:password | Simple, internal |
| Bearer Token | Token in Authorization header | Common for apps |
| OAuth 2.0 | Token-based, refresh tokens | Third-party auth |
| JWT | Self-contained JSON tokens | Stateless auth |
Request:
GET /api/data HTTP/1.1
X-API-Key: your-api-key-here
Request:
GET /api/users HTTP/1.1
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
JWT is a self-contained token with three parts:
header.payload.signature
Example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4iLCJpYXQiOjE1MTYyMzkwMjJ9.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
| Practice | Good Example |
|---|---|
| Use plural nouns | /users, /products |
| Nest related resources | /users/123/orders |
| Use query params for filtering | /users?role=admin |
| Version your API | /v1/users |
| Keep URLs simple | /orders/123 not /getOrderById?id=123 |
{
"status": "success",
"data": {
"users": [...],
"pagination": {
"page": 1,
"per_page": 20,
"total": 100,
"total_pages": 5
}
}
}
{
"status": "error",
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"errors": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
Query Parameters:
GET /api/users?page=2&per_page=20
Response:
{
"data": [...],
"pagination": {
"page": 2,
"per_page": 20,
"total_items": 100,
"total_pages": 5
}
}
GET /api/products?category=electronics&price_min=1000&sort=price_desc
| Tool | Type | Best For |
|---|---|---|
| Postman | GUI | Visual testing, collections |
| Insomnia | GUI | Clean interface |
| cURL | CLI | Quick tests, scripting |
| Swagger UI | Web | Documentation + testing |
| HTTPie | CLI | Human-friendly cURL alternative |
JavaScript (Jest + Supertest):
const request = require('supertest');
const app = require('./app');
describe('Users API', () => {
it('should get all users', async () => {
const res = await request(app).get('/api/users');
expect(res.statusCode).toBe(200);
expect(res.body).toBeInstanceOf(Array);
});
it('should create a user', async () => {
const res = await request(app)
.post('/api/users')
.send({ name: 'Test', email: 'test@test.com' });
expect(res.statusCode).toBe(201);
expect(res.body.name).toBe('Test');
});
});
| API | Purpose | Auth |
|---|---|---|
| JSONPlaceholder | Fake REST API | None |
| GitHub API | GitHub data | OAuth/Token |
| OpenWeatherMap | Weather data | API Key |
| REST Countries | Country info | None |
| PokeAPI | Pokémon data | None |
| The Movie DB | Movie data | API Key |
REST uses multiple endpoints for different resources. GraphQL uses one endpoint where clients specify exactly what data they need. REST is simpler; GraphQL is more flexible for complex queries.
No. REST is an architectural style, HTTP is a protocol. REST commonly uses HTTP, but REST principles could theoretically apply to other protocols.
Use HTTPS, implement authentication (JWT/OAuth), validate inputs, rate limit requests, and use proper authorization for each endpoint.
PUT replaces the entire resource. PATCH updates only specified fields. Use PUT when updating everything, PATCH for partial updates.
Common methods: URL path (/v1/users), header (Accept-Version: v1), or query param (?version=1). URL path is most common and visible.
Learning backend development? Explore more resources on Sproutern for programming tutorials, career guidance, and skill development.
This article was last reviewed and updated on February 23, 2026. Source: Sproutern Career Research Team.
Our team of career experts, industry professionals, and former recruiters brings decades of combined experience in helping students and freshers launch successful careers.
Get 50+ real interview questions from top MNCs, ATS-optimized resume templates, and a step-by-step placement checklist — delivered to your inbox.
🔒 No spam. We respect your privacy.
Discover the best programming languages to learn for career growth and high-paying tech jobs....
Master Data Structures and Algorithms with this complete roadmap. From arrays to dynamic programming...
If you found this article helpful, please cite it as: