Learning FastAPI from Scratch: Quickly Understanding the Core Concepts of API Development

What is an API?

Imagine using a food delivery app on your phone to place an order. The app needs to request “return menu list” and “submit order information” from the restaurant’s server. This “request-response” process is how APIs work. Simply put, an API is a “bridge for communication” between different software systems, enabling secure and efficient data transfer between clients (e.g., phones, web browsers) and servers.

Why Choose FastAPI?

Among Python’s web frameworks, FastAPI is a “rising star” that has gained rapid popularity due to several advantages:
- Simple to Use: Syntax is close to native Python, requiring minimal configuration.
- High Performance: Exceptionally fast (performance comparable to Node.js and Go), suitable for high-concurrency scenarios.
- Automatic Documentation: Built-in Swagger UI and ReDoc generate interactive API documentation immediately after development.
- Type Hint Support: Works seamlessly with Python type annotations to auto-generate code hints and data validation.
- Async-Friendly: Supports asynchronous programming, making long-running tasks (e.g., database queries) more efficient.

Quick Start: Installation & First “Hello World”

Install FastAPI and Server

First, install FastAPI and the Uvicorn server tool:

pip install fastapi uvicorn

Write Your First API

Create a main.py file with the following code:

from fastapi import FastAPI

# Initialize FastAPI application
app = FastAPI()

# Define a route and its handler function
@app.get("/")  # When a GET request is made to the root path "/"
def read_root():
    return {"message": "Hello, FastAPI!"}  # Returns JSON-formatted data

Run the API

Execute in the terminal:

uvicorn main:app --reload

main:app specifies the app instance in main.py, and --reload auto-restarts the server when code changes.
Visit http://localhost:8000 to see the response: {"message": "Hello, FastAPI!"}.

Core Concept 1: Routes & View Functions

A route acts like a “label” for your API endpoint—when a user accesses a specific URL, FastAPI matches the URL path to the corresponding “handler function” (view function).

Example:

@app.get("/hello")  # Route path: "/hello", HTTP method: GET
def say_hello():
    return {"message": "Hello, FastAPI!"}

Visiting http://localhost:8000/hello triggers the say_hello function and returns the result.

Core Concept 2: HTTP Methods (GET/POST, etc.)

Different HTTP methods serve distinct use cases:
- GET: Retrieve data (e.g., fetching a list or details), parameters in the URL.
- POST: Submit data (e.g., creating a user or uploading a file), parameters in the request body.

GET Request Example (Query Parameters)

@app.get("/items/")  # Path: "/items/"
def get_items(limit: int = 10, offset: int = 0):  # Optional parameters with defaults
    return {"limit": limit, "offset": offset}

Visit http://localhost:8000/items/?limit=20&offset=5 to get {"limit": 20, "offset": 5}.

POST Request Example (Request Body)

POST requires data in the request body. Use Pydantic models to define data structure:

from pydantic import BaseModel

# Define data model (enforce type constraints)
class Item(BaseModel):
    name: str
    price: float
    is_offer: bool | None = None  # Optional field, default: None

@app.post("/items/")  # POST request to submit Item data
def create_item(item: Item):
    return {"item": item.dict(), "message": "Item created!"}

Sending a JSON payload like {"name": "Phone", "price": 999.99} will trigger validation and return the result.

Core Concept 3: Three Ways to Handle Request Data

  1. Path Parameters: Dynamic parts of the URL (e.g., /user/{user_id})
   @app.get("/user/{user_id}")
   def get_user(user_id: int):  # user_id is an integer
       return {"user_id": user_id, "message": f"User {user_id}'s info"}
  1. Query Parameters: Key-value pairs after ? in the URL (e.g., /search?q=python)
   @app.get("/search")
   def search(q: str, page: int = 1):
       return {"query": q, "page": page}
  1. Request Body: Complex data (e.g., forms, JSON), received via Pydantic models
    (See the POST example above, where Item models parse JSON request bodies.)

Core Concept 4: Building Responses & Status Codes

Return Data

FastAPI automatically converts Python data (e.g., dictionaries, lists) to JSON, eliminating manual serialization.

Custom Status Codes

By default, 200 OK is returned. Use status_code to specify others:

from fastapi import status

@app.post("/items/", status_code=status.HTTP_201_CREATED)
def create_item(item: Item):
    return {"item": item}  # Returns 201 Created status code

Core Concept 5: Data Validation with Pydantic Models

Pydantic acts as FastAPI’s “data validator,” auto-validating request data via type annotations:

class User(BaseModel):
    name: str  # Must be a string
    age: int   # Must be an integer
    email: str | None = None  # Optional field, default: None

@app.post("/register/")
def register(user: User):
    if user.age < 18:
        return {"error": "Age must be ≥18"}
    return {"user": user.dict(), "message": "Registration successful"}

If data is invalid (e.g., age is a string), FastAPI returns clear error messages.

Core Concept 6: Automatic API Documentation

FastAPI includes built-in Swagger UI and ReDoc for testing endpoints:
- Access http://localhost:8000/docs (Swagger UI: interactive testing interface).
- Access http://localhost:8000/redoc (ReDoc: more elegant documentation).

These tools auto-generate endpoint descriptions, parameter examples, and response formats—no manual documentation needed!

Summary & Next Steps

You now know FastAPI’s core basics:
- Define endpoints with routes and view functions.
- Handle GET/POST methods and data input.
- Validate data with Pydantic models.
- Use automatic documentation for quick debugging.

Next steps to explore:
- Asynchronous API development (async def).
- Middleware and dependency injection (e.g., database connections, authentication).
- Database integration (SQLAlchemy).

FastAPI is simple yet powerful—practice building endpoints, and you’ll master it quickly!

Xiaoye