Routing & Response Wrapping
ZodiacCore enhances FastAPI's routing system to provide automatic response standardization. By using APIRouter, you ensure that every endpoint returns a consistent JSON structure without manual boilerplate.
1. The Zodiac APIRouter
The APIRouter in ZodiacCore is a drop-in replacement for fastapi.APIRouter. It uses a custom ZodiacRoute class that intercepts outgoing data and wraps it.
Automatic Wrapping
When you return a dictionary, a Pydantic model, or a list from your route, Zodiac automatically wraps it in a Response model:
from zodiac_core.routing import APIRouter
router = APIRouter()
@router.get("/status")
async def get_status():
return {"status": "online"}
Resulting JSON:
2. Standard Response Structure
All Zodiac responses follow this schema:
| Field | Type | Description |
|---|---|---|
code |
int |
Business status code (0 for success). |
message |
string |
A brief description of the result. |
data |
any |
The actual payload (result of your function). |
Manual Responses
If you need to return a non-standard response (e.g., a FileResponse or a custom status code), you can still return raw FastAPI Response objects or Zodiac's Response class. If the return type is already a Response, Zodiac will not wrap it again.
from zodiac_core.response import response_ok
@router.get("/custom")
async def manual():
return response_ok(message="Custom success", data={"id": 1})
3. OpenAPI Integration
ZodiacCore's APIRouter dynamically generates Pydantic models for your responses. This means your Swagger UI (/docs) will correctly display the wrapped structure, including the code, message, and data fields, mapped to your specific return type.
4. API Reference
Routing Utilities
APIRouter
Bases: APIRouter
Zodiac-enhanced APIRouter that uses ZodiacRoute by default.
All routes registered via this router will automatically: - Wrap response_model with Response[T] for OpenAPI docs - Wrap endpoint return values with Response structure
Source code in zodiac_core/routing.py
ZodiacRoute
Bases: APIRoute
Custom APIRoute that automatically wraps response models and endpoint returns with the standard Response[T] structure.
Source code in zodiac_core/routing.py
Response Helpers
Response
Bases: BaseModel, Generic[T]
Standard API response model.
Source code in zodiac_core/response.py
create_response(http_code, code=None, data=None, message='')
Create a standardized JSON response.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
http_code
|
int
|
HTTP status code |
required |
code
|
Optional[int]
|
Business status code (defaults to http_code if not provided) |
None
|
data
|
Any
|
Response payload |
None
|
message
|
str
|
Response message |
''
|
Source code in zodiac_core/response.py
response_ok(code=None, data=None, message='Success')
Create a successful response (200 OK)
Source code in zodiac_core/response.py
response_created(code=None, data=None, message='Created')
Create a resource created response (201 Created)
Source code in zodiac_core/response.py
response_bad_request(code=None, data=None, message='Bad Request')
Create a bad request error response (400 Bad Request)
Source code in zodiac_core/response.py
response_unauthorized(code=None, data=None, message='Unauthorized')
Create an unauthorized response (401 Unauthorized)
Source code in zodiac_core/response.py
response_forbidden(code=None, data=None, message='Forbidden')
Create a forbidden response (403 Forbidden)
Source code in zodiac_core/response.py
response_not_found(code=None, data=None, message='Not Found')
Create a not found response (404 Not Found)
Source code in zodiac_core/response.py
response_conflict(code=None, data=None, message='Conflict')
Create a conflict response (409 Conflict)
Source code in zodiac_core/response.py
response_unprocessable_entity(code=None, data=None, message='Unprocessable Entity')
Create an unprocessable entity response (422 Unprocessable Entity)
Source code in zodiac_core/response.py
response_server_error(code=None, data=None, message='Internal Server Error')
Create a server error response (500 Internal Server Error)