Aller au contenu

Quickstart en 5 minutes

De zéro à un endpoint qui répond, sans cookiecutter (pour comprendre ce qui se passe).

Pressé ?

Allez directement au scaffold cookiecutter — un service complet avec tests, Docker, CI en 30 secondes.

1. Installer

python3.14 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install "mic-core[fastapi]"

2. Écrire un handler

main.py :

from fastapi import FastAPI
from mic.contracts import StrictSchema, wrap_http_success
from mic.http import HttpResponseSpec, HttpRouteSpec
from mic.fastapi import build_fastapi_router
from mic.model.errors import DomainError


# 1. Schéma d'entrée strict
class CreateItem(StrictSchema):
    name: str
    quantity: int = 0


# 2. Handler agnostique
def _create(*, payload: CreateItem) -> HttpResponseSpec:
    if payload.quantity < 0:
        raise DomainError(
            code="items.invalid_quantity",
            message="quantity must be >= 0",
            details={"received_quantity": payload.quantity},
        )
    return HttpResponseSpec(
        status_code=201,
        body=wrap_http_success(
            {"name": payload.name, "qty": payload.quantity}
        ),
    )


# 3. Câblage
routes = (
    HttpRouteSpec(
        method="POST",
        path="/api/v1/items",
        name="items_v1_create",
        category="items",
        handler=_create,
    ),
)

app = FastAPI()
app.include_router(build_fastapi_router(routes=routes))

3. Lancer

pip install uvicorn
uvicorn main:app --reload

4. Appeler

# Happy path
curl -X POST http://localhost:8000/api/v1/items \
    -H "Content-Type: application/json" \
    -d '{"name": "widget", "quantity": 3}'
# {"success":true,"data":{"name":"widget","qty":3},"meta":null}

# DomainError
curl -X POST http://localhost:8000/api/v1/items \
    -H "Content-Type: application/json" \
    -d '{"name": "x", "quantity": -1}'
# 400 {"success":false,"code":"items.invalid_quantity","message":"...","details":{"received_quantity":-1}}

# extra=forbid
curl -X POST http://localhost:8000/api/v1/items \
    -H "Content-Type: application/json" \
    -d '{"name": "x", "secret": "boom"}'
# 400 {"success":false,"code":"http.validation_error","message":"...","details":[...]}

5. Passer à Litestar (sans toucher le handler)

pip install "mic-core[litestar]"

Modifiez juste l'assemblage final :

# Avant (FastAPI)
from fastapi import FastAPI
from mic.fastapi import build_fastapi_router

app = FastAPI()
app.include_router(build_fastapi_router(routes=routes))

# Après (Litestar)
from litestar import Litestar
from mic.litestar import build_litestar_router

app = Litestar(route_handlers=[build_litestar_router(routes=routes)])

Le handler _create n'a pas changé d'une virgule. Les curl ci-dessus produisent les mêmes réponses. C'est ça, MIC.

Et après ?