7.9 KiB
FastAPI – GET Endpoints and JSON Responses
Overview
This document explains how to create multiple GET endpoints in FastAPI, return JSON responses, and use path parameters to retrieve specific data from an in-memory dataset.
The example uses a simple list of users to simulate a database.
1. Example Application
Create or update main.py with the following content:
from fastapi import FastAPI
app = FastAPI()
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/")
def root_dir():
return {"message": "API is working"}
@app.get("/users")
def get_users():
return users
@app.get("/user/{name_input}")
def get_user_by_name(name_input: str):
for item in users:
if item["name"] == name_input:
return {"information": item}
return {"message": "User not found"}
2. Application Initialization
app = FastAPI()
This creates the main FastAPI application instance.
The variable app is used by uvicorn when starting the service.
Example:
uvicorn main:app --reload
In main:app:
main = Python file name
app = FastAPI application instance
3. In-Memory Data Store
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
This list is used as temporary storage.
Each user is represented as a Python dictionary.
FastAPI can automatically convert these dictionaries into JSON responses.
Example Python object:
{"name": "abbas", "age": 20}
Example JSON response:
{
"name": "abbas",
"age": 20
}
Important Note
This in-memory list is only suitable for learning, development, and testing.
If the application restarts, the data will be reset.
For production, use a persistent database such as PostgreSQL, MySQL, MongoDB, or another database system.
4. Defined Endpoints
The application defines three GET endpoints:
GET /
GET /users
GET /user/{name_input}
5. Root Endpoint
@app.get("/")
def root_dir():
return {"message": "API is working"}
This endpoint is available at:
GET /
It returns a simple JSON response:
{
"message": "API is working"
}
This type of endpoint is commonly used as a simple health check.
For example, load balancers, monitoring systems, or Kubernetes probes can use it to check whether the API is reachable.
6. Get All Users Endpoint
@app.get("/users")
def get_users():
return users
This endpoint is available at:
GET /users
It returns the full list of users.
Example response:
[
{
"name": "abbas",
"age": 20
},
{
"name": "mmd",
"age": 37
},
{
"name": "asghar",
"age": 19
}
]
FastAPI automatically serializes the Python list into a JSON array.
7. Get User by Name Endpoint
@app.get("/user/{name_input}")
def get_user_by_name(name_input: str):
for item in users:
if item["name"] == name_input:
return {"information": item}
return {"message": "User not found"}
This endpoint is available at:
GET /user/{name_input}
The {name_input} part is a path parameter.
Example request:
GET /user/abbas
In this request, FastAPI assigns:
name_input = "abbas"
The function then searches the users list for a user whose name matches the input.
8. Successful Response Example
Request:
GET /user/abbas
Response:
{
"information": {
"name": "abbas",
"age": 20
}
}
9. Failure Response Example
Request:
GET /user/ali
Response:
{
"message": "User not found"
}
In the current simple version, the API returns a normal JSON message even when the user does not exist.
However, in a real API, it is better to return a proper 404 Not Found response.
10. Path Parameters
A path parameter is a dynamic part of the URL.
In this route:
@app.get("/user/{name_input}")
name_input is a path parameter.
Example:
GET /user/mmd
FastAPI extracts the value from the URL and passes it to the function:
def get_user_by_name(name_input: str):
Because name_input is defined as a string:
name_input: str
FastAPI validates it as a string.
11. Better Version with HTTPException
The previous version works, but it does not return the correct HTTP status code when a user is not found.
A better version uses HTTPException.
from fastapi import FastAPI, HTTPException, status
app = FastAPI()
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/")
def root_dir():
return {"message": "API is working"}
@app.get("/users")
def get_users():
return users
@app.get("/user/{name_input}")
def get_user_by_name(name_input: str):
for item in users:
if item["name"] == name_input:
return {"information": item}
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
12. Improved Failure Response
Request:
GET /user/ali
Response:
{
"detail": "User not found"
}
HTTP status code:
404 Not Found
This is better because the API response now correctly tells the client that the requested resource does not exist.
13. Running the Application
Start the FastAPI application using uvicorn:
uvicorn main:app --reload
The application will be available at:
http://localhost:8000
14. Accessing the Endpoints
Root endpoint:
http://localhost:8000/
Get all users:
http://localhost:8000/users
Get user by name:
http://localhost:8000/user/abbas
Interactive API documentation:
http://localhost:8000/docs
Alternative API documentation:
http://localhost:8000/redoc
15. Testing with curl
Test Root Endpoint
curl http://localhost:8000/
Response:
{
"message": "API is working"
}
Test Get All Users
curl http://localhost:8000/users
Response:
[
{
"name": "abbas",
"age": 20
},
{
"name": "mmd",
"age": 37
},
{
"name": "asghar",
"age": 19
}
]
Test Get User by Name
curl http://localhost:8000/user/abbas
Response:
{
"information": {
"name": "abbas",
"age": 20
}
}
Test User Not Found
curl http://localhost:8000/user/ali
Response:
{
"detail": "User not found"
}
16. Complete Recommended Version
from fastapi import FastAPI, HTTPException, status
app = FastAPI()
users = [
{"name": "abbas", "age": 20},
{"name": "mmd", "age": 37},
{"name": "asghar", "age": 19},
]
@app.get("/")
def root_dir():
return {"message": "API is working"}
@app.get("/users")
def get_users():
return users
@app.get("/user/{name_input}")
def get_user_by_name(name_input: str):
for item in users:
if item["name"] == name_input:
return {"information": item}
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
17. Best Practices
Use GET endpoints only for retrieving data.
Do not use GET requests to create, update, or delete resources.
Return structured JSON responses.
Use proper HTTP status codes.
Use 404 Not Found when a requested resource does not exist.
Use 200 OK when the request is successful.
Replace in-memory lists with a real database in production.
Keep route names clear and consistent.
Use plural naming for collection endpoints, such as:
GET /users
Use specific resource endpoints for single items, such as:
GET /users/{username}
As the project grows, separate code into different files for routes, models, services, and database logic.