Back to Blog
Lesson 32 of the Python: Programming from Zero with Python course
PythonAugust 18, 20263 min read

Defining API Endpoints: Routes and Decorators in FastAPI

Learn to define API endpoints using decorators in FastAPI. Master creating GET routes and returning dictionary data to build a functional backend service.

PythonFastAPIAPIWeb DevelopmentBackendREST
A retro Route 66 wall clock surrounded by soft, magical bokeh lighting.

Previously in this course, we covered Setting Up FastAPI to initialize our development environment. Now that your server is running, it’s time to define the actual logic that makes your API useful.

In modern web development, an endpoint is a specific URL path (like /items or /status) that your server listens to. When a client sends a request to that URL, the server executes a corresponding function. To link these together in Python, we use decorators.

Understanding Decorators as Route Handlers

A decorator is a special Python syntax—prefixed with the @ symbol—that "wraps" a function to modify its behavior. In FastAPI, we use the app instance to decorate our functions, effectively telling the framework: "When a user visits this URL, run this specific function."

Think of the decorator as a traffic controller. It sees the incoming request path, checks if it matches a defined route, and directs the request to your code.

Building Your First GET Endpoint

A GET request is the standard way to retrieve data from a server. When a browser loads a webpage or a script fetches JSON, it is almost always performing a GET request.

Let’s extend our running API project by adding a simple status endpoint that returns our application's current state as a dictionary.

PYTHON
from fastapi import FastAPI

app = FastAPI()

# This decorator defines the route and the HTTP method
@app.get("/status")
def get_status():
    # FastAPI automatically converts this dictionary to JSON
    return {
        "status": "online",
        "version": "1.0.0",
        "message": "API is running successfully"
    }

How it works:

  1. @app.get("/status"): This tells FastAPI that when a GET request hits the /status path, it should execute the function immediately below it.
  2. def get_status():: This is your standard Python function. It performs the logic—in this case, simply returning a data structure.
  3. Automatic JSON Conversion: Because we are returning a dictionary, FastAPI automatically serializes it into a JSON response. You don't need to manually import the json module here; the framework handles the serialization for you.

Hands-On Exercise: Adding Data to Your API

In your project folder, create a new file named main.py if you haven't already. Add the following code to provide an endpoint that returns a sample dataset from our statistics processor project:

  1. Define a new route @app.get("/data").
  2. Inside the function, create a dictionary representing a simple data summary.
  3. Return that dictionary.
  4. Run your server using uvicorn main:app --reload and visit http://127.0.0.1:8000/data in your browser.

Common Pitfalls

  • Forgetting the Decorator: If you define the function but forget the @app.get(...) line above it, the function remains just a regular function. It will never be triggered by web requests.
  • Path Mismatches: Ensure your path starts with a forward slash (/). A path like status instead of /status will often cause the framework to ignore the route.
  • Returning Non-JSON Types: While FastAPI handles dictionaries, lists, and strings well, returning complex objects (like custom classes) requires extra configuration. Stick to basic types like dictionaries for now.

Frequently Asked Questions

What if I want to use a different HTTP method, like POST? You simply change the decorator. Use @app.post("/path") for creating data. We will cover this in detail when we handle API payloads.

Can I have multiple endpoints in one file? Yes. You can define as many functions as you want, each decorated with its own route. They will all live within the same app instance.

Why does the browser show JSON? Browsers are smart enough to recognize the application/json content type header that FastAPI automatically adds to your response. This makes testing your endpoints in the browser very convenient.

Recap

We have successfully moved from a "Hello World" server to a data-returning service. By using decorators to define endpoints and routes, we can organize our API logic cleanly. Returning a dictionary is the most efficient way to provide structured data to any client, whether it's a browser, a mobile app, or another script.

Up next: List Comprehensions — we'll learn how to transform and filter data structures concisely before returning them through our API.

Similar Posts