Build a Ravyn API with Edgy¶
This tutorial shows a practical API path:
- define a model,
- persist incoming request data,
- wire Edgy lifecycle into an ASGI app.
Why This Tutorial¶
It demonstrates a real request path with a framework integration, not only isolated query snippets.
Application Flow¶
sequenceDiagram
participant Client
participant API as Ravyn endpoint
participant Model as Edgy Model
participant DB as Database
Client->>API: POST /create
API->>Model: validate payload as model
Model->>DB: save()
DB-->>Model: inserted row
Model-->>API: model instance
API-->>Client: JSON response
Implementation¶
from ravyn import Ravyn, Gateway, post
import edgy
from edgy.testclient import DatabaseTestClient as Database
database = Database("sqlite:///db.sqlite")
models = edgy.Registry(database=database)
class User(edgy.Model):
name: str = edgy.CharField(max_length=100)
email: str = edgy.EmailField(max_length=100)
language: str = edgy.CharField(max_length=200, null=True)
description: str = edgy.TextField(max_length=5000, null=True)
class Meta:
registry = models
@post("/create")
async def create_user(data: User) -> User:
"""
You can perform the same directly like this
as the validations for the model (nulls, mandatories, @field_validators)
already did all the necessary checks defined by you.
"""
user = await data.save()
return user
app = models.asgi(
Ravyn(
routes=[Gateway(handler=create_user)],
)
)
What to Observe¶
- The payload is validated through the model fields.
- The handler persists data with
await data.save(). models.asgi(...)binds the app lifecycle to Edgy.
Try It¶
Send a request to /create with a payload compatible with User.
Expected response shape:
{
"id": 1,
"name": "Edgy",
"email": "edgy@ravyn.dev",
"language": "EN",
"description": "A description"
}
Next Step¶
Move to Multi-Database and Schema Workflow when you need cross-db or tenant-aware behavior.