Routes generation (FastAPI)¶
AutoCRUD generates API endpoints by applying route templates to each registered resource
when you call apply(router).
Important: the final set of endpoints depends on: -
model_naming/add_model(name=...)-route_templates(default or customized) - whether you usecreate_action()/update_action()/ ref routes / backup routes
Minimal usage¶
from fastapi import FastAPI
from autocrud import crud
app = FastAPI()
crud.add_model(User)
crud.apply(app)
Resource name → base path¶
A model is registered with a resource name:
add_model(User)→ name inferred from model class +model_namingadd_model(User, name="people")→ override path base to/people
Default templates (typical endpoints)¶
When route_templates is None (default behavior) or a configuration dict, AutoCRUD installs
a default set of templates (create/list/read/update/patch/delete/restore/export/import, etc).
For a resource named users, you typically get endpoints like:
POST /users— createGET /users/...— list variants (depending on templates, may include data/meta/full/revision views)GET /users/{id}/...— read variants (depending on templates)PUT /users/{id}— replacePATCH /users/{id}— RFC6902 JSON Patch (if Patch template is enabled)DELETE /users/{id}— soft delete (if Delete template is enabled)POST /users/{id}/restore— restore (if Restore template is enabled)- Revision-related endpoints (switch / list / info) depending on templates
Why the endpoints are not listed exhaustively here¶
AutoCRUD supports customizing templates and adding custom routes. If you need an authoritative list,
use your generated OpenAPI docs (Swagger UI / ReDoc) after calling apply().
Custom route templates¶
Configure default templates (dict form)¶
You can pass a dict {TemplateClass: kwargs} to configure default templates:
from autocrud import AutoCRUD
from autocrud.crud.route_templates import ListRouteTemplate
autocrud = AutoCRUD(route_templates={
ListRouteTemplate: {"dependency_provider": my_provider},
})
Provide a full template list¶
Add templates incrementally¶
Templates should be added before apply() for predictable behavior.
Custom create actions¶
Use create_action() to add additional create endpoints for a resource:
from msgspec import Struct
from fastapi import Body
from autocrud import crud
class ImportFromUrl(Struct):
url: str
@crud.create_action("article", label="Import from URL")
async def import_from_url(body: ImportFromUrl = Body(...)):
content = await fetch_and_parse(body.url)
return Article(content=content) # returning a resource triggers auto-create
create_action() is lazy: it stores metadata and routes are created at apply() time.
Custom update actions¶
Use update_action() to add custom update endpoints for an existing resource.
The handler automatically receives the current resource data (injected by parameter name),
and can optionally receive RevisionInfo and ResourceMeta.
from msgspec import Struct
from fastapi import Body
from autocrud import crud
class LevelUpInput(Struct):
levels: int = 1
@crud.update_action("character", label="Level Up")
def level_up(existing: Character, body: LevelUpInput = Body(...)) -> Character:
return Character(
name=existing.name,
level=existing.level + body.levels,
)
Key differences from create_action():
- Route:
POST /{resource}/{resource_id}/{action_path}(includesresource_id) - The existing resource is auto-fetched via
rm.get(resource_id)and injected into the parameter named byexisting_param(default"existing") mode="update"(default) creates a new revision;mode="modify"edits the draft in-place- If the handler returns
None, no update is performed
update_action() is lazy — routes are registered at apply() time.
Async update actions¶
Both create_action() and update_action() support an async_mode parameter for
long-running operations:
-
async_mode="job"— creates a Job resource in the message queue system. The endpoint returns HTTP 202 with aJobRedirectInfo. The actual update runs in the MQ consumer, which lazy-fetches the existing resource before calling your handler. -
async_mode="background"— schedules the handler via FastAPIBackgroundTasks. The endpoint returns HTTP 202 immediately. No Job model is created (fire-and-forget).
from msgspec import Struct
from fastapi import Body
from autocrud import crud
class TrainInput(Struct):
hours: int = 1
# Job mode — creates a trackable Job resource
@crud.update_action("character", label="Train", async_mode="job")
def train(existing: Character, body: TrainInput = Body(...)) -> Character:
import time
time.sleep(body.hours * 10) # long-running training
return Character(name=existing.name, level=existing.level + body.hours)
# Background mode — fire-and-forget
@crud.update_action("character", label="Background Heal", async_mode="background")
def bg_heal(existing: Character) -> Character:
import time
time.sleep(5)
return Character(name=existing.name, level=existing.level + 1)
Key points:
- Job mode payloads automatically include
resource_id— the existing resource is lazy-fetched at job execution time (not at endpoint time). - Both
mode="update"(new revision) andmode="modify"(in-place) work with async modes. - Use
job_nameto override the auto-generated Job resource name. - If the handler returns
None, no update is performed.
Relationships (refs)¶
If you use Ref(...) fields, AutoCRUD may install relationship-related routes and behaviors.
See: docs/howto/relationships.md and docs/concepts/refs.md.