컨텐츠로 이동

미들웨어

미들웨어를 사용하면 페이지나 엔드포인트가 렌더링될 때마다 요청과 응답을 가로채고 동작을 동적으로 추가할 수 있습니다.

또한 이를 통해 모든 Astro 컴포넌트 및 API 엔드포인트에서 사용할 수 있는 locals 객체를 변경하여 엔드포인트와 페이지 전반에 걸쳐 요청별 정보를 설정하고 공유할 수 있습니다.

미들웨어는 SSG 및 SSR Astro 프로젝트 모두에서 사용할 수 있습니다.

사용 방법

  1. src/middleware.js|ts 파일을 생성합니다. (또는 src/middleware/index.js|ts 파일을 생성할 수도 있습니다.)

  2. 이 파일에서 onRequest() 함수를 내보냅니다. 이는 default export가 아니어야 합니다.

    src/middleware.js
    export function onRequest ({ locals, request }, next) {
    // 요청의 응답 데이터 가로채기
    // 선택적으로 `locals`를 수정하여 응답을 변환합니다.
    locals.title = "새로운 제목";
    // Response 객체 또는 `next()` 함수의 호출 결과를 반환합니다.
    return next();
    };
  3. .astro 파일에서 Astro.locals를 통해 응답 데이터를 사용합니다.

    src/components/Component.astro
    ---
    const data = Astro.locals;
    ---
    <h1>{data.title}</h1>
    <p>{data.property} 속성은 미들웨어로부터 전달되었습니다.</p>

미들웨어 타입

타입 안전성을 활용하려면 defineMiddleware() 유틸리티 함수를 가져와 사용할 수 있습니다.

src/middleware.ts
import { defineMiddleware } from "astro:middleware";
// `context`와 `next`에 자동으로 타입이 설정됩니다.
export const onRequest = defineMiddleware((context, next) => {
});

대신 JsDoc을 사용하여 타입 안전성을 활용하는 경우 MiddlewareRequestHandler를 사용할 수 있습니다.

src/middleware.js
/**
* @type {import("astro").MiddlewareResponseHandler}
*/
// `context`와 `next`에 자동으로 타입이 설정됩니다.
export const onRequest = (context, next) => {
};

Astro.locals에 존재하며, .astro 파일과 미들웨어 코드에 자동 완성을 제공하는 정보에 타입을 제공하려면 env.d.ts 파일에서 전역 네임스페이스를 선언하세요.

src/env.d.ts
/// <reference types="astro/client" />
declare namespace App {
interface Locals {
user: {
name: string
},
welcomeTitle: () => string,
orders: Map<string, object>
}
}

그러면 미들웨어 파일에서 자동 완성 및 유형 안전성을 활용할 수 있습니다.

Astro.locals에는 문자열, 숫자, 심지어 함수나 맵과 같은 복잡한 데이터 타입까지 모든 타입의 데이터를 저장할 수 있습니다.

src/middleware.js
export function onRequest ({ locals, request }, next) {
// 요청의 응답 데이터 가로채기
// 선택적으로 `locals`를 수정하여 응답을 변환합니다.
locals.user.name = "John Wick";
locals.welcomeTitle = () => {
return "반가워요 " + locals.user.name;
};
// Response 객체 또는 `next()` 함수의 호출 결과를 반환합니다.
return next();
};

그러면 .astro 파일에서 이 정보를 사용할 수 있습니다.

src/pages/orders.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>

예: 민감한 정보 수정

아래 예에서는 페이지에서 수정된 HTML을 렌더링할 수 있도록 미들웨어를 사용하여 “비밀 정보”라는 단어를 “수정됨”으로 대체합니다.

src/middleware.js
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
});
};

미들웨어 체이닝

sequence() 함수를 사용하여 여러 미들웨어를 지정된 순서로 결합할 수 있습니다.

src/middleware.js
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);

그러면 다음과 같은 순서대로 콘솔에 메시지가 출력됩니다.

Terminal window
validation 요청
auth 요청
greeting 요청
greeting 응답
auth 응답
validation 응답

API 참조

onRequest()

모든 페이지 또는 API 경로를 렌더링하기 전에 호출되는 src/middleware.js 파일에서 반드시 내보내야 하는 함수입니다. 두 개의 선택적 인수인 contextnext()를 전달받을 수 있습니다. onRequest() 함수는 Response 객체를 직접 반환하거나 next() 함수를 호출한 값을 반환해야 합니다.

context

렌더링 중에 다른 미들웨어, API 경로 및 .astro 경로에 사용할 수 있는 정보가 포함된 객체입니다.

이 객체는 onRequest() 함수에 전달되는 선택적 인수이며 locals 객체 및 렌더링 중 공유할 모든 추가 속성을 포함할 수 있습니다. 예를 들어 context 객체에는 인증에 사용되는 쿠키가 포함될 수 있습니다.

이는 API 경로에 전달되는 것과 동일한 context (EN) 객체입니다.

next()

전달된 Request 객체에 대한 Response 객체를 가로채거나(읽고 수정) 체인의 다음 미들웨어를 호출하고 Response 객체를 반환하는 함수입니다. 예를 들어 이 함수는 응답의 HTML 본문을 수정할 수 있습니다.

이 함수는 onRequest()의 선택적 인수이며 미들웨어에서 반환하는 필수 Response 객체를 제공할 수 있습니다.

locals

미들웨어에서 조작할 수 있으며, Response의 데이터가 포함된 객체입니다.

locals 객체는 요청 처리 프로세스를 통해 APIContext (EN)AstroGlobal 객체의 속성으로 전달됩니다. 이를 통해 미들웨어, API 경로 및 .astro 페이지 간 데이터를 공유할 수 있습니다. 이는 렌더링 단계 전반에 걸쳐 사용되는 사용자 데이터와 같은 요청별 데이터를 저장하는 데 유용합니다.

locals는 단일 Astro 경로 내에서 생성되고 제거되는 객체입니다. 경로 페이지가 렌더링되면 기존 locals는 제거되며 새 locals 객체가 생성됩니다. 여러 페이지 요청에 걸쳐 지속되어야 하는 정보는 다른 곳에 저장되어야 합니다.

sequence()

미들웨어 함수를 인수로 전달받고, 전달된 순서대로 실행하는 함수입니다.

createContext

Astro 미들웨어에서 사용할 수 있으며, APIContext (EN)를 생성하기 위한 low-level API입니다.

Astro 미들웨어를 자동으로 실행시키기 위해 이 함수를 통합/어댑터에서 사용할 수 있습니다.

trySerializeLocals

모든 값을 전달받고, 이 값의 직렬화된 버전(문자열)을 반환하려고 시도하는 low-level API입니다. 값을 직렬화할 수 없으면 함수에서 런타임 오류가 발생합니다.