TS
#astro#api#endpoints#rest#ssr#dynamic-routes

Astro: API Route (endpoint) с динамическим путём

Создание REST endpoint в Astro: APIRoute, динамический сегмент [slug], GET/POST и опциональная авторизация по заголовку.

Как использовать

  1. Скопируйте нужный фрагмент кода.
  2. Вставьте в свой проект и при необходимости измените под задачу.
  3. Проверьте зависимости и окружение (версии, переменные).

API Routes в Astro — это серверные endpoints в src/pages/. В режиме output: "static" эндпоинты вызываются при сборке; для работы по запросу нужен режим server или hybrid и для конкретного файла — export const prerender = false.

Динамический endpoint (Endpoints | Astro Docs):

// src/pages/api/blog/[slug]/view.ts
import type { APIRoute } from "astro";

export const prerender = false; // on-demand в static/hybrid

export const GET: APIRoute = async ({ params }) => {
  const { slug } = params;
  // запрос к БД: const views = await getViewsCount(slug);
  const views = 0;
  return new Response(
    JSON.stringify({ slug, views }),
    {
      status: 200,
      headers: { "Content-Type": "application/json" },
    }
  );
};

export const POST: APIRoute = async ({ params, request }) => {
  const { slug } = params;
  // await incrementViews(slug);
  return new Response(
    JSON.stringify({ success: true }),
    {
      status: 200,
      headers: { "Content-Type": "application/json" },
    }
  );
};

Несколько HTTP-методов и ALL (HTTP methods):

// src/pages/api/products/[id].ts
import type { APIRoute } from "astro";

export const GET: APIRoute = async ({ params }) => {
  return new Response(
    JSON.stringify({ id: params.id, name: "Product" }),
    { status: 200, headers: { "Content-Type": "application/json" } }
  );
};

export const PUT: APIRoute = async ({ params, request }) => {
  const body = await request.json();
  return new Response(
    JSON.stringify({ success: true }),
    { status: 200, headers: { "Content-Type": "application/json" } }
  );
};

export const DELETE: APIRoute = async ({ params }) => {
  return new Response(
    JSON.stringify({ success: true }),
    { status: 200, headers: { "Content-Type": "application/json" } }
  );
};

export const ALL: APIRoute = async ({ request }) => {
  return new Response(
    JSON.stringify({ error: `Method ${request.method} not supported` }),
    { status: 405 }
  );
};

Проверка авторизации в API Route:

// src/pages/api/admin/posts.ts
import type { APIRoute } from "astro";

const ADMIN_TOKEN = import.meta.env.ADMIN_TOKEN;

export const GET: APIRoute = async ({ request }) => {
  const token = request.headers.get("Authorization")?.replace("Bearer ", "");
  if (token !== ADMIN_TOKEN) {
    return new Response(
      JSON.stringify({ error: "Unauthorized" }),
      { status: 401, headers: { "Content-Type": "application/json" } }
    );
  }
  const posts: unknown[] = [];
  return new Response(JSON.stringify(posts), {
    status: 200,
    headers: { "Content-Type": "application/json" },
  });
};

Usage:

  • Имя файла с расширением .ts или .js задаёт путь: api/blog/[slug]/view.ts/api/blog/:slug/view.
  • Экспортируйте функции с именами методов: GET, POST, PUT, DELETE, ALL.
  • Контекст handler: { params, request, redirect } и др. (API Reference).

Notes:

⚠️ В статическом режиме для динамических путей без getStaticPaths endpoint не будет сгенерирован. Используйте output: "server" или "hybrid" и при необходимости export const prerender = false в файле endpoint.