docs/api-routes/overview.md
import reflex as rx
In addition to your frontend app, Reflex uses a FastAPI backend to serve your app. The API transformer feature allows you to transform or extend the ASGI app that serves your Reflex application.
The API transformer provides a way to:
This is useful for creating a backend API that can be used for purposes beyond your Reflex app, or for integrating Reflex with existing backend services.
You can set the api_transformer parameter when initializing your Reflex app:
import reflex as rx
from fastapi import FastAPI, Depends
from fastapi.security import OAuth2PasswordBearer
# Create a FastAPI app
fastapi_app = FastAPI(title="My API")
# Add routes to the FastAPI app
@fastapi_app.get("/api/items")
async def get_items():
return dict(items=["Item1", "Item2", "Item3"])
# Create a Reflex app with the FastAPI app as the API transformer
app = rx.App(api_transformer=fastapi_app)
The api_transformer parameter can accept:
When you provide a FastAPI or Starlette instance as the API transformer, Reflex will mount its internal API to your app, allowing you to define additional routes:
import reflex as rx
from fastapi import FastAPI, Depends
from fastapi.security import OAuth2PasswordBearer
# Create a FastAPI app with authentication
fastapi_app = FastAPI(title="Secure API")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# Add a protected route
@fastapi_app.get("/api/protected")
async def protected_route(token: str = Depends(oauth2_scheme)):
return dict(message="This is a protected endpoint")
# Create a token endpoint
@fastapi_app.post("/token")
async def login(username: str, password: str):
# In a real app, you would validate credentials
if username == "user" and password == "password":
return dict(access_token="example_token", token_type="bearer")
return dict(error="Invalid credentials")
# Create a Reflex app with the FastAPI app as the API transformer
app = rx.App(api_transformer=fastapi_app)
You can also provide a callable that transforms the ASGI app:
import reflex as rx
from starlette.middleware.cors import CORSMiddleware
# Create a transformer function that returns a transformed ASGI app
def add_cors_middleware(app):
# Wrap the app with CORS middleware and return the wrapped app
return CORSMiddleware(
app=app,
allow_origins=["https://example.com"],
allow_methods=["*"],
allow_headers=["*"],
)
# Create a Reflex app with the transformer
app = rx.App(api_transformer=add_cors_middleware)
You can apply multiple transformers by providing a sequence:
import reflex as rx
from fastapi import FastAPI
from starlette.middleware import Middleware
from starlette.middleware.cors import CORSMiddleware
# Create a FastAPI app
fastapi_app = FastAPI(title="My API")
# Add routes to the FastAPI app
@fastapi_app.get("/api/items")
async def get_items():
return dict(items=["Item1", "Item2", "Item3"])
# Create a transformer function
def add_logging_middleware(app):
# This is a simple example middleware that logs requests
async def middleware(scope, receive, send):
# Log the request path
path = scope["path"]
print("Request:", path)
await app(scope, receive, send)
return middleware
# Create a Reflex app with multiple transformers
app = rx.App(api_transformer=[fastapi_app, add_logging_middleware])
Some routes on the backend are reserved for the runtime of Reflex, and should not be overridden unless you know what you are doing.
localhost:8000/ping/: You can use this route to check the health of the backend.
The expected return is "pong".
localhost:8000/_event: the frontend will use this route to notify the backend that an event occurred.
# Overriding this route will break the event communication
localhost:8000/_upload: This route is used for file uploads when using
rx.upload(), including rx.upload_files(...) and
rx.upload_files_chunk(...).