Skip to content

Migrating from FastAPI

JustAPI is engineered as a drop-in replacement for FastAPI. In most cases, migration is as simple as changing imports.

# FastAPI
from fastapi import FastAPI, Depends, HTTPException, Query, Path, Header
from fastapi.responses import JSONResponse
# JustAPI — same names, same API
from justapi import JustAPIApp, Depends, HTTPException, Query, Path, Header
from justapi.responses import JSONResponse
# FastAPI
app = FastAPI(title="My API", version="1.0.0")
# JustAPI
app = JustAPIApp(title="My API", version="1.0.0")
# FastAPI (requires uvicorn)
# uvicorn main:app --host 0.0.0.0 --port 8000
# JustAPI — built-in Rust server
if __name__ == "__main__":
app.run("0.0.0.0:8000")
# FastAPI requirements
fastapi==0.109.0
uvicorn[standard]==0.27.0
# JustAPI requirements — one dependency
justapi>=2.0.0
FastAPI Import JustAPI Import Notes
FastAPI JustAPIApp Core application class
APIRouter APIRouter Same API, works identically
Depends Depends Dependency injection
HTTPException HTTPException Error raising
Query Query Query parameter extraction
Path Path Path parameter extraction
Header Header Header extraction
Cookie Cookie Cookie extraction
Body Body Body parameter extraction
File File File upload
Form Form Form field extraction
UploadFile UploadFile Uploaded file representation
Response Response Base response class
JSONResponse JSONResponse JSON response
HTMLResponse HTMLResponse HTML response
PlainTextResponse PlainTextResponse Plain text response
RedirectResponse RedirectResponse HTTP redirect
StreamingResponse StreamingResponse Streaming response
RequestValidationError RequestValidationError Validation error
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
app = FastAPI(title="Pet Store")
class Pet(BaseModel):
name: str
species: str
def verify_token(token: str = Header(...)):
if token != "secret":
raise HTTPException(401)
@app.get("/pets/{pet_id}")
def get_pet(pet_id: int, token: str = Depends(verify_token)):
return {"pet_id": pet_id}
@app.post("/pets/")
def create_pet(pet: Pet):
return {"name": pet.name}
from justapi import JustAPIApp, Depends, HTTPException, Header
from pydantic import BaseModel
app = JustAPIApp(title="Pet Store")
class Pet(BaseModel):
name: str
species: str
def verify_token(token: str = Header(...)):
if token != "secret":
raise HTTPException(401)
@app.get("/pets/{pet_id}")
def get_pet(pet_id: int, token: str = Depends(verify_token)):
return {"pet_id": pet_id}
@app.post("/pets/")
def create_pet(pet: Pet):
return {"name": pet.name}
# FastAPI
@app.middleware("http")
async def add_header(request, call_next):
response = await call_next(request)
response.headers["X-Custom"] = "value"
return response
# JustAPI — identical syntax
@app.middleware("http")
def add_header(request, call_next):
response = call_next(request)
response["headers"] = response.get("headers", []) + [(b"X-Custom", b"value")]
return response
  • Running the server: JustAPI’s app.run() replaces uvicorn/gunicorn
  • Middleware signature: Slightly different header manipulation (tuple-based)
  • OpenAPI docs: Same URLs (/docs, /redoc), plus Scalar UI at /scalar
  • Route decorators (@app.get, @app.post, etc.)
  • Pydantic model validation
  • Dependency injection (Depends)
  • Exception handling (HTTPException, custom handlers)
  • Path/Query/Header/Cookie/Body extractors
  • Sub-routers (APIRouter, include_router)
  • WebSocket handlers
  • Static file serving
Metric FastAPI + Uvicorn JustAPI Improvement
Throughput 36,189 req/s 701,234 req/s ~20x faster
p99 Latency 24.63 ms 0.19 ms ~130x lower
JSON validation Python runtime Rust (GIL-free) Zero overhead
DB queries Python asyncio Rust sqlx pool Native speed
Memory usage Per-request overhead Zero-copy buffers Minimal
  • Replace from fastapi import with from justapi import
  • Replace FastAPI() with JustAPIApp()
  • Replace uvicorn.run() with app.run()
  • Update middleware response header manipulation
  • Test all routes return the same responses
  • Compare performance with your load testing tool
  • Update requirements.txt / pyproject.toml
  • Update Dockerfile if using custom build

JustAPI is designed for gradual adoption. You can:

  1. Migrate one route at a time using APIRouter
  2. Run JustAPI and FastAPI side-by-side behind a reverse proxy
  3. Keep your existing tests — the response format is identical