Building a REST API with FastAPI
Let's talk about building APIs. You probably know *why* you'd want to build one – they're the backbone of modern web applications, allowing different services to communicate and share data. But if…
Building a REST API with FastAPI
Let's talk about building APIs. You probably know *why* you'd want to build one – they're the backbone of modern web applications, allowing different services to communicate and share data. But if you're coming from a background with Flask or Django, or even just starting out, you might be looking for something… faster, more modern, and frankly, less boilerplate. That's where FastAPI comes in.
FastAPI is a Python web framework specifically designed for building APIs. It's built on top of standard Python type hints, which allows for automatic data validation, serialization, and API documentation. And it's *fast* – seriously, it's one of the fastest Python web frameworks available, rivaling Node.js and Go.
This article will walk you through building a simple REST API with FastAPI, covering the core concepts and giving you a solid foundation to build upon.
Why FastAPI?
Before diving into the code, let's quickly recap why you should consider FastAPI:
async and await for asynchronous programming.Setting Up Your Project
First, you'll need to install FastAPI and Uvicorn, an ASGI server that FastAPI uses to run.
pip install fastapi uvicornNow, create a file named main.py. This will be the entry point for our API.
Defining Your First Endpoint
Let's start with a simple "Hello, World!" endpoint.
from fastapi import FastAPIapp = FastAPI()
@app.get("/")
async def read_root():
return {"Hello": "World"}
Let's break this down:
from fastapi import FastAPI: Imports the FastAPI class.app = FastAPI(): Creates an instance of the FastAPI application.@app.get("/"): This is a decorator that registers the read_root function as a handler for GET requests to the root path ("/").async def read_root(): This is an asynchronous function that will be executed when a GET request is made to the root path. Using async allows FastAPI to handle many requests concurrently.return {"Hello": "World"}: Returns a JSON response. FastAPI automatically serializes Python dictionaries to JSON.To run this, open your terminal and execute:
uvicorn main:app --reloadThis starts the Uvicorn server, serving your API. The --reload flag enables automatic reloading whenever you make changes to your code. Open your browser and navigate to http://127.0.0.1:8000/. You should see {"Hello": "World"}.
Also, check out http://127.0.0.1:8000/docs. This is the automatically generated Swagger UI documentation for your API! Pretty cool, right?
Adding Parameters and Data Validation
Let's create an endpoint that accepts a parameter and validates the input. We'll create an endpoint that greets a user by name.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModelapp = FastAPI()
class User(BaseModel):
name: str
age: int
@app.get("/greet/{user_name}")
async def greet_user(user_name: str):
return {"greeting": f"Hello, {user_name}!"}
@app.post("/users/")
async def create_user(user: User):
if user.age < 0:
raise HTTPException(status_code=400, detail="Age must be a non-negative number")
return {"message": f"User {user.name} created successfully!"}
Here's what's new:
from pydantic import BaseModel: Imports the BaseModel class from Pydantic.class User(BaseModel): ...: Defines a Pydantic model called User. This model defines the expected structure of the data we'll receive in a POST request. name: str and age: int specify the fields and their data types.@app.get("/greet/{user_name}"): This endpoint now has a path parameter user_name. FastAPI automatically extracts the value from the URL.@app.post("/users/"): This endpoint handles POST requests to /users/.async def create_user(user: User): The user: User parameter tells FastAPI to expect a JSON body that conforms to the User model. Pydantic automatically validates the input data.raise HTTPException(...): If the age is invalid, we raise an HTTPException with a 400 status code (Bad Request) and a descriptive error message.Now, try sending a POST request to http://127.0.0.1:8000/users/ with the following JSON body:
{
"name": "Alice",
"age": 30
}You should receive a response like: {"message": "User Alice created successfully!"}.
If you try sending invalid data, like a negative age, you'll get a 400 error with the detail message you specified. This is the power of Pydantic's data validation.
Working with Databases (Briefly)
While a full database integration is beyond the scope of this article, it's important to know how FastAPI handles it. You'll typically use an asynchronous database library like databases or an ORM like SQLAlchemy with its asynchronous capabilities.
FastAPI's dependency injection system is *perfect* for managing database connections. You can create a dependency that establishes a database connection and then inject that dependency into your endpoint functions. This keeps your endpoint logic clean and focused.
Practical Tips
async and await for I/O-bound operations like database queries and network requests. This will significantly improve your API's performance.Next Steps
This is just a starting point. Here are some things you can explore next:
FastAPI is a powerful and versatile framework. Head over to the [official documentation](https://fastapi.tiangolo.com/) to learn more and start building your own amazing APIs! And don't forget to check out the Coding4Bread platform for more in-depth courses and tutorials on FastAPI and other backend technologies.