컨텐츠로 건너뛰기

엔드포인트

Astro를 사용하면 모든 종류의 데이터를 제공하는 사용자 정의 엔드포인트를 만들 수 있습니다. 이를 사용하여 이미지를 생성하거나, RSS 문서를 노출하거나, 사이트의 전체 API를 빌드하기 위한 API 라우트로 사용할 수 있습니다.

정적으로 생성된 사이트에서 사용자 정의 엔드포인트는 빌드 시 호출되어 정적 파일을 생성합니다. SSR 모드를 선택하면 사용자 정의 엔드포인트가 요청 시 호출되는 라이브 서버 엔드포인트로 전환됩니다. 정적 및 SSR 엔드포인트는 유사하게 정의되지만 SSR 엔드포인트는 추가 기능을 지원합니다.

사용자 정의 엔드포인트를 생성하려면 /pages 디렉터리에 .js 또는 .ts 파일을 추가하세요. 빌드 프로세스 중에 .js 또는 .ts 확장자가 제거되므로 파일 이름에 생성하려는 데이터의 확장자를 포함해야 합니다. 예를 들어 src/pages/data.json.ts/data.json 엔드포인트를 빌드합니다.

엔드포인트는 전역 Astro 객체와 유사한 속성을 가진 컨텍스트 객체를 받는 GET 함수 (선택적으로 async)를 내보냅니다. 여기서 nameurl을 사용하는 Response 객체를 반환하며, Astro는 빌드 시 이를 호출하고 본문 콘텐츠를 사용하여 파일을 생성합니다.

src/pages/builtwith.json.ts
// 출력: /builtwith.json
export function GET({ params, request }) {
return new Response(
JSON.stringify({
name: "Astro",
url: "https://astro.build/",
}),
);
}

Astro v3.0부터는 반환된 Response 객체가 더 이상 encoding 속성을 포함할 필요가 없습니다. 예를 들어 바이너리 .png 이미지를 생성하려면 다음을 수행합니다.

src/pages/astro-logo.png.ts
export async function GET({ params, request }) {
const response = await fetch(
"https://docs.astro.build/assets/full-logo-light.png",
);
return new Response(await response.arrayBuffer());
}

APIRoute 타입을 사용하여 엔드포인트 함수의 타입을 지정할 수도 있습니다.

import type { APIRoute } from "astro";
export const GET: APIRoute = async ({ params, request }) => {...}

엔드포인트는 페이지와 동일한 동적 라우팅 기능을 지원합니다. 파일의 이름을 대괄호로 묶인 매개변수 이름으로 지정하고 getStaticPaths() 함수를 내보냅니다. 그러면 엔드포인트 함수에 전달된 params 속성을 사용하여 매개변수에 액세스할 수 있습니다.

src/pages/api/[id].json.ts
import type { APIRoute } from "astro";
const usernames = ["Sarah", "Chris", "Yan", "Elian"];
export const GET: APIRoute = ({ params, request }) => {
const id = params.id;
return new Response(
JSON.stringify({
name: usernames[id],
}),
);
};
export function getStaticPaths() {
return [
{ params: { id: "0" } },
{ params: { id: "1" } },
{ params: { id: "2" } },
{ params: { id: "3" } },
];
}

이렇게 하면 빌드 시 /api/0.json, /api/1.json, /api/2.json, /api/3.json의 네 가지 JSON 엔드포인트가 생성됩니다. 엔드포인트의 동적 라우팅은 페이지의 동적 라우팅과 동일하게 작동하지만, 엔드포인트는 컴포넌트가 아닌 함수이므로 props는 지원되지 않습니다.

모든 엔드포인트는 request 속성을 받지만, 정적 모드에서는 request.url에만 액세스할 수 있습니다. 이는 현재 엔드포인트의 전체 URL을 반환하며 페이지의 Astro.request.url과 동일하게 작동합니다.

src/pages/request-path.json.ts
import type { APIRoute } from "astro";
export const GET: APIRoute = ({ params, request }) => {
return new Response(
JSON.stringify({
path: new URL(request.url).pathname,
}),
);
};

서버 엔드포인트 (API 라우트)

섹션 제목: 서버 엔드포인트 (API 라우트)

정적 파일 엔드포인트 섹션에서 설명된 모든 내용은 SSR 모드에서도 사용할 수 있습니다. 즉, 파일은 전역 Astro 객체와 유사한 속성을 가진 컨텍스트 객체를 받는 GET 함수를 내보낼 수 있습니다.

그러나 static 모드와 달리, 라우트에 대한 요청 시 렌더링을 활성화하면 엔드포인트도 요청 시 빌드됩니다. 이를 통해 빌드 시에는 사용할 수 없는 새로운 기능이 잠금 해제되고, 런타임에 요청을 수신하고 서버에서 코드를 안전하게 실행하는 API 라우트를 빌드할 수 있습니다.

라우트는 server 모드에서 기본적으로 요청 시 렌더링됩니다. static 모드에서는 export const prerender = false를 사용하여 각각의 사용자 정의 엔드포인트에 대한 사전 렌더링을 선택 해제해야 합니다.

서버 엔드포인트는 getStaticPaths를 내보내지 않고도 params에 액세스할 수 있으며, 상태 코드 및 헤더를 설정할 수 있는 Response 객체를 반환할 수 있습니다.

src/pages/[id].json.js
import { getProduct } from "../db";
export async function GET({ params }) {
const id = params.id;
const product = await getProduct(id);
if (!product) {
return new Response(null, {
status: 404,
statusText: "찾을 수 없음",
});
}
return new Response(JSON.stringify(product), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
}

이렇게 하면 동적 라우트와 일치하는 모든 요청에 응답합니다. 예를 들어 /helmet.json으로 이동하면 params.idhelmet으로 설정됩니다. helmet이 모의 제품 데이터베이스에 존재하면 엔드포인트는 Response 객체를 사용하여 JSON으로 응답하고 성공적인 HTTP 상태 코드를 반환합니다. 그렇지 않으면 Response 객체를 사용하여 404로 응답합니다.

SSR 모드에서는 특정 공급자가 이미지를 반환하기 위해 Content-Type 헤더를 요구합니다. 이 경우 Response 객체를 사용하여 headers 속성을 지정합니다. 예를 들어 바이너리 .png 이미지를 생성하려면 다음을 수행합니다.

src/pages/astro-logo.png.ts
export async function GET({ params, request }) {
const response = await fetch(
"https://docs.astro.build/assets/full-logo-light.png",
);
const buffer = Buffer.from(await response.arrayBuffer());
return new Response(buffer, {
headers: { "Content-Type": "image/png" },
});
}

GET 함수 외에도 모든 HTTP 메서드의 이름을 가진 함수를 내보낼 수 있습니다. 요청이 들어오면 Astro는 메서드를 확인하고 해당 함수를 호출합니다.

해당하는 내보낸 함수가 없는 모든 메서드와 일치하도록 ALL 함수를 내보낼 수도 있습니다. 일치하는 메서드가 없는 요청이 있으면 사이트의 404 페이지로 리디렉션됩니다.

src/pages/methods.json.ts
export const GET: APIRoute = ({ params, request }) => {
return new Response(
JSON.stringify({
message: "GET 메서드",
}),
);
};
export const POST: APIRoute = ({ request }) => {
return new Response(
JSON.stringify({
message: "POST 메서드",
}),
);
};
export const DELETE: APIRoute = ({ request }) => {
return new Response(
JSON.stringify({
message: "DELETE 메서드",
}),
);
};
export const ALL: APIRoute = ({ request }) => {
return new Response(
JSON.stringify({
message: `${request.method} 메서드`,
}),
);
};

GET 함수는 정의했지만 HEAD 함수는 정의하지 않은 경우, Astro는 GET 함수를 호출하고 응답에서 본문을 제거하여 HEAD 요청을 자동으로 처리합니다.

SSR 모드에서 request 속성은 현재 요청을 참조하는 완전히 사용 가능한 Request 객체를 반환합니다. 이를 통해 데이터를 수락하고 헤더를 확인할 수 있습니다.

src/pages/test-post.json.ts
export const POST: APIRoute = async ({ request }) => {
if (request.headers.get("Content-Type") === "application/json") {
const body = await request.json();
const name = body.name;
return new Response(
JSON.stringify({
message: "이름: " + name,
}),
{
status: 200,
},
);
}
return new Response(null, { status: 400 });
};

엔드포인트 컨텍스트는 Astro.redirect와 유사한 redirect() 유틸리티를 내보냅니다.

src/pages/links/[id].js
import { getLinkUrl } from "../db";
export async function GET({ params, redirect }) {
const { id } = params;
const link = await getLinkUrl(id);
if (!link) {
return new Response(null, {
status: 404,
statusText: "찾을 수 없음",
});
}
return redirect(link, 307);
}
기여하기 커뮤니티 후원하기