Fresh — это современный фреймворк для построения быстрых веб-приложений на основе Deno. Его ключевое отличие заключается в минимализме и высоком уровне производительности благодаря отсутствию сборщика и рендерингу на стороне сервера. Одной из важнейших возможностей является гибкая система middleware и плагинов, позволяющая расширять функциональность приложения без изменения его ядра.
Middleware — это функции, которые выполняются до
обработки запроса конкретным маршрутом или после него, обеспечивая
возможность управлять потоками данных, авторизацией, логированием,
кэшированием и другими аспектами работы приложения. В Fresh middleware
строятся вокруг объекта Context, который предоставляет
доступ к запросу (Request) и ответу
(Response), а также к состоянию приложения.
Основная структура middleware выглядит следующим образом:
export async function handler(req, ctx) {
// Действия до передачи запроса дальше
const result = await ctx.next(); // Передача запроса следующему middleware или обработчику
// Действия после обработки запроса
return result;
}
Ключевые моменты:
ctx.next() обязателен для передачи управления
следующему уровню обработки.Плагины в Fresh позволяют добавлять middleware и расширять возможности фреймворка без модификации исходного кода приложения. Плагин — это модуль, который регистрирует один или несколько middleware в системе.
Простейший пример плагина:
export default function myPlugin() {
return {
async onRequest(ctx) {
console.log("Запрос получен:", ctx.req.url);
return await ctx.next();
},
};
}
Особенности работы с плагинами:
onRequest,
onResponse или другие хуки.state) приложения
для хранения данных между запросами.Подключение плагина выполняется на уровне приложения через конфигурацию маршрутов. Например:
import { start } from "fresh/server.ts";
import myPlugin from "./plugins/myPlugin.js";
await start({
plugins: [myPlugin()],
});
Важные моменты:
Middleware можно оформлять как отдельные функции и регистрировать их через плагины. Пример middleware для логирования времени выполнения запроса:
export function timingMiddleware() {
return {
async onRequest(ctx) {
const start = performance.now();
const result = await ctx.next();
const duration = performance.now() - start;
console.log(`Запрос ${ctx.req.url} обработан за ${duration.toFixed(2)}ms`);
return result;
},
};
}
Подключение:
import { start } from "fresh/server.ts";
import { timingMiddleware } from "./plugins/timingMiddleware.js";
await start({
plugins: [timingMiddleware()],
});
Плагины и middleware могут использовать глобальное или локальное состояние. Это удобно для кеширования, аутентификации или хранения пользовательских данных между запросами:
export function authPlugin() {
return {
async onRequest(ctx) {
const token = ctx.req.headers.get("Authorization");
ctx.state.user = token ? decodeToken(token) : null;
return await ctx.next();
},
};
}
onRequest каждого
middleware последовательно.onResponse хуки (если они определены).Правильная организация порядка выполнения middleware критична для безопасности, логирования и производительности.
Middleware могут перехватывать ошибки, возникающие в последующих слоях обработки:
export function errorHandler() {
return {
async onRequest(ctx) {
try {
return await ctx.next();
} catch (err) {
console.error("Ошибка в обработке запроса:", err);
return new Response("Internal Server Error", { status: 500 });
}
},
};
}
Этот подход позволяет централизованно управлять ошибками и предотвращает падение всего приложения.
ctx.next()
для передачи управления.ctx.state) доступно для всех
middleware и плагинов.Эти принципы обеспечивают масштабируемость, высокую производительность и модульность приложений на Fresh.