Follow AiTechWorlds on LinkedIn for professional AI content!Follow Now →

FastAPI Tutorial: Building Your First REST API in 30 Minutes

A hands-on FastAPI tutorial for beginners: build a fully functional REST API in 30 minutes with CRUD endpoints, request validation, and automatic docs.

A
AiTechWorlds Team
May 27, 2026 7 min read
📱

Get more content like this on Telegram!

Daily AI tips, notes & resources — free

Join Free →

FastAPI Tutorial: Building Your First REST API in 30 Minutes

When I discovered FastAPI after months of Flask and Django, my first reaction was "why didn't I start here?"

FastAPI does something no other Python framework does as well: it makes building an API feel effortless without hiding what's happening. You write Python functions. You add type hints. FastAPI turns those into a fully documented, validated API automatically.

This tutorial will have you running a real REST API with full documentation in 30 minutes. No prior API experience needed — just Python fundamentals.


What We're Building

A task management API with full CRUD operations:

  • GET /tasks — list all tasks
  • POST /tasks — create a task
  • GET /tasks/{id} — get one task
  • PUT /tasks/{id} — update a task
  • DELETE /tasks/{id} — delete a task

By the end, you'll have an API running with automatic documentation at /docs. You can test every endpoint without writing any frontend code.


Setup (5 Minutes)

1. Create a virtual environment

mkdir task-api
cd task-api
python -m venv venv
source venv/bin/activate  # Mac/Linux
# OR
venv\Scripts\activate  # Windows

2. Install FastAPI

pip install fastapi uvicorn

That's it. No database setup yet — we'll start with in-memory storage so nothing gets in the way of learning the API concepts.

3. Create main.py

Create a file called main.py in your project folder. This is where everything goes.


Your First FastAPI Endpoint (5 Minutes)

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Task API is running"}

Run it:

uvicorn main:app --reload

Open http://localhost:8000 — you should see {"message": "Task API is running"}.

Open http://localhost:8000/docs — you'll see the Swagger UI showing your endpoint, completely automatically generated. This is one of FastAPI's best features.

What just happened: @app.get("/") is a decorator that registers the function as a GET endpoint at the "/" path. The function returns a Python dict; FastAPI converts it to JSON automatically.


Adding Data Models with Pydantic (5 Minutes)

FastAPI uses Pydantic for data validation. You define the shape of your data as a class, and FastAPI validates all incoming requests against it automatically.

from fastapi import FastAPI
from pydantic import BaseModel
from typing import Optional
from datetime import datetime

app = FastAPI()

class Task(BaseModel):
    id: int
    title: str
    description: Optional[str] = None
    completed: bool = False
    created_at: datetime = datetime.now()

class TaskCreate(BaseModel):
    title: str
    description: Optional[str] = None

Two models:

  • Task — the full task object (what we return from the API)
  • TaskCreate — what the client sends to create a task (no id, no created_at — those are generated server-side)

In-Memory Storage

For this tutorial, we'll store tasks in a Python list. In a real app, you'd use a database.

# Storage (in-memory — resets when server restarts)
tasks_db: list[Task] = []
next_id = 1

The CRUD Endpoints (10 Minutes)

GET /tasks — List All Tasks

@app.get("/tasks", response_model=list[Task])
def get_tasks():
    return tasks_db

The response_model=list[Task] tells FastAPI what the response shape looks like — it uses this for documentation and to filter any extra fields.

POST /tasks — Create a Task

@app.post("/tasks", response_model=Task, status_code=201)
def create_task(task_data: TaskCreate):
    global next_id
    task = Task(
        id=next_id,
        title=task_data.title,
        description=task_data.description,
    )
    tasks_db.append(task)
    next_id += 1
    return task

FastAPI automatically validates that the request body matches TaskCreate. If the client sends invalid data (missing title, wrong types), FastAPI returns a 422 error with a clear explanation — no custom validation code required.

GET /tasks/ — Get One Task

from fastapi import FastAPI, HTTPException

@app.get("/tasks/{task_id}", response_model=Task)
def get_task(task_id: int):
    for task in tasks_db:
        if task.id == task_id:
            return task
    raise HTTPException(status_code=404, detail="Task not found")

{task_id} in the path is a path parameter. FastAPI automatically converts it to int and validates it.

PUT /tasks/ — Update a Task

class TaskUpdate(BaseModel):
    title: Optional[str] = None
    description: Optional[str] = None
    completed: Optional[bool] = None

@app.put("/tasks/{task_id}", response_model=Task)
def update_task(task_id: int, updates: TaskUpdate):
    for task in tasks_db:
        if task.id == task_id:
            if updates.title is not None:
                task.title = updates.title
            if updates.description is not None:
                task.description = updates.description
            if updates.completed is not None:
                task.completed = updates.completed
            return task
    raise HTTPException(status_code=404, detail="Task not found")

DELETE /tasks/ — Delete a Task

@app.delete("/tasks/{task_id}", status_code=204)
def delete_task(task_id: int):
    for i, task in enumerate(tasks_db):
        if task.id == task_id:
            tasks_db.pop(i)
            return
    raise HTTPException(status_code=404, detail="Task not found")

The Complete main.py

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Optional
from datetime import datetime

app = FastAPI(title="Task API", description="A simple task management API")

class TaskCreate(BaseModel):
    title: str
    description: Optional[str] = None

class TaskUpdate(BaseModel):
    title: Optional[str] = None
    description: Optional[str] = None
    completed: Optional[bool] = None

class Task(BaseModel):
    id: int
    title: str
    description: Optional[str] = None
    completed: bool = False
    created_at: str = ""

tasks_db: list[Task] = []
next_id = 1

@app.get("/")
def read_root():
    return {"message": "Task API", "docs": "/docs"}

@app.get("/tasks", response_model=list[Task])
def get_tasks():
    return tasks_db

@app.post("/tasks", response_model=Task, status_code=201)
def create_task(task_data: TaskCreate):
    global next_id
    task = Task(
        id=next_id,
        title=task_data.title,
        description=task_data.description,
        created_at=datetime.now().isoformat(),
    )
    tasks_db.append(task)
    next_id += 1
    return task

@app.get("/tasks/{task_id}", response_model=Task)
def get_task(task_id: int):
    for task in tasks_db:
        if task.id == task_id:
            return task
    raise HTTPException(status_code=404, detail="Task not found")

@app.put("/tasks/{task_id}", response_model=Task)
def update_task(task_id: int, updates: TaskUpdate):
    for task in tasks_db:
        if task.id == task_id:
            if updates.title is not None:
                task.title = updates.title
            if updates.description is not None:
                task.description = updates.description
            if updates.completed is not None:
                task.completed = updates.completed
            return task
    raise HTTPException(status_code=404, detail="Task not found")

@app.delete("/tasks/{task_id}", status_code=204)
def delete_task(task_id: int):
    for i, task in enumerate(tasks_db):
        if task.id == task_id:
            tasks_db.pop(i)
            return
    raise HTTPException(status_code=404, detail="Task not found")

Testing Your API (5 Minutes)

Open http://localhost:8000/docs. You'll see the full Swagger UI. Click any endpoint, click "Try it out," fill in the form, and execute. No Postman required.

Testing sequence:

  1. POST /tasks with {"title": "Learn FastAPI"} — should return the created task
  2. GET /tasks — should show your task in a list
  3. PUT /tasks/1 with {"completed": true} — should mark it done
  4. DELETE /tasks/1 — should remove it
  5. GET /tasks/1 — should return 404

Next Steps After This Tutorial

Add a real database: Replace in-memory storage with SQLite + SQLAlchemy. The FastAPI documentation has an excellent SQL databases tutorial.

Add authentication: Add JWT token authentication so only logged-in users can manage their tasks. This turns the tutorial project into a portfolio piece.

Deploy it: Push to GitHub, connect to Railway or Render, and deploy for free. A live URL makes this a proper portfolio project.

For the portfolio context and what to build next, see our guide on Python projects that get you a developer job.

For a comparison of FastAPI vs. Django for larger projects, our Django vs. Flask guide covers when to choose each framework.


Frequently Asked Questions

What is FastAPI?

A modern Python framework for building APIs with automatic documentation, request validation, and async support. One of the fastest Python frameworks.

FastAPI vs. Django REST Framework?

FastAPI for new API-only projects. Django + DRF for full web apps or teams with existing Django expertise.

How do I deploy FastAPI?

Railway or Render (free tier) for beginners. Add requirements.txt, set start command to uvicorn main:app --host 0.0.0.0 --port $PORT, connect GitHub repo.

Does FastAPI support databases?

Yes — SQLAlchemy, Tortoise-ORM, SQLModel, and any Python database library.


Final Thoughts

In 30 minutes, you've built a real REST API with five endpoints, automatic documentation, and request validation. That's the FastAPI experience — get productive immediately, without the boilerplate that slows down other frameworks.

This tutorial project is a solid foundation for a portfolio piece. Add authentication, a database, and deploy it, and you have exactly the kind of project that gets interviews.

For learning about the Python requests library to call APIs like this one from other scripts, see our Python requests library guide. And to continue with data handling and OOP patterns, our Python OOP tutorial builds the class-based patterns you'll use in larger FastAPI apps.

Share this article:

Frequently Asked Questions

FastAPI is a modern Python web framework for building APIs. It's popular because it's fast (one of the fastest Python frameworks, comparable to Node.js), easy to learn (uses standard Python type hints), automatically generates API documentation (Swagger UI at /docs), and validates request/response data automatically using Pydantic. FastAPI has become the preferred choice for new Python API projects because of its developer experience and performance.
A

AiTechWorlds Team

✓ Verified Writer

The AiTechWorlds team is passionate about AI, technology, and education. We create high-quality, research-backed content to help you learn, grow, and succeed in the modern digital world.

Related Articles

10K+ Members Growing Daily

Get Free AI Notes Daily

Join AiTechWorlds on Telegram and get daily AI tips, prompt engineering templates, coding resources, and exclusive content — 100% free!

📚 Free Study Notes🤖 AI Tips Daily⚡ Prompt Templates💻 Coding Resources
Join Free Channel

No spam. Leave anytime.

!