Fresh — это современный фреймворк для построения веб-приложений на базе Deno, ориентированный на скорость и минимализм. Основная философия Fresh заключается в том, чтобы исключить избыточность клиентского JavaScript там, где он не нужен, и использовать серверный рендеринг с обновлением только необходимых частей страницы. В контексте версионирования API это становится особенно актуально, поскольку Fresh позволяет гибко управлять маршрутизацией и структурой данных без усложнения клиентской логики.
Маршрутизация в Fresh строится на файловой системе проекта. Каждый
файл в папке routes автоматически становится маршрутом.
Например, файл routes/api/users.ts будет доступен по пути
/api/users.
Ключевые моменты маршрутизации:
[param].ts.routes/api/v1 и routes/api/v2,
сохраняя старые версии API.handler, которая
получает объект Request и возвращает объект
Response.// routes/api/v1/users.ts
import { Handlers } from "$fresh/server.ts";
export const handler: Handlers = {
async GET(req) {
return new Response(JSON.stringify([{ id: 1, name: "Alice" }]), {
headers: { "Content-Type": "application/json" },
});
},
};
Версионирование API необходимо для безопасного внедрения новых функций без нарушения совместимости со старыми клиентами. В Fresh рекомендуется использовать папки для каждой версии API, что позволяет изолировать логику и постепенно переносить клиентов на новые версии.
Пример структуры:
routes/
api/
v1/
users.ts
v2/
users.ts
Преимущества такого подхода:
Каждый обработчик в Fresh работает с объектами Request и
Response. Для версионирования API важно поддерживать
одинаковый интерфейс данных или документировать различия между
версиями.
// routes/api/v2/users.ts
import { Handlers } from "$fresh/server.ts";
export const handler: Handlers = {
async GET(req) {
const users = [{ id: 1, fullName: "Alice Smith" }];
return new Response(JSON.stringify(users), {
headers: { "Content-Type": "application/json" },
});
},
};
В версии v2 структура ответа изменилась: поле
name заменено на fullName. Такой подход
позволяет клиентам, использующим старую версию API, оставаться
функциональными, пока новые клиенты адаптируются к изменениям.
Fresh использует возможности Deno для автоматического кэширования модулей и версионирования зависимостей через URL. В контексте API это облегчает поддержку стабильных версий библиотек и уменьшает риск несовместимости.
Советы по кэшированию данных:
Cache-Control для статических
данных.ETag или
Last-Modified.Тестирование является критическим этапом при работе с несколькими версиями API. Fresh интегрируется с Deno Test для юнит- и интеграционных тестов.
// tests/api_v1_test.ts
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
import { handler } from "../routes/api/v1/users.ts";
Deno.test("v1 users GET", async () => {
const response = await handler.GET(new Request("http://localhost/api/v1/users"));
const data = await response.json();
assertEquals(data[0].name, "Alice");
});
Тесты позволяют уверенно выпускать новые версии API, минимизируя вероятность регрессий.
Fresh поддерживает инкрементальное обновление страниц без полного перерендеринга. Это важно для API, которые обслуживают фронтенд-приложения в реальном времени, поскольку позволяет:
Использование Fresh для версионирования API сочетает преимущества серверного рендеринга, строгой организации маршрутов и гибкого управления версиями. Структурирование проекта через папки с версиями, стандартизированные обработчики запросов и встроенное тестирование создают надежную основу для масштабируемых веб-приложений с поддержкой нескольких версий API одновременно.