컨텐츠로 건너뛰기

엔드포인트

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

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

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

엔드포인트는 Astro global 객체와 유사한 속성을 가진 context 객체를 수신하는 GET 함수(선택적으로 async)를 내보냅니다. 여기서는 nameurl이 포함된 Response 객체를 반환하고 Astro는 빌드 시 이를 호출하고 본문 내용을 사용하여 파일을 생성합니다.

src/pages/builtwith.json.ts
// Outputs: /builtwith.json
export async 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로 4개의 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 global 객체와 유사한 속성을 가진 context 객체를 수신하는 GET 함수를 내보낼 수 있습니다.

그러나 정적 모드와 달리 서버 모드를 구성하면 엔드포인트가 요청될 때 빌드됩니다. 이를 통해 빌드 시 사용할 수 없던 새로운 기능을 사용할 수 있으며, 요청을 수신하고 런타임 시 서버에서 코드를 안전하게 실행하는 API 라우트를 만들 수 있습니다.

경로는 기본적으로 server 모드에서 요청 시 렌더링됩니다. hybrid 모드에서는 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: 'Not found'
});
}
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} 메서드!`
})
)
}

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 });
}

엔드포인트 context는 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);
}