Request Body¶
A request body is data sent by the client in the HTTP request, typically as JSON. FasterAPI uses msgspec structs for fast, type-safe validation and serialisation — no Pydantic required.
Defining a model¶
Subclass msgspec.Struct to describe the expected fields:
- Required fields have no default (
name,price). - Optional fields have a default (
in_stock).
Using the model in a route¶
Declare the struct as a parameter. FasterAPI reads the JSON body, validates it, and
passes an Item instance to your handler:
from FasterAPI import Faster
import msgspec
app = Faster()
class Item(msgspec.Struct):
name: str
price: float
in_stock: bool = True
@app.post("/items")
async def create_item(item: Item):
return {"name": item.name, "price": item.price}
curl -X POST http://localhost:8000/items \
-H "Content-Type: application/json" \
-d '{"name": "Widget", "price": 9.99}'
# {"name":"Widget","price":9.99}
Path + query + body together¶
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, notify: bool = False):
result = {"item_id": item_id, **msgspec.structs.asdict(item)}
if notify:
result["message"] = "notified"
return result
item_idcomes from the path.notifycomes from the query string.itemcomes from the JSON body.
Nested models¶
class Image(msgspec.Struct):
url: str
width: int
height: int
class Product(msgspec.Struct):
name: str
image: Image | None = None
Optional body¶
Use | None with a default to make the body optional:
@app.patch("/items/{item_id}")
async def partial_update(item_id: int, item: Item | None = None):
if item is None:
return {"item_id": item_id, "updated": False}
return {"item_id": item_id, "name": item.name}
Validation errors¶
If the client sends invalid JSON or a field fails type coercion, FasterAPI returns:
{
"detail": [
{
"loc": ["body"],
"msg": "Expected `float`, got `str` - at `$.price`",
"type": "value_error.msgspec"
}
]
}
Using Body() for raw JSON¶
For cases where you want an arbitrary JSON value rather than a struct:
Next steps¶
- Response Model — control what data is returned to the client.
- Form Data & File Uploads — non-JSON request bodies.
- Dependencies — share validation logic across routes.