Warning: Bocadillo is now UNMAINTAINED. Users are recommended to migrate to a supported alternative, such as Starlette or FastAPI. Please see #344 for more information.
JSON validation
Bocadillo has built-in support for JSON data validation within views using TypeSystem, a data validation library.
NOTE
If you're looking to validate data before saving it to a database, see Data validation (ORM). If you are looking to validate arbitrary JSON objects, read on!
How it works
JSON data validation is implemented by registering an error handler for the typesystem.ValidationError
exception.
Thanks to this, you can transparently use all the features of TypeSystem and let validation fail within views: Bocadillo will format and send a 400 Bad Request
error response for you.
TypeSystem comes installed with Bocadillo, and this feature is enabled by default, so you can use it right out of the box. 🎉
Example
Consider a todos
application.
- In
models.py
, we define aTodo
data schema.
import typesystem
class Todo(typesystem.Schema):
title = typesystem.String(max_length=20)
done = typesystem.Boolean(default=False)
- In
app.py
, we validate the JSON payload with theTodo
schema and then create a todo item:
# todos/app.py
from bocadillo import App
from .models import Todo
app = App()
@app.route("/todos")
class TodoList:
async def post(self, req, res):
# NOTE: this may raise a `ValidationError` if the JSON
# payload is invalid.
# No need to try/except: the error handler will process
# the exception for us!
todo = Todo.validate(await req.json())
# TODO: store todo item.
res.json = dict(todo)
res.status_code = 201
Let's try it out:
- Run the app using
$ uvicorn todos.asgi:app
. - Make a request with a valid JSON payload — everything should be fine:
$ curl \
-X POST \
-d '{"title": "Make breakfast"}' \
http://localhost:8000/todos
{
"title": "Make breakfast",
"done": false
}
- Send an invalid payload instead (e.g. title too long) — Bocadillo should automatically return an explicit error response:
$ curl \
-X POST \
-d '{"title": "Buy cornflakes at the store and make breakfast"}' \
http://localhost:8000/todos
{
"error": "400 Bad Request",
"status": 400,
"detail": { "title": "Must have no more than 20 characters." }
}
This is a fairly basic example, but you can read the TypeSystem documentation to learn about more complex validation techniques.
Disabling validation error handling
If you wish to disable the ValidationError
error handler, use the HANDLE_TYPESYSTEM_VALIDATION_ERROR
setting:
# myproject/settings.py
HANDLE_TYPESYSTEM_VALIDATION_ERROR = False
You would then have to handle typesystem.ValidationError
yourself, or implement your own error handlers in case you want to use a different data validation library.