컨텐츠로 이동

미들웨어

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

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

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

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

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

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

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

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

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

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

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

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

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

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