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¶
- 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"}
- 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}
- Request Body: Complex data (e.g., forms, JSON), received via Pydantic models
(See the POST example above, whereItemmodels 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!