Definitions
createNexusDefinition
을 사용하면 서버와 클라이언트 양쪽에서 사용할 수 있는 예측 가능한 형식의 요청 definition
을 만들 수 있습니다.
Import
import { createNexusDefinition } from "next-nexus";
중요: 이 프로젝트에서는
definition
객체를 반드시 팩토리(factory)를 통해 생성해야 합니다.createNexusDefinition<T>({...})
를 직접 일회성으로 호출하는 방식은 허용되지 않습니다.
팩토리 사용 (필수)
공통 기본값을 가진 팩토리를 만든 후, 이를 기반으로 각 도메인에 맞는 definition
객체를 만드세요.
export const createApiDefinition = createNexusDefinition({
baseURL: "https://api.example.com",
timeout: 5,
retry: { count: 1, delay: 1 },
headers: { "x-app": "docs" },
});
export const productDefinition = {
list: createApiDefinition<Product[]>({
method: "GET",
endpoint: "/products",
server: {
// next-nexus는 기본적으로 server.cache를 'no-store'로 둡니다. 정적 캐싱/ISR이 필요할 때만 'force-cache'를 명시하세요.
revalidate: 1800, // next: { revalidate: 1800 } 로 매핑
tags: ["products"], // next: { tags: ['products'] } 로 매핑
},
client: { tags: ["products"], revalidate: 300 },
}),
detail: (id: string) =>
createApiDefinition<Product>({
method: "GET",
endpoint: `/products/${id}`,
client: { tags: ["products", `product:${id}`], revalidate: 300 },
}),
like: (id: string) =>
createApiDefinition<{ success: boolean }>({
method: "POST",
endpoint: `/products/${id}/like`,
}),
};
Cached Response Headers
client.cachedHeaders
를 사용하면 x-total-count
와 같이 안전하고 크기가 작은 헤더를 데이터와 함께 하이드레이션 페이로드에 포함시킬 수 있습니다.
Define
export const listWithTotalDefinition = createApiDefinition<Product[]>({
method: "GET",
endpoint: "/products",
client: {
tags: ["products"],
revalidate: 300,
cachedHeaders: ["x-total-count"],
},
});
참고
- 민감한 헤더는 캐시하지 마세요.
- 헤더는 추가 요청 없이 하이드레이션 페이로드에서 복원됩니다.
Options
method
: ‘GET’ | ‘POST’ | ‘PUT’ | ‘PATCH’ | ‘DELETE’endpoint
: string (경로 부분)baseURL?
: string (endpoint 앞에 붙는 주소)headers?
: HeadersInit (병합됨;'null'
또는'undefined'
같은 falsy 문자열 값은 헤더를 제거함)server?
:{ cache?: RequestCache; revalidate?: number; tags?: string[] }
client?
:{ revalidate?: number; tags?: string[]; cachedHeaders?: string[] }
timeout?
: number (초)retry?
:{ count: number; delay?: number }
interceptors?
: string[] (interceptors.request/response.use
로 등록한 이름)
기본값 (Defaults)
server.cache
: 이 값을 생략하면 next-nexus는 Next.js 버전에 관계없이 기본적으로'no-store'
를 사용합니다. Next.js 14는'force-cache'
, 15+는'no-store'
가 기본값이지만, next-nexus는 일관성을 위해'no-store'
를 유지합니다. 정적 캐싱이나 ISR이 필요한 경우에만server.cache: 'force-cache'
를 명시적으로 설정하세요.- 이름 규칙 (Naming): 명확성을 위해
*Definition
접미사를 사용하세요 (예:productDefinition
,listWithTotalDefinition
).
타입 (Typing)
- 전송 계층 중심의 타입을 선호합니다:
Product
,ProductListResponse
. - 제네릭으로 전달한 응답 타입은
nexus
,useNexusQuery
,useNexusMutation
,nexusCache
로 이어집니다. - Zod와 같은 런타임 스키마를 사용하는 경우, 스키마로부터 TypeScript 타입을 추론하고 일관된 이름을 유지하세요 (
ProductSchema
→type Product = z.infer<...>
).
패턴과 안티패턴
패턴 (Patterns)
- 팩토리를 사용하여 파라미터가 있는 엔드포인트를 위한 동적
definition
객체를 만드세요.const detail = (id: string) => createApiDefinition<Product>({ method: "GET", endpoint: `/products/${id}`, });
client.cachedHeaders
를 통해 작고 안전한 응답 헤더(예:x-total-count
)를 캐시하세요.tags
를 일관되게 사용하여 서버와 클라이언트에서 정밀한 재검증을 활성화하세요.
안티패턴 (Anti-patterns)
- 위임된(delegated) 서브트리 내부에서 서버 전용 API를 혼합하여 사용하는 것.
tags
를 생략한 채 나중에 데이터의 특정 부분만 재검증하려고 시도하는 것.- 공통 팩토리를 사용하지 않고 요청을 개별적으로 정의하는 것. (일관성 및 타입 안정성 저하)
팁 (Tips)
- 헤더 병합: 헤더 값으로 문자열
'null'
또는'undefined'
를 사용하면 병합 후 해당 헤더가 제거됩니다. - 라우트 프록시: 훅에
route
prop을 전달하면, 런타임은baseURL
을 지우고route
경로를 엔드포인트로 사용합니다.
함께 보기
Last updated on