Server X Action 짜잔

송윤서·2025년 3월 17일

Next.js

목록 보기
4/7
post-thumbnail

Server Action

서버에서 실행되는 비동기 함수
Next.js 애플리케이션에서 폼 제출 및 데이터 변형을 처리하기 위해 서버 및 클라이언트 구성 요소에서 호출할 수 있습니다.

서버 구성 요소

export default function Page() {
  // Server Action
  async function create() {
    'use server'
    // Mutate data
  }
 
  return '...'
}

-> 인라인 함수 수준 또는 모듈 수준"use server" 지시문을 사용할 수 있습니다.

클라이언트 구성 요소

'use server'
 
export async function create() {}

-> 서버 작업을 호출하려면 새 파일 생성 후 "use server" 을 맨 위에 추가합니다.

사용예시

"use server"; 
// 이 코드가 있으면 서버에서 실행, 없으면 클라이언트에서 실행 (실행되는 주체가 다름)

const getData = async () => {
  const res = await fetch("https://jsonplaceholder.typicode.com/posts");
  const data = await res.json();
  console.log("서버에서 실행")
  return data;
};

export { getData };

Action -> props로 전달

클라이언트 구성 요소에 서버 작업을 props으로 전달할 수 있습니다.
<ClientComponent updateItemAction={updateItem} />

'use client'
 
export default function ClientComponent({
  updateItemAction,
}: {
  updateItemAction: (formData: FormData) => void
}) {
  return <form action={updateItemAction}>{/* ... */}</form>
}

Middleware

페이지를 렌더링하기 전에 서버 측에서 실행되는 함수
즉, 페이지를 렌더링하기 전에 서버 측에서 실행되는 함수

사용 사례

  1. 인증 및 권한 부여
    • 특정 페이지나 API Routes에 대한 엑세스 권한 부여하기 전에 사용자 신원 및 세션 쿠키 확인
  2. 서버 측 리디렉션
    - 특정 조건에 따라 서버 수준에서 사용자 리디렉션
    3.경로 재작성
    - 요청 속성에 따라 API Routes나 페이지에 대한 경로를 동적으로 다시 작성하여 A/B 테스트, 기능 출시 또는 request properties를 지원

사용법

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url))
}
 
// See "Matching Paths" below to learn more
export const config = {
  matcher: '/about/:path*',
}

실행되는 경로 정의 방법 2가지

1. 사용자 정의 matcher 구성

matcher값은 상수여야 빌드 타임에 정적으로 분석할 수 있습니다. 변수와 같은 동적 값은 무시됩니다.

export const config = {
  matcher: '/about/:path*',
}

export const config = {
  matcher: ['/about/:path*', '/dashboard/:path*'],
}

-> 배열 구문 사용하면 단일 경로 또는 여러 경로 일치시키기 가능

export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico, sitemap.xml, robots.txt (metadata files)
     */
    '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
  ],
}

-> missing또는 배열을 사용하거나 has둘을 조합하여 특정 요청에 대해 미들웨어를 우회할 수도 있습니다

사용 예시

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";


// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL("/home", request.url));
}

// See "Matching Paths" below to learn more
export const config = {
  matcher: "/about/:path*",
};

2. 조건문

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
 
export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/about')) {
    return NextResponse.rewrite(new URL('/about-2', request.url))
  }
 
  if (request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.rewrite(new URL('/dashboard/user', request.url))
  }
}
profile
Front-end Developer

0개의 댓글