feat: add standards wiki, MCP registry, and app template
This commit is contained in:
77
standards_src/wiki/04_spec_first_routing.md
Normal file
77
standards_src/wiki/04_spec_first_routing.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# Spec-First Routing
|
||||
|
||||
## Summary
|
||||
|
||||
The OpenAPI document is the single source of truth for the HTTP contract.
|
||||
Handlers are bound to it by name; there is no decorator router.
|
||||
|
||||
---
|
||||
|
||||
## The contract
|
||||
|
||||
- `openapi.yaml` (or `.json`) declares paths, schemas, parameters, responses,
|
||||
and security.
|
||||
- A custom `operationId` names the handler function.
|
||||
- The framework (`openapi_first`) validates requests/responses against the
|
||||
spec and dispatches to the handler whose name equals `operationId`.
|
||||
|
||||
## App bootstrap
|
||||
|
||||
```python
|
||||
# main.py
|
||||
from openapi_first.app import OpenAPIFirstApp
|
||||
|
||||
app = OpenAPIFirstApp(
|
||||
openapi_path="openapi.yaml",
|
||||
routes_module=interfaces.openapi, # module whose namespace holds handlers
|
||||
title="<App> API",
|
||||
version="0.1.0",
|
||||
lifespan=lifespan,
|
||||
)
|
||||
```
|
||||
|
||||
`lifespan` calls the composition root:
|
||||
|
||||
```python
|
||||
@asynccontextmanager
|
||||
async def lifespan(app):
|
||||
app.state.resources = await init()
|
||||
yield
|
||||
await shutdown()
|
||||
```
|
||||
|
||||
## Handler registry
|
||||
|
||||
`interfaces/openapi.py` is a flat re-export of every handler, so the framework
|
||||
can resolve `operationId` across the whole app:
|
||||
|
||||
```python
|
||||
from interfaces.item.routes import *
|
||||
from interfaces.wallet.routes import *
|
||||
from interfaces.progress.sse import *
|
||||
```
|
||||
|
||||
## Handler shape
|
||||
|
||||
Handlers are thin and synchronous with respect to business logic:
|
||||
|
||||
```python
|
||||
async def create_item(request: Request, body: dict):
|
||||
svc = request.app.state.resources["item_svc"]
|
||||
return await svc.create(Item.model_validate(body))
|
||||
```
|
||||
|
||||
## Conventions
|
||||
|
||||
- `operationId` naming: `list_<resource>`, `create_<resource>`,
|
||||
`get_<resource>`, `update_<resource>`, `delete_<resource>`.
|
||||
- Read-only endpoints may use a cache decorator keyed on path + query + user.
|
||||
- Validation errors -> `400`; not found -> `404`; delete -> `204`.
|
||||
- Security is declared once in the spec and enforced by the framework; handlers
|
||||
contain no auth code.
|
||||
|
||||
## Codegen
|
||||
|
||||
The `openapi_first` library can scaffold models and route stubs from the spec,
|
||||
and ships app templates (CRUD app, model app, service). Prefer codegen over
|
||||
hand-writing boilerplate.
|
||||
Reference in New Issue
Block a user