Web MobileIntermediate16 min readUpdated March 2025
Building REST APIs with FastAPI
Build a validated, documented REST API in Python with FastAPI, then call it from JavaScript. Covers models, CRUD routes, status codes and CORS.
REST Principles
A REST API exposes resources as URLs and uses HTTP methods to act on them:
- GET `/tasks` — list tasks
- POST `/tasks` — create a task
- GET `/tasks/{id}` — read one task
- PUT `/tasks/{id}` — update a task
- DELETE `/tasks/{id}` — remove a task
A Complete FastAPI Service
FastAPI uses Python type hints and Pydantic models to validate input automatically and generate interactive docs at `/docs`. Run with `uvicorn main:app --reload`.
python
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel, Field
app = FastAPI(title="Tasks API")
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["*"],
allow_headers=["*"],
)
class TaskIn(BaseModel):
title: str = Field(min_length=1, max_length=120)
done: bool = False
class Task(TaskIn):
id: int
db: dict[int, Task] = {}
next_id = 1
@app.get("/tasks", response_model=list[Task])
def list_tasks():
return list(db.values())
@app.post("/tasks", response_model=Task, status_code=201)
def create_task(payload: TaskIn):
global next_id
task = Task(id=next_id, **payload.model_dump())
db[next_id] = task
next_id += 1
return task
@app.get("/tasks/{task_id}", response_model=Task)
def get_task(task_id: int):
if task_id not in db:
raise HTTPException(status_code=404, detail="Task not found")
return db[task_id]
@app.delete("/tasks/{task_id}", status_code=204)
def delete_task(task_id: int):
if db.pop(task_id, None) is None:
raise HTTPException(status_code=404, detail="Task not found")Calling the API from JavaScript
A small client wrapper keeps error handling in one place:
javascript
const API = "http://localhost:8000";
async function request(path, options = {}) {
const res = await fetch(`${API}${path}`, {
headers: { "Content-Type": "application/json" },
...options,
});
if (!res.ok) {
const detail = await res.json().catch(() => ({}));
throw new Error(detail.detail || `HTTP ${res.status}`);
}
return res.status === 204 ? null : res.json();
}
export const createTask = (title) =>
request("/tasks", { method: "POST", body: JSON.stringify({ title }) });
export const listTasks = () => request("/tasks");
const task = await createTask("Write docs");
console.log(task, await listTasks());Status Codes to Know
Return meaningful codes so clients can react correctly:
- 200 OK, 201 Created, 204 No Content
- 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 422 Validation Error
- 500 Internal Server Error
Key Takeaways
- REST maps resources to URLs and actions to HTTP methods.
- FastAPI validates input with type hints and generates docs automatically.
- Configure CORS explicitly for browser clients.
- Return accurate status codes and consistent error bodies.
Contact Us
Have a question or feedback? Fill out the form below or reach us directly at support@nvaitraining.com