Adapters
deno-inertia utilise exclusivement les Web API (Request/Response). Les adapters font le pont entre ces types standards et les frameworks qui ont leurs propres abstractions (Oak, Hono).
std/http — aucun adapter nécessaire
std/http et createRouter() travaillent directement avec Request/Response. Aucun adapter n'est requis.
import { createInertia, createRouter } from "deno-inertia"
const inertia = createInertia({ /* ... */ })
const router = createRouter()
router.get("/", (req) => inertia.render(req, "Home", {}))
Deno.serve({ port: 3000 }, router.handler)Hono — deno-inertia/hono
Hono utilise nativement les Web API — ses handlers reçoivent et retournent des Request/Response standards. L'adapter fournit uniquement toWebRequest(c) pour extraire le Request du contexte Hono.
Import
// deno.json
{
"imports": {
"deno-inertia": "jsr:@streemkit/inertia-deno",
"deno-inertia/hono": "jsr:@streemkit/inertia-deno/hono",
"hono": "jsr:@hono/hono@^4"
}
}toWebRequest(c)
import { createInertia } from "deno-inertia"
import { toWebRequest } from "deno-inertia/hono"
import { Hono } from "hono"
const inertia = createInertia({ /* ... */ })
const app = new Hono()
app.get("/", (c) =>
inertia.render(toWebRequest(c), "Home", { title: "Accueil" })
)
app.post("/form", async (c) => {
const body = await c.req.parseBody()
const errors = validate(body)
if (errors) {
return inertia.renderWithErrors(toWebRequest(c), "Form", {}, errors)
}
return inertia.redirect("/merci")
})
Deno.serve({ port: 3000 }, app.fetch)Pourquoi pas
c.req.rawdirectement ?toWebRequest(c)est l'équivalent exact dec.req.raw. Il est fourni pour la symétrie avec l'adapter Oak et pour clarifier l'intention. Les deux approches fonctionnent.
serveAssets(distDir, base?)
Middleware Hono qui sert les assets Vite compilés depuis dist/ avec Cache-Control: public, max-age=31536000, immutable (noms de fichiers hashés).
import { serveAssets } from "deno-inertia/hono"
if (Deno.env.get("PROD_MODE") === "1") {
app.use("/assets/*", serveAssets("dist"))
}- Rejette les path traversal (
..) avec 403 - Détecte automatiquement le type MIME depuis l'extension
base— préfixe URL à retirer, défaut :"/assets/"
Pas d'applyResponse
Contrairement à Oak, Hono retourne directement des Response depuis ses handlers. Puisque deno-inertia produit nativement des Response, aucune conversion n'est nécessaire en retour — on retourne directement le résultat de render().
Oak — deno-inertia/oak
Oak utilise son propre système de contexte (Context) qui abstrait Request et Response. L'adapter fournit deux fonctions :
toWebRequest(ctx)— convertit le contexte Oak enRequestWeb APIapplyResponse(ctx, res)— applique uneResponseWeb API sur le contexte Oak
Import
// deno.json
{
"imports": {
"deno-inertia": "jsr:@streemkit/inertia-deno",
"deno-inertia/oak": "jsr:@streemkit/inertia-deno/oak",
"@oak/oak": "jsr:@oak/oak@^17"
}
}toWebRequest(ctx)
Reconstruit un Request Web API depuis le contexte Oak.
import { toWebRequest } from "deno-inertia/oak"
router.get("/", async (ctx) => {
const req = toWebRequest(ctx)
const res = await inertia.render(req, "Home", {})
await applyResponse(ctx, res)
})applyResponse(ctx, res)
Applique une Response Web API sur le contexte Oak :
- Copie le status HTTP
- Copie tous les headers (
Set-Cookie,X-Inertia,Vary, etc.) - Gère les redirections 303 (SPA POST → GET)
- Gère les 409 (version mismatch — seul
X-Inertia-Locationcompte) - Écrit le corps (HTML ou JSON)
import { createInertia } from "deno-inertia"
import { toWebRequest, applyResponse } from "deno-inertia/oak"
import { Application, Router } from "@oak/oak"
const inertia = createInertia({ /* ... */ })
const app = new Application()
const router = new Router()
router.get("/", async (ctx) => {
const req = toWebRequest(ctx)
const res = await inertia.render(req, "Home", {})
await applyResponse(ctx, res)
})
router.post("/form", async (ctx) => {
const body = await ctx.request.body.formData()
const errors = validate(Object.fromEntries(body))
const req = toWebRequest(ctx)
if (errors) {
const res = await inertia.renderWithErrors(req, "Form", {}, errors)
await applyResponse(ctx, res)
return
}
await applyResponse(ctx, inertia.redirect("/merci"))
})
app.use(router.routes())
app.use(router.allowedMethods())
app.listen({ port: 3000 })Pourquoi des packages séparés ?
Les adapters sont dans des exports séparés (./hono, ./oak) pour ne pas forcer les dépendances sur tous les projets. Un projet qui utilise uniquement Hono ne télécharge pas Oak, et inversement.
| Import | Dépendance ajoutée |
|---|---|
deno-inertia | aucune (Web API pure) |
deno-inertia/hono | @hono/hono |
deno-inertia/oak | @oak/oak |
Créer un adapter personnalisé
Pour tout framework qui expose un Request Web API, l'intégration est triviale :
// Framework hypothétique
framework.use(async (ctx, next) => {
const req = ctx.webRequest // déjà un Request standard
const res = await router.handler(req)
ctx.sendResponse(res)
})Si le framework n'expose pas de Request standard, il suffit d'en reconstruire un :
function toWebRequest(ctx: CustomCtx): Request {
return new Request(ctx.url, {
method: ctx.method,
headers: new Headers(ctx.headers),
body: ctx.hasBody ? ctx.rawBody : undefined,
})
}