Next.js 미들웨어 및 엣지 함수를 사용하여 엣지에서 웹 애플리케이션 가속
Min-jun Kim
Dev Intern · Leapcell

소개: 웹 성능의 새로운 프런티어
오늘날 빠르게 변화하는 디지털 세계에서 웹 애플리케이션의 속도와 응답성에 대한 사용자 기대치는 그 어느 때보다 높아졌습니다. 전통적으로 서버 측 로직은 중앙 집중식 데이터 센터에서 실행되었으며, 이는 종종 이러한 서버에서 멀리 떨어진 사용자에게 지연 시간 문제를 야기했습니다. 이러한 지리적 거리는 성능에 상당한 영향을 미칠 수 있으며, 특히 동적 콘텐츠나 실시간 상호 작용에 크게 의존하는 애플리케이션의 경우 더욱 그렇습니다. 엣지 컴퓨팅의 등장은 사용자에게 더 가까이 계산을 가져옴으로써 이 문제에 대한 강력한 솔루션을 제공합니다. 인기 있는 React 프레임워크인 Next.js는 미들웨어 및 엣지 함수와 같은 강력한 기능을 통합함으로써 이러한 패러다임 전환을 수용했습니다. 이러한 혁신을 통해 개발자는 네트워크 엣지에서 직접 코드를 실행하여 성능 최적화, 향상된 보안 및 개인화된 사용자 경험을 위한 새로운 가능성을 열 수 있습니다. 이 글에서는 Next.js 미들웨어 및 엣지 함수의 기술적 기반을 살펴보고 개발자가 진정으로 전 세계적이고 성능이 뛰어난 웹 애플리케이션을 구축할 수 있도록 지원하는 방법을 설명합니다.
핵심 개념: 엣지 생태계 이해
실질적인 적용 사례를 살펴보기 전에 엣지 컴퓨팅 및 Next.js 구현과 관련된 몇 가지 기본 용어를 명확히 해 보겠습니다.
- 엣지 컴퓨팅: 데이터 소스에 더 가까운 계산 및 데이터 저장을 가져오는 분산 컴퓨팅 패러다임입니다. 이는 지연 시간을 줄이고 대역폭을 절약하며 응답성을 향상시킵니다. 정적 파일만 제공하는 것이 아니라 동적 로직도 실행하는 전역 콘텐츠 전송 네트워크(CDN)를 상상해 보세요.
- 엣지 런타임: 엣지에서의 실행 환경입니다. 기존 Node.js 서버와 달리 엣지 런타임은 종종 가볍고 빠르게 부팅되며 저지연 작업에 최적화됩니다. 전체 Node.js 환경에 비해 API 표면 영역이 더 제한적입니다.
- Next.js 미들웨어: 일반적으로 요청이 완료되기 전에 코드를 실행할 수 있는 강력한 기능입니다. Next.js 라우팅 시스템의 중요한 구성 요소로, 들어오는 요청 및 나가는 응답에 대한 세밀한 제어를 제공합니다. 미들웨어는 엣지 런타임에서 실행됩니다.
- Next.js 엣지 함수: 엣지 런타임에서 실행되는 범용 함수입니다. 미들웨어가 특별히 라우팅 및 요청 조작을 처리하는 반면, 엣지 함수는 API 엔드포인트 또는 백그라운드 처리와 같이 더 넓은 범위의 작업에 사용될 수 있으며 모두 엣지에서 실행됩니다. 엣지 근접성의 이점을 가진 서버리스와 유사한 운영 모델을 제공합니다.
Next.js 미들웨어: 요청 가로채기 및 변환
Next.js 미들웨어는 요청이 처리되기 전에 코드를 실행할 수 있는 방법을 제공합니다. 이는 인증, 권한 부여, 국제화, A/B 테스팅 및 URL 재작성과 같은 작업에 매우 유용합니다.
미들웨어 작동 방식
미들웨어 함수는 프로젝트의 루트 또는 특정 디렉터리 내에 middleware.ts
(또는 .js
) 파일에 정의됩니다. 이 함수는 NextResponse
를 await
하고 요청이나 응답을 수정하거나 사용자를 리디렉션할 수 있습니다.
다음은 Next.js 미들웨어를 사용하여 인증되지 않은 사용자를 리디렉션하는 방법에 대한 기본 예입니다.
// middleware.ts import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const isAuthenticated = /* 사용자가 인증되었는지 확인하는 논리, 예: 쿠키에서 */ false; if (!isAuthenticated && request.nextUrl.pathname.startsWith('/dashboard')) { // 인증되지 않았고 보호된 경로에 액세스하려고 하면 로그인으로 리디렉션 return NextResponse.redirect(new URL('/login', request.url)); } // 인증되었거나 공개 경로에 액세스하면 요청을 진행하도록 허용 return NextResponse.next(); } // 선택적으로, 미들웨어를 선택적으로 적용하기 위한 matcher를 정의 // 이것은 미들웨어를 관련 경로에만 실행하여 성능을 최적화합니다. export const config = { matcher: ['/dashboard/:path*', '/api/:path*'], };
이 예에서 middleware
함수는 사용자가 인증되었는지 확인합니다. 인증되지 않았고 /dashboard
아래의 경로에 액세스하려고 하면 /login
으로 리디렉션됩니다. matcher
구성은 이 미들웨어가 /dashboard
또는 /api
로 시작하는 경로에 대해서만 실행되도록 하여 효율성을 향상시킵니다.
미들웨어 사용 사례:
- 인증 & 권한 부여: 사용자 세션 또는 토큰을 확인하여 경로를 보호합니다.
- 국제화 (i18n): 사용자 언어 기본 설정을 감지하고 URL을 재작성하거나 적절한 헤더를 설정합니다.
- A/B 테스팅: 사용자 속성 또는 실험 그룹에 따라 페이지의 다른 버전을 동적으로 제공합니다.
- URL 재작성 & 리디렉션: URL을 정리하고, 폴백 페이지를 구현하거나, 레거시 라우팅을 처리합니다.
- 기능 플래그: 특정 사용자 또는 지역에 대해 기능을 활성화하거나 비활성화합니다.
Next.js 엣지 함수: 엣지에서의 범용 로직
미들웨어는 요청을 가로채고 변환하도록 특별히 설계된 반면, 엣지 함수는 엣지에서 코드를 실행할 수 있는 더 범용적인 방법을 제공합니다. API 엔드포인트 생성과 같이 낮은 지연 시간을 요구하지만 반드시 주요 탐색 흐름을 수정할 필요는 없는 작업에 이상적입니다.
엣지 함수 작동 방식
엣지 함수는 본질적으로 엣지 런타임에서 실행되는 서버리스 함수입니다. Next.js에서는 API 경로(예: pages/api/hello-edge.ts
또는 app/api/hello-edge/route.ts
)를 만들고 런타임을 지정하여 엣지 함수를 정의할 수 있습니다.
// pages/api/hello-edge.ts (Pages Router) import type { NextRequest } from 'next/server'; export const config = { runtime: 'edge', // 이 API 경로가 엣지 런타임에서 실행되도록 지정 }; export default function handler(request: NextRequest) { return new Response(`Hello from the Edge! Your path is: ${request.nextUrl.pathname}`); }
// app/api/hello-edge/route.ts (App Router) import type { NextRequest } from 'next/server'; export const runtime = 'edge'; // 이 API 경로가 엣지 런타임에서 실행되도록 지정 export async function GET(request: NextRequest) { return new Response(`Hello from the Edge! Your path is: ${request.nextUrl.pathname}`); }
/api/hello-edge
로 요청이 오면 함수는 사용자에게 가장 가까운 엣지 위치에서 최소 지연 시간으로 실행됩니다. runtime: 'edge'
(또는 export const runtime = 'edge'
) 구성을 주목하세요. 이는 Next.js에 이 함수를 엣지로 배포하도록 지시하는 데 중요합니다.
엣지 함수 사용 사례:
- 저지연 API 엔드포인트: 엣지에서 직접 API 요청을 위한 동적 데이터를 제공하거나 계산을 수행하여 왕복 시간을 줄입니다.
- 데이터 변환: 클라이언트에 보내기 전에 외부 소스에서 가져온 데이터를 수정하거나 필터링합니다.
- 지리적 타겟팅: 사용자의 지리적 위치를 기반으로 콘텐츠 또는 광고를 제공합니다.
- 실시간 분석 수집: 중앙 서버 병목 현상 없이 사용자로부터 분석 데이터를 신속하게 수집하고 처리합니다.
- 개인화 엔진: 엣지에 저장된 사용자 프로필을 기반으로 개인화된 콘텐츠 또는 추천을 렌더링합니다.
엣지 런타임 제약 사항
엣지 런타임은 전체 Node.js 환경에 비해 특정 제약 사항이 있는 특수 환경이라는 점을 이해하는 것이 중요합니다. 이러한 제약 사항은 종종 저지연 및 엣지에서의 효율적인 실행을 보장하기 위한 것입니다.
- 제한적인 Node.js API: 많은 내장 Node.js 모듈(예:
fs
,process
또는 특정crypto
함수)은 일반적으로 사용할 수 없습니다. - 파일 시스템 액세스 불가: 엣지 함수/미들웨어는 파일 시스템을 읽거나 쓸 수 없습니다.
- 표준 스트림 액세스 불가:
stdin
,stdout
,stderr
는 일반적으로 사용할 수 없습니다. - 더 작은 번들 크기: 리소스 제약 및 빠른 부팅 요구 사항으로 인해 엣지 함수/미들웨어 번들을 작게 유지하는 것이 좋습니다.
- 기본적으로 상태 비저장: 엣지 함수는 일반적으로 상태 비저장입니다. 지속적인 데이터는 외부 데이터베이스나 캐시에 저장해야 합니다.
개발자는 이러한 제약 사항을 염두에 두고 엣지 로직을 그에 맞게 설계해야 하며, 가볍고 자체 포함된 함수를 선택해야 합니다.
결론: 미래는 엣지에 있습니다
Next.js 미들웨어와 엣지 함수는 고성능, 복원력 및 개인화된 웹 애플리케이션 구축에서 상당한 도약을 나타냅니다. 네트워크 엣지에서 코드 실행을 가능하게 함으로써 개발자는 지연 시간을 대폭 줄이고 사용자 경험을 개선하며 동적 콘텐츠 제공 및 API 상호 작용을 위한 새로운 가능성을 열 수 있습니다. 이러한 개념을 마스터하면 성능이 뛰어날 뿐만 아니라 진정으로 전 세계적이고 사용자의 지리적 위치에 관계없이 최적의 성능으로 사용자를 지원하는 애플리케이션을 설계할 수 있습니다. 사용자에게 더 가까운 계산은 더 이상 사치가 아니라 현대 웹 개발의 초석이며, Next.js는 이를 달성할 수 있는 강력한 도구를 제공합니다.