Pipeline d'une requête
Comment les garde-fous de sécurité vivent dans le pipeline Elysia, et comment le typage circule jusqu'aux clients.
Le point d'avoir choisi Elysia plutôt qu'un routeur minimal, c'est d'encoder les garde-fous de sécurité dans le pipeline du framework, pas de les disperser dans les handlers. La friction anti-abus et la proportionnalité deviennent déclaratives sur chaque route.
Le module posts et le plugin safety décrits ici sont conçus mais pas encore construits. Les extraits montrent le pattern cible, cohérent avec le schéma déjà en place.
Les macros de sécurité
Une macro Elysia compose de la logique de cycle de vie réutilisable, typée, activable par clé sur une route. On définit une fois les garde-fous, on les applique partout.
// apps/server/src/plugins/safety.ts
export const safety = new Elysia({ name: "safety" }).macro({
auth: {
resolve: async ({ request, status }) => {
const session = await auth.api.getSession({ headers: request.headers });
if (!session) return status(401, "Sign in required");
return { user: session.user };
},
},
requireTrust: (min: "new" | "active" | "trusted") => ({
resolve: ({ user, status }) =>
trustRank(user.trustLevel) < trustRank(min)
? status(403, "Not allowed yet")
: {},
}),
rateLimit: (bucket: string) => ({
beforeHandle: ({ user, status }) =>
limiter.ok(bucket, user.id) ? undefined : status(429, "Slow down"),
}),
});Une route qui les utilise
Une instance Elysia égale un module. La route déclare ses garde-fous, valide son corps avec un schéma Zod partagé, et délègue au service.
// apps/server/src/modules/posts/index.ts
export const posts = new Elysia({ prefix: "/posts" })
.use(safety)
.post("/", ({ user, body }) => PostService.create(user.id, body), {
auth: true,
requireTrust: "active",
rateLimit: "post:create",
body: CreatePost,
});Un post qui exige d'être connecté, active au minimum, limité en débit, et validé. Tout est déclaratif et typé, jusqu'au client.
Le chemin d'une requête
Les garde-fous s'exécutent dans l'ordre, avant le code métier. Un échec s'arrête net sur un code de statut clair, la logique de création n'est jamais atteinte.
Le typage de bout en bout
La couche API prévue est Eden Treaty. Le client web et le client natif héritent directement des types du serveur Elysia, sans duplication ni génération manuelle. Un changement de contrat côté serveur se répercute à la compilation côté client, ce qui rend les erreurs de bord visibles avant l'exécution.
Le socle a été scaffoldé avec l'option --api none, donc seul le transport de l'authentification est câblé aujourd'hui. Brancher Eden Treaty est la première brique du backend métier.