미들웨어
미들웨어를 사용하면 페이지나 엔드포인트가 렌더링될 때마다 요청과 응답을 가로채고 동작을 동적으로 추가할 수 있습니다.
또한 이를 통해 모든 Astro 컴포넌트 및 API 엔드포인트에서 사용할 수 있는 locals
객체를 변경하여 엔드포인트와 페이지 전반에 걸쳐 요청별 정보를 설정하고 공유할 수 있습니다.
미들웨어는 SSG 및 SSR Astro 프로젝트 모두에서 사용할 수 있습니다.
사용 방법
섹션 제목: 사용 방법-
src/middleware.js|ts
파일을 생성합니다. (또는src/middleware/index.js|ts
파일을 생성할 수도 있습니다.) -
이 파일에서
context
객체와next()
함수를 전달할 수 있는onRequest()
함수를 내보냅니다. 이는 기본 내보내기가 아니어야 합니다.src/middleware.js export function onRequest ({ locals, request }, next) {// 요청의 응답 데이터 가로채기// 선택적으로 `locals`의 속성을 수정합니다.locals.title = "새로운 제목";// Response 객체 또는 `next()` 함수의 호출 결과를 반환합니다.return next();}; -
.astro
파일에서Astro.locals
를 통해 응답 데이터를 사용합니다.src/components/Component.astro ---const data = Astro.locals;---<h1>{data.title}</h1><p>{data.property} 속성은 미들웨어로부터 전달되었습니다.</p>
context
객체
섹션 제목: context 객체context
객체에는 렌더링 프로세스 중 다른 미들웨어, API 경로 및 .astro
경로에 사용할 수 있는 정보가 포함되어 있습니다.
이는 onRequest()
에 전달되는 선택적 인수로, 렌더링 중 공유할 추가 속성과 locals
객체를 포함할 수 있습니다. 예를 들어, context
객체에는 인증에 사용되는 쿠키가 포함될 수 있습니다.
context.locals
에 데이터 저장
섹션 제목: context.locals에 데이터 저장context.locals
는 미들웨어에서 조작할 수 있는 객체입니다.
이 locals
객체는 요청 처리 프로세스를 통해 전달되며 APIContext
및 AstroGlobal
에 대한 속성으로 사용할 수 있습니다. 이를 통해 미들웨어, API 경로 및 .astro
페이지 간에 데이터를 공유할 수 있습니다. 이는 렌더링 단계 전반에 걸쳐 사용자 데이터와 같은 요청별 데이터를 저장하는 데 유용합니다.
통합은 locals
객체를 통해 속성을 설정하고 기능을 제공할 수 있습니다. 통합을 사용하는 경우, 문서를 통해 해당 속성을 재정의하거나 불필요한 작업을 수행하고 있지 않은지 확인하세요.
locals
에는 문자열, 숫자, 심지어 함수나 맵과 같은 모든 타입의 데이터를 저장할 수 있습니다.
export function onRequest ({ locals, request }, next) { // 요청의 응답 데이터 가로채기 // 선택적으로 `locals`의 속성을 수정합니다. locals.user.name = "John Wick"; locals.welcomeTitle = () => { return "반가워요 " + locals.user.name; };
// Response 객체 또는 `next()` 함수의 호출 결과를 반환합니다. return next();};
그러면 Astro.locals
를 통해 .astro
파일에서 이 정보를 사용할 수 있습니다.
---const title = Astro.locals.welcomeTitle();const orders = Array.from(Astro.locals.orders.entries());---<h1>{title}</h1><p>이 {data.property} 속성은 미들웨어로부터 전달되었습니다.</p><ul> {orders.map(order => { return <li>{/* 각각의 order에 대해 해야 할 작업 */}</li>; })}</ul>
locals
는 단일 Astro 경로 내에서 살고 죽는 객체입니다. 경로 페이지가 렌더링되면, 기존 locals
가 제거되고 새로운 locals
가 생성됩니다. 그러므로 여러 페이지 요청에 걸쳐 지속되어야 하는 정보는 다른 곳에 저장되어야 합니다.
locals
값은 런타임에 재정의될 수 없습니다. 그렇게 하면 사용자가 저장한 모든 정보가 지워질 위험이 있기 때문입니다. dev
모드에서 Astro는 검사를 수행하고, locals
가 재정의되면 오류를 발생시킵니다.
예: 민감한 정보 수정
섹션 제목: 예: 민감한 정보 수정아래 예에서는 페이지에서 수정된 HTML을 렌더링할 수 있도록 미들웨어를 사용하여 “비밀 정보”라는 단어를 “수정됨”으로 대체합니다.
export const onRequest = async (context, next) => { const response = await next(); const html = await response.text(); const redactedHtml = html.replaceAll("비밀 정보", "수정됨");
return new Response(redactedHtml, { status: 200, headers: response.headers });};
미들웨어 타입
섹션 제목: 미들웨어 타입타입 안전성을 활용하기 위해 defineMiddleware()
유틸리티 함수를 가져와 사용할 수 있습니다.
import { defineMiddleware } from "astro:middleware";
// `context`와 `next`가 자동으로 입력됩니다.export const onRequest = defineMiddleware((context, next) => {
});
대신 JsDoc을 사용하여 타입 안전성을 활용하는 경우 MiddlewareResponseHandler
를 사용할 수 있습니다.
/** * @type {import("astro").MiddlewareResponseHandler} */// `context`와 `next`가 자동으로 입력됩니다.export const onRequest = (context, next) => {
};
.astro
파일과 미들웨어 코드에서 자동 완성 기능을 제공하는 Astro.locals
의 데이터에 타입 정보를 제공하려면 env.d.ts
파일에 전역 네임스페이스를 선언하세요.
/// <reference types="astro/client" />declare namespace App { interface Locals { user: { name: string }, welcomeTitle: () => string, orders: Map<string, object> }}
그러면 미들웨어 파일에서 자동 완성 및 타입 안전성을 활용할 수 있습니다.
미들웨어 체이닝
섹션 제목: 미들웨어 체이닝sequence()
를 사용하여 여러 미들웨어를 지정된 순서로 결합할 수 있습니다.
import { sequence } from "astro:middleware";
async function validation(_, next) { console.log("validation 요청"); const response = await next(); console.log("validation 응답"); return response;}
async function auth(_, next) { console.log("auth 요청"); const response = await next(); console.log("auth 응답"); return response;}
async function greeting(_, next) { console.log("greeting 요청"); const response = await next(); console.log("greeting 응답"); return response;}
export const onRequest = sequence(validation, auth, greeting);
그러면 다음과 같은 순서대로 콘솔에 메시지가 출력됩니다.
validation 요청auth 요청greeting 요청greeting 응답auth 응답validation 응답