Dev API
Pendant emberkit dev, EmberKit peut intercepter /api et /api/* et exécuter votre logique backend dans Node — sans serveur proxy séparé.
Production
Le middleware Dev API est uniquement pour le développement. En production, branchez les APIs via votre hôte (Cloudflare Workers, serveur Node, etc.). Le site Orange Ember utilise worker.ts en production et devApiPlugin en local.
Quand l'utiliser
| Approche | Idéal pour |
|---|---|
Basé sur fichiers src/routes/_api/* | Handlers REST colocalisés avec les routes, similaire à Next.js Route Handlers |
| Module handler personnalisé | Routeurs style Express existants, migrations Turso à la première requête, handleApiRequest partagé pour dev et Workers |
Recommandé — emberkit.config.ts
import { defineConfig } from '@emberkit/core';
import { emberkitVitePlugin } from '@emberkit/core/vite-plugin';
import tailwindcss from '@tailwindcss/vite';
export default defineConfig({
mode: 'ssr',
devApi: {
handler: './src/server/api-router.node.ts',
export: 'handleApiRequestNode',
prefix: '/api', // optional, default '/api'
},
vite: {
plugins: [emberkitVitePlugin(), tailwindcss()],
},
});
emberkitVitePlugin() automatiquement :
- Charge
devApidepuis ce fichier et enregistre le middleware dev - Active
sqlRawPluginpour imports*.sql?raw - Retombe sur
src/routes/_api/*quanddevApiest omis
Option B — plugins Vite explicites (avancé)
Nécessaire seulement si vous ne pouvez pas utiliser devApi dans emberkit.config.ts ou avez besoin d'un ordre de plugins personnalisé :
import {
devApiPlugin,
emberkitVitePlugin,
sqlRawPlugin,
} from '@emberkit/core/vite-plugin';
export const appVitePlugins = [
sqlRawPlugin(),
devApiPlugin({
handler: './src/server/api-router.node.ts',
export: 'handleApiRequestNode',
}),
emberkitVitePlugin(),
];
Ne dupliquez pas devApi dans config et devApiPlugin en même temps.
Handler Node personnalisé
Exportez une fonction avec la signature IncomingMessage / ServerResponse de Node :
// src/server/api-router.node.ts
import type { IncomingMessage, ServerResponse } from 'node:http';
import { handleApiRequest } from './api-router.ts';
export async function handleApiRequestNode(
req: IncomingMessage,
res: ServerResponse,
): Promise<void> {
const host = req.headers.host ?? 'localhost';
const url = `http://${host}${req.url ?? '/'}`;
const request = new Request(url, { method: req.method, headers: req.headers });
const response = await handleApiRequest(request, env);
// copy status, headers, body to res ...
}
Partagez handleApiRequest(request, env) entre dev (Node) et production (Workers) pour un comportement cohérent.
Utilisez createNodeDevApiHandler pour éviter de dupliquer le pont headers/cookies sûr :
import { createNodeDevApiHandler } from '@emberkit/core/vite-plugin';
import { handleApiRequest } from './api-router.ts';
export const handleApiRequestNode = createNodeDevApiHandler(
handleApiRequest,
() => ({
TURSO_DATABASE_URL: process.env.TURSO_DATABASE_URL ?? '',
// ...
}),
);
Routes API basées sur fichiers
Ajoutez des handlers sous src/routes/_api/ :
src/routes/_api/
health.ts → GET /api/health
blog/
list.ts → GET /api/blog/list
Quand devApi n'est pas défini en config et qu'au moins une route _api existe, EmberKit active automatiquement le routage dev API basé sur fichiers.
devApi personnalisé remplace l'auto routing
Si vous définissez devApi.handler, les routes _api basées sur fichiers ne sont pas utilisées sauf si vous les appelez depuis votre handler.
Routage des requêtes
- Le pathname de l'URL est
/apiou commence par/api/. - Le middleware dev s'exécute avant le rendu SSR des pages (SSR ignore les URLs API).
- Le module handler est chargé une fois via
server.ssrLoadModule()et mis en cache.
Tests locaux
pnpm dev
curl -s "http://localhost:4321/api/health"
curl -s "http://localhost:4321/api/blog/list?lang=en"
Si le port est occupé, EmberKit choisit le suivant libre — consultez la bannière du dev server.
Exports Vite
Depuis @emberkit/core/vite-plugin :
| Export | Description |
|---|---|
devApiPlugin(options) | Plugin Vite pour handler personnalisé |
registerDevApiMiddleware(server, options) | Enregistrer middleware sur un dev server existant |
registerFileBasedDevApiMiddleware(server) | Enregistrer routage fichiers _api |
isApiRequest(url) | Retourne true pour /api et /api/* |
incomingMessageToRequest(req) | Convertir requête Node en Fetch Request |
writeFetchResponseToNode(res, response) | Écrire Fetch Response vers Node |