Adapter Server Entrypoint API 참조
이 모듈은 어댑터 작성자가 개발 모드에서 렌더링된 페이지나 astro build를 통해 미리 빌드된 페이지를 지원하면서 서버 엔트리포인트를 빌드하는 데 도움을 줍니다.
astro/app은 내부적으로 Astro의 공식 서버 어댑터에 사용되며, 특정 런타임이나 배포 호스트를 위한 커스텀 어댑터를 빌드하려는 사용자도 공개적으로 사용할 수 있습니다.
어댑터를 NPM에 게시 (EN)할 때 적절한 키워드를 사용하여 통합 디렉터리에 나열되도록 하세요.
Astro는 표준 Request 및 Response 객체를 사용합니다. 요청/응답에 다른 API를 사용하는 호스트는 어댑터에서 이러한 유형으로 변환해야 합니다. 예를 들어, Astro는 NodeJS 작업을 위한 도우미를 제공합니다.
astro/app/entrypoint에서 가져오기
섹션 제목: “astro/app/entrypoint에서 가져오기”app 모듈의 entrypoint 디렉터리에서 다음 도우미를 가져옵니다.
import { createApp} from "astro/app/entrypoint";createApp()
섹션 제목: “createApp()”타입: (options?: { streaming: boolean }) => App
astro@6.0.0
어댑터의 서버 엔트리포인트를 빌드할 때 표준 Request 및 Response 객체로 작업하는 메서드가 포함된 App 인스턴스를 반환합니다.
import { createApp } from "astro/app/entrypoint";import http from "http";
const app = createApp();
addEventListener("fetch", event => { event.respondWith( app.render(event.request) );});createApp() 함수는 다음 옵션을 허용합니다.
options.streaming
섹션 제목: “options.streaming”타입: boolean
기본값: true
HTML 스트리밍 활성화 여부를 정의합니다. 스트리밍은 성능을 향상시키고 일반적으로 더 나은 방문자 경험을 제공하므로, 대부분의 경우 스트리밍을 비활성화하는 것은 권장되지 않습니다.
HTML 스트리밍은 문서를 청크로 나누어 네트워크를 통해 전송하고 페이지에 순서대로 렌더링합니다. 이는 일반적으로 방문자가 가능한 한 빨리 HTML을 볼 수 있게 하지만, 네트워크 조건 및 데이터 가져오기 대기와 같은 요인으로 인해 페이지 렌더링이 차단될 수 있습니다.
하지만 HTML 스트리밍을 비활성화해야 하는 경우 (예: 호스트가 CDN 수준에서 스트리밍되지 않는 HTML 캐싱만 지원하는 경우), createApp()에 streaming: false를 전달하여 기본 동작을 거부할 수 있습니다.
import { createApp } from 'astro/app/entrypoint'
const app = createApp({ streaming: false })App 인스턴스
섹션 제목: “App 인스턴스”createApp() 함수는 다음 메서드를 가진 클래스 인스턴스를 반환합니다.
app.render()
섹션 제목: “app.render()”타입: (request: Request, options?: RenderOptions) => Promise<Response>
Request와 일치하는 Astro 페이지를 호출하고 렌더링한 후 Response 객체에 대한 프로미스를 반환합니다. 이는 페이지를 렌더링하지 않는 API 라우트에서도 작동합니다.
const response = await app.render(request);app.match()
섹션 제목: “app.match()”타입: (request: Request, allowPrerenderedRoutes = false) => RouteData | undefined
요청이 Astro 앱의 라우팅 규칙과 일치하는지 확인합니다.
if(app.match(request)) { const response = await app.render(request);}404.astro 파일을 제공하면 Astro가 404를 처리하므로 일반적으로 .match를 사용하지 않고 app.render(request)를 호출할 수 있습니다. 404를 다른 방식으로 처리하고 싶을 때 app.match(request)를 사용하세요.
기본적으로 미리 렌더링된 라우트는 일치하더라도 반환되지 않습니다. 두 번째 인수로 true를 사용하여 이 동작을 변경할 수 있습니다.
app.getAdapterLogger()
섹션 제목: “app.getAdapterLogger()”타입: () => AstroIntegrationLogger
astro@v3.0.0
어댑터의 런타임 환경에서 사용할 수 있는 Astro 로거 인스턴스를 반환합니다.
const logger = app.getAdapterLogger();try { /* 에러가 발생할 수 있는 로직 */} catch { logger.error("Astro 로거를 사용한 사용자 정의 에러 메시지.");}app.getAllowedDomains()
섹션 제목: “app.getAllowedDomains()”타입: () => Partial<RemotePattern>[] | undefined
astro@5.14.2
security.allowedDomains에 구성된 대로 온디맨드 렌더링을 사용할 때 들어오는 요청에 대해 허용된 호스트 패턴 목록을 반환합니다.
app.removeBase()
섹션 제목: “app.removeBase()”타입: (pathname: string) => string
astro@1.6.4
주어진 경로에서 기본 경로를 제거합니다. 파일 시스템에서 자산을 조회해야 할 때 유용합니다.
app.setCookieHeaders()
섹션 제목: “app.setCookieHeaders()”타입: (response: Response) => Generator<string, string[], any>
astro@1.4.0
Response 객체에서 개별 쿠키 헤더 값을 생성하는 제너레이터를 반환합니다. 이는 요청 처리 중에 설정되었을 수 있는 여러 쿠키를 적절하게 처리하는 데 사용됩니다.
다음 예시는 응답에서 얻은 각 헤더에 대해 Set-Cookie 헤더를 추가합니다.
for (const setCookieHeader of app.setCookieHeaders(response)) { response.headers.append('Set-Cookie', setCookieHeader);}astro/app/node에서 가져오기
섹션 제목: “astro/app/node에서 가져오기”app 모듈의 node 디렉터리에서 다음 도우미를 가져옵니다.
import { createRequest, writeResponse} from "astro/app/node";이 모듈은 createApp()에서 제공하는 메서드와 함께 사용되어 NodeJS IncomingMessage를 웹 표준 Request로 변환하고 웹 표준 Response를 NodeJS ServerResponse로 스트리밍합니다.
createRequest()
섹션 제목: “createRequest()”타입: (req: NodeRequest, options?: { skipBody?: boolean; allowedDomains?: Partial<RemotePattern>[]; }) => Request
astro@6.0.0
NodeJS IncomingMessage를 표준 Request 객체로 변환합니다. 요청이 생성되는 방식을 추가로 제어하기 위해 선택적 객체를 두 번째 인수로 전달할 수 있습니다. 이는 본문을 무시하고 싶거나 (기본값은 false) 구성된 allowedDomains를 요청에 전달하려는 경우 유용합니다.
다음 예시는 Request를 생성하고 이를 app.render()에 전달합니다.
import { createApp } from "astro/app/entrypoint";import { createRequest } from "astro/app/node";import { createServer } from "node:http";
const app = createApp();
const server = createServer(async (req, res) => { const request = createRequest(req); const response = await app.render(request);})writeResponse()
섹션 제목: “writeResponse()”타입: (source: Response, destination: ServerResponse) => Promise<ServerResponse<IncomingMessage> | undefined>
astro@6.0.0
웹 표준 Response를 NodeJS 서버 응답으로 스트리밍합니다. 이 함수는 Response 객체와 초기 ServerResponse를 취한 다음 ServerResponse 객체의 프로미스를 반환합니다.
다음 예시는 Request를 생성하고 이를 app.render()에 전달한 후 응답을 작성합니다.
import { createApp } from "astro/app/entrypoint";import { createRequest, writeResponse } from "astro/app/node";import { createServer } from "node:http";
const app = createApp();
const server = createServer(async (req, res) => { const request = createRequest(req); const response = await app.render(request); await writeResponse(response, res);})astro/app 타입
섹션 제목: “astro/app 타입”app 모듈에서 다음 타입을 가져옵니다.
import type { RenderOptions,} from "astro/app";RenderOptions
섹션 제목: “RenderOptions”타입: {addCookieHeader?: boolean; clientAddress?: string; locals?: object; prerenderedErrorPageFetch?: (url: ErrorPagePath) => Promise<Response>; routeData?: RouteData;}
라우트 렌더링을 제어하기 위한 옵션을 설명합니다.
RenderOptions.addCookieHeader
섹션 제목: “RenderOptions.addCookieHeader”타입: boolean
기본값: false
Astro.cookie.set()으로 작성된 모든 쿠키를 응답 헤더에 자동으로 추가할지 여부입니다.
true로 설정하면 응답의 Set-Cookie 헤더에 쉼표로 구분된 키-값 쌍으로 추가됩니다. 표준 response.headers.getSetCookie() API를 사용하여 개별적으로 읽을 수 있습니다.
const response = await app.render(request, { addCookieHeader: true });RenderOptions.clientAddress
섹션 제목: “RenderOptions.clientAddress”타입: string
기본값: request[Symbol.for("astro.clientAddress")]
페이지에서는 Astro.clientAddress로, API 라우트 및 미들웨어에서는 ctx.clientAddress로 사용할 수 있는 클라이언트 IP 주소입니다.
아래 예시는 x-forwarded-for 헤더를 읽고 이를 clientAddress로 전달합니다. 이 값은 사용자가 Astro.clientAddress로 사용할 수 있게 됩니다.
const clientAddress = request.headers.get("x-forwarded-for");const response = await app.render(request, { clientAddress });RenderOptions.locals
섹션 제목: “RenderOptions.locals”타입: object
요청의 수명 주기 동안 정보를 저장하고 액세스하는 데 사용되는 context.locals 객체입니다.
아래 예시는 x-private-header라는 헤더를 읽고 객체로 파싱을 시도한 다음 locals에 전달하며, 이는 모든 미들웨어 함수로 전달될 수 있습니다.
const privateHeader = request.headers.get("x-private-header");let locals = {};try { if (privateHeader) { locals = JSON.parse(privateHeader); }} finally { const response = await app.render(request, { locals });}RenderOptions.prerenderedErrorPageFetch()
섹션 제목: “RenderOptions.prerenderedErrorPageFetch()”타입: (url: ErrorPagePath) => Promise<Response>
기본값: fetch
astro@5.6.0
미리 렌더링된 에러 페이지를 가져오기 위한 커스텀 구현을 제공할 수 있는 함수입니다.
이 함수는 기본 fetch() 동작을 재정의하는 데 사용됩니다. 예를 들어, fetch()를 사용할 수 없거나 서버 자체를 호출할 수 없는 경우에 사용합니다.
다음 예시는 HTTP 호출을 수행하는 대신 디스크에서 500.html 및 404.html을 읽습니다.
return app.render(request, { prerenderedErrorPageFetch: async (url: string): Promise<Response> => { if (url.includes("/500")) { const content = await fs.promises.readFile("500.html", "utf-8"); return new Response(content, { status: 500, headers: { "Content-Type": "text/html" }, }); }
const content = await fs.promises.readFile("404.html", "utf-8"); return new Response(content, { status: 404, headers: { "Content-Type": "text/html" }, }); }});제공되지 않으면 Astro는 에러 페이지를 가져오기 위해 기본 동작으로 돌아갑니다.
RenderOptions.routeData
섹션 제목: “RenderOptions.routeData”타입: RouteData
기본값: app.match(request)
라우트에 대한 정보를 정의합니다. 렌더링할 라우트를 이미 알고 있는 경우 유용합니다. 이렇게 하면 렌더링할 라우트를 결정하기 위해 내부적으로 app.match()를 호출하는 과정을 건너뜁니다.
const routeData = app.match(request);if (routeData) { return app.render(request, { routeData });} else { /* 어댑터 관련 404 응답 */ return new Response(..., { status: 404 });}