API Design & Development: 0 to 100
A comprehensive guide to understanding, designing, and building APIs, from basic concepts to a full-scale Spotify-like system.
1. Fundamentals
What is an API?
API (Application Programming Interface) is a set of rules that allows different software entities to communicate with each other. It acts as a contract between a Client (who requests data) and a Server (who provides data).
Client-Server Architecture
- Client: The frontend (Browser, Mobile App) or another service holding the interface.
- Server: The backend system that processes requests, talks to the database, and sends responses.
- Database: Stores the persistent data (Users, Songs, Playlists).
HTTP Basics
APIs typically operate over HTTP (Hypertext Transfer Protocol).
- Request: Sent by the client (contains Method, URL, Headers, Body).
- Response: Sent by the server (contains Status Code, Headers, Body).
Common HTTP Methods
| Method | Description | Safe? | Idempotent? |
|---|---|---|---|
| GET | Retrieve a resource. Should not modify data. | âś… | âś… |
| POST | Create a new resource. | ❌ | ❌ |
| PUT | Update/Replace an existing resource entirely. | ❌ | ✅ |
| PATCH | Partially update a resource. | ❌ | ❌ |
| DELETE | Remove a resource. | ❌ | ✅ |
HTTP Status Codes (The “Traffic Lights”)
- 2xx Success:
200 OK: Standard success.201 Created: Resource created successfully.
- 3xx Redirection:
301 Moved Permanently: Resource has a new URL.
- 4xx Client Error:
400 Bad Request: Invalid input.401 Unauthorized: Authentication required.403 Forbidden: Authenticated, but no permission.404 Not Found: Resource doesn’t exist.
- 5xx Server Error:
500 Internal Server Error: The server crashed or failed.
2. REST Architecture
REST (Representational State Transfer) is the most popular architectural style for web APIs.
Key Principles
- Stateless: The server doesn’t “remember” the client state between requests. Every request must contain all necessary info (e.g., auth tokens).
- Resource-Based: Everything is a “Resource” identified by a URI (Uniform Resource Identifier).
- Uniform Interface: Consistent usage of HTTP methods (GET for reading, POST for creating).
Naming Conventions (Best Practices)
- Use Nouns, not Verbs.
- Use Plurals for collections.
- Use Lower-case with hyphens for readability.
âś… Good:
GET /users(Get all users)GET /users/123(Get user with ID 123)POST /songs(Add a new song)DELETE /playlists/456(Delete playlist 456)
❌ Bad:
GET /getUsers(RPC style, avoid)POST /createSong(Verbs are redundant with HTTP methods)GET /users/123/songs(Good: Sub-resources)
3. Implementation: Building a Simple API
We’ll use Node.js and Express due to their simplicity and popularity.
Setup
- Initialize project:
npm init -y - Install Express:
npm install express
Basic Server Code (server.js)
const express = require('express');
const app = express();
const port = 3000;
// Middleware to parse JSON bodies
app.use(express.json());
// 1. GET Request
app.get('/api/health', (req, res) => {
res.status(200).json({ status: 'OK', message: 'Server is running' });
});
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
4. Case Study: Spotify Clone API
Let’s design a backend for a streaming service.
Requirements
- Browse Music: songs, albums, artists.
- Manage Playlists: create playlists, add/remove songs.
- User Profiles: follow artists, like songs.
Data Model (JSON Structure)
Song Resource
{
"id": "s101",
"title": "Bohemian Rhapsody",
"artist_id": "a001",
"album_id": "al01",
"duration_ms": 354000,
"streams": 1500000000
}
Playlist Resource
{
"id": "p505",
"name": "Rock Classics",
"owner_id": "u99",
"tracks": ["s101", "s102", "s105"],
"is_private": false
}
Endpoints Design
1. Songs & Albums
GET /songs-> List songs (supports pagination/search like?q=queen).GET /songs/:id-> Get details for a song.GET /artists/:id/albums-> Get albums by an artist.
2. User Actions
POST /users/:id/likes-> Like a song (Body:{ "song_id": "s101" }).DELETE /users/:id/likes/:song_id-> Unlike a song.
3. Playlists (Complex Logic)
POST /playlists-> Create new playlist.GET /playlists/:id-> View playlist.POST /playlists/:id/tracks-> Add song to playlist.- Check: Does playlist exist? Is user the owner? Does song exist?
DELETE /playlists/:id/tracks/:song_id-> Remove song.
Implementation Snippet
Adding a Song to a Playlist
// Mock Database
const playlists = [
{ id: 'p1', name: 'My Jams', tracks: [] }
];
app.post('/playlists/:id/tracks', (req, res) => {
const { id } = req.params;
const { song_id } = req.body;
// 1. Find Playlist
const playlist = playlists.find(p => p.id === id);
if (!playlist) {
return res.status(404).json({ error: 'Playlist not found' });
}
// 2. Add Song (Validation logic skipped for brevity)
playlist.tracks.push(song_id);
// 3. respond
res.status(201).json({
message: 'Track added successfully',
playlist: playlist
});
});
5. Advanced Topics
Authentication vs Authorization
- Authentication (AuthN): Who are you? (e.g., Login with Email/Password -> Receive JWT).
- Authorization (AuthZ): What can you do? (e.g., Admin vs User).
Status Codes for Auth
- 401 Unauthorized: “I don’t know who you are.” (Missing/Invalid Token).
- 403 Forbidden: “I know who you are, but you can’t do this.” (Scope mismatch).
Pagination
Crucial for endpoints returning lists (like /songs).
- Limit/Offset:
GET /songs?limit=20&offset=0 - Cursor-based:
GET /songs?limit=20&after_id=s100(Better for infinite scroll).
Rate Limiting
Prevent abuse by limiting requests per IP/User (e.g., 100 req/min). Returns 429 Too Many Requests.
| Back to Top | Home |