본문으로 건너뛰기
Previous
Next
Nitro 완벽 가이드 | 유니버설 서버 엔진·라우팅·캐시·Edge·실전 API

Nitro 완벽 가이드 | 유니버설 서버 엔진·라우팅·캐시·Edge·실전 API

Nitro 완벽 가이드 | 유니버설 서버 엔진·라우팅·캐시·Edge·실전 API

이 글의 핵심

Nitro는 한 번 작성한 서버 코드를 Node·Bun·Lambda·Cloudflare Workers 등 여러 런타임에 배포할 수 있게 해 주는 유니버설 서버 엔진입니다. 파일 기반 라우팅, 라우트 규칙 기반 캐싱, Unstorage 기반 스토리지, WebSocket까지 한 흐름으로 익힐 수 있습니다.

이 글의 핵심

Nitro는 Nuxt 3와 Analog가 공통으로 사용하는 유니버설 서버 엔진입니다. HTTP 핸들러·미들웨어·빌드 출력·배포 프리셋을 하나의 추상화로 묶어, 동일한 소스에서 Node 서버, 서버리스 함수, Edge Worker로 재컴파일·재배포할 수 있게 설계되었습니다.

실무 관점: “프론트는 Nuxt, API는 별도 Express”로 나누면 배포 파이프라인과 인증·캐시 정책이 이중으로 갈립니다. Nitro 레이어에 API를 두면 한 애플리케이션 경계 안에서 라우트 규칙·스토리지·런타임 어댑터를 공유할 수 있어 운영 복잡도가 줄어듭니다.

들어가며: 왜 Nitro인가

풀스택 프레임워크는 서버 런타임이 플랫폼마다 다릅니다. AWS Lambda는 이벤트 객체가 있고, Cloudflare Workers는 Fetch API 중심이며, 전통 Node 서버는 장시간 TCP 연결과 파일 시스템에 의존합니다. Nitro는 이런 차이를 프리셋(preset)런타임 어댑터 뒤로 숨기고, 개발자에게는 파일 기반 라우트defineEventHandler 같은 일관된 API를 제공합니다.

실무 문제 시나리오

시나리오 1: 스테이징은 Node인데 프로덕션은 Edge예요

동일 Nitro 빌드에 preset만 바꿔 재배포할 수 있습니다. 다만 Edge는 Node 전용 모듈·일부 네이티브 의존성이 제한되므로, 대상 프리셋을 초기에 고정하고 제약을 CI에서 검증하는 편이 안전합니다.

시나리오 2: 페이지는 ISR이 필요하고 API는 캐시하면 안 돼요

Nuxt의 routeRules·Nitro 라우트 규칙으로 경로별로 SWR·정적 프리렌더·캐시 헤더를 분리합니다. API 경로는 Cache-Control: private 또는 no-store로 두고, 공개 문서 경로만 s-maxage를 부여하는 식의 하이브리드 전략이 일반적입니다.

시나리오 3: 세션·레이트 리밋 저장소를 어디에 둘까요

Nitro Unstorage 추상화로 memory·redis·클라우드 KV 등을 드라이버로 교체할 수 있습니다. 로컬 개발은 파일·메모리, 프로덕션은 관리형 KV로 스위치하는 패턴이 흔합니다.


1. Nitro의 핵심 개념

1.1 유니버설 런타임과 프리셋

Nitro는 소스 트리를 단일 번들로 빌드한 뒤, nitro.configpreset(또는 Nuxt의 nitro.preset)에 따라 출력물 형태가 달라집니다. 예를 들어 node-servernode로 구동 가능한 서버 엔트리를, vercel은 Vercel Functions 레이아웃에 맞는 산출물을 생성합니다.

핵심은 “한 코드베이스 — 여러 배포 타겟” 입니다. 다만 “동일 동작”을 보장하려면 플랫폼 제한(실행 시간, 파일 시스템, TCP/WebSocket, 환경 변수 주입 방식)을 각 프리셋 문서와 함께 읽어야 합니다.

1.2 H3 이벤트 모델

Nitro의 HTTP 레이어는 h3를 기반으로 합니다. 요청 단위로 event 객체가 전달되며, 헤더·쿠키·본문 파싱, 리다이렉트, 스트리밍 응답이 이 모델 위에서 이루어집니다. Express의 req/res와 개념은 비슷하지만, 웹 표준 Request/Response에 가까운 추상화로 통일되어 Edge 런타임과도 맞춥니다.

1.3 UnJS 생태계

Nitro는 UnJS 계열 모듈(h3, unstorage, ofetch 등)과 잘 맞물립니다. 특히 unstorage는 “스토리지 추상화”로서 로컬·메모리·Redis·S3·클라우드 KV를 동일 API로 다루게 해 주어, 서버리스·Edge 전환 시 저장소 교체 비용을 줄입니다.

1.4 Nuxt·Analog와의 관계

  • Nuxt 3: server/ 디렉터리와 nuxt.confignitro·routeRules가 Nitro 빌드에 직접 연결됩니다.
  • Analog(Angular 풀스택): Nitro를 서버 엔진으로 사용하며, Angular 측 빌드와 Nitro 라우트가 결합됩니다.

즉 Nitro를 이해하면 Vue(Nuxt)Angular(Analog) 양쪽의 서버 측 확장 지점을 같은 모델로 읽을 수 있습니다.


2. 파일 기반 라우팅

2.1 Nuxt에서의 관례

Nuxt 프로젝트에서 가장 흔한 구조는 다음과 같습니다.

  • server/api/**/*.ts: 기본적으로 /api/** URL로 매핑됩니다.
  • server/routes/**/*.ts: 루트 경로에 직접 매핑됩니다(프로젝트 설정에 따라 접두사를 붙일 수 있음).

파일 이름이 곧 URL 패턴이 됩니다. 동적 세그먼트는 [id].ts, 캐치올은 [...slug].ts 형태를 사용합니다.

// server/api/users/[id].ts
// GET /api/users/:id
import { defineEventHandler, getRouterParam } from 'h3';

export default defineEventHandler((event) => {
  const id = getRouterParam(event, 'id');
  return { id, source: 'nitro' };
});

위 핸들러는 한 파일이 한 라우트를 담당합니다. RESTful API를 만들 때는 디렉터리로 리소스를 나누고, 공통 검증은 서버 미들웨어로 뺍니다.

2.2 미들웨어 체인

server/middleware/에 두는 미들웨어는 요청이 핸들러에 도달하기 전에 실행됩니다. 인증 헤더 검사, 요청 ID 부여, 로깅 등 횡단 관심사에 적합합니다.

// server/middleware/01-request-id.ts
import { defineEventHandler, getRequestHeader, setResponseHeader } from 'h3';
import { randomUUID } from 'node:crypto';

export default defineEventHandler((event) => {
  const incoming = getRequestHeader(event, 'x-request-id');
  const id = incoming ?? randomUUID();
  event.context.requestId = id;
  setResponseHeader(event, 'x-request-id', id);
});

event.context는 이후 핸들러까지 전달되는 요청 범위 저장소로 쓰입니다. 다만 민감 정보를 넣을 때는 로그에 남지 않도록 주의합니다.

2.3 순수 Nitro 프로젝트

Nuxt 없이 Nitro만 쓸 때는 보통 routes/ 디렉터리에 핸들러를 두고 nitro.config.ts로 프리셋·별칭·런타임 설정을 관리합니다. 라우팅 규칙·플러그인·스토리지 바인딩은 모두 Nitro 설정 파일 한곳에서 조정할 수 있습니다.


3. 캐싱 전략과 하이브리드 렌더링

3.1 routeRules로 경로별 정책 분리

Nuxt에서는 routeRules정적 프리렌더·SSR·SWR(ISR 스타일)·헤더를 경로 단위로 지정합니다. 이는 Nitro가 빌드·런타임에 반영할 라우트 메타데이터로 연결됩니다.

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/docs/**': { swr: 3600 },
    '/dashboard/**': { ssr: false },
    '/api/**': {
      cors: true,
      headers: { 'cache-control': 'no-store' },
    },
  },
});
  • prerender: 빌드 시 HTML을 생성합니다. 마케팅 랜딩·문서처럼 변하지 않는 구간에 적합합니다.
  • swr: stale-while-revalidate 스타일로 캐시된 응답을 제공하고 백그라운드에서 재검증합니다. 트래픽이 크고 갱신 주기가 허용되는 페이지에 유리합니다.
  • ssr: false: 해당 트리는 클라이언트 렌더링 위주로 두어 서버 부하를 줄이거나 인증된 앱 영역과 공개 영역을 나눌 때 쓰입니다.
  • API: 기본적으로 캐시하지 않는 것이 안전합니다. 공개 GET API에 한해 s-maxage를 주려면 의도적으로 헤더를 설계합니다.

3.2 캐시 키와 무효화의 현실

HTTP 캐시는 키가 URL·헤더·Vary에 의해 결정됩니다. 개인화 쿠키가 있는 요청이 공용 캐시에 닿지 않게 Vary·private를 조정해야 합니다. 무효화는 CDN·호스팅 제공 기능(태그 퍼지, API)에 의존하는 경우가 많으므로, “캐시에 싣지 말아야 할 데이터” 를 먼저 정의하는 편이 안전합니다.

3.3 Nitro 내부 캐시와 스토리지

라우트 외에도 Nitro 스토리지에 짧은 TTL 객체를 두어 부가 캐시(예: 외부 API 응답, 계산 비용 큰 파생 데이터)를 저장할 수 있습니다. 이는 HTTP 캐시와는 별층이며, 일관성 요구·TTL·스탬피드 방지를 코드로 명시해야 합니다.


4. 배포 타겟: Vercel, Netlify, AWS

4.1 공통: 프리셋 선택

배포 문서에 맞는 preset을 지정합니다. 예시는 개념 설명용이며, 실제 버전별 이름은 Nitro·호스팅 문서를 확인합니다.

// nitro.config.ts (개념 예시)
import { defineNitroConfig } from 'nitro/config';

export default defineNitroConfig({
  preset: 'node-server',
});

Nuxt에서는 export default defineNuxtConfig({ nitro: { preset: '...' } }) 형태로 동일하게 넘깁니다.

4.2 Vercel·Netlify

이러한 플랫폼은 서버리스 함수 또는 에지 함수로 배포됩니다. 장점은 글로벌 분산과 트래픽 기반 과금 구조이고, 제약은 실행 시간·페이로드 크기·파일 시스템입니다. 장시간 연결(WebSocket)이나 대용량 업로드는 별도 서비스(전용 Node, 객체 스토리지 직접 업로드)와 조합하는 경우가 많습니다.

4.3 AWS Lambda

API Gateway + Lambda 조합은 검증된 패턴입니다. Cold start·동시 실행 한도·VPC 연결 여부가 비용과 지연에 큰 영향을 줍니다. Nitro 출력이 Lambda 핸들러 형태로 제공되더라도, 연결 풀·DB 접근은 서버리스 친화적으로 재설계해야 합니다.

4.4 운영 체크리스트

  • 환경 변수: 빌드 타임 vs 런타임 주입 방식이 플랫폼마다 다릅니다.
  • 로그·트레이싱: 요청 ID를 미들웨어에서 통일해 분산 로그를 상관시킵니다.
  • 리전: 데이터 규제가 있으면 스토리지·함수·CDN 리전을 함께 설계합니다.

5. Storage Layer와 KV

5.1 Unstorage 추상화

Nitro 생태계에서는 unstorage를 통해 키-값 저장소를 통일합니다. 로컬은 디스크나 메모리, 프로덕션은 클라우드 KV로 전환하는 시나리오가 대표적입니다.

// server/api/counter/[key].get.ts
import { defineEventHandler, getRouterParam } from 'h3';

export default defineEventHandler(async (event) => {
  const key = getRouterParam(event, 'key') ?? 'default';
  const storage = useStorage('data');
  const raw = (await storage.getItem(`counter:${key}`)) ?? '0';
  const n = Number(raw) || 0;
  await storage.setItem(`counter:${key}`, String(n + 1));
  return { key, count: n + 1 };
});

useStorage에 넘기는 네임스페이스(data)는 nitro 설정에서 드라이버와 매핑됩니다. 로컬에서는 .data/ 디렉터리, 프로덕션에서는 원격 KV가 되도록 분기합니다.

5.2 Cloudflare KV와 바인딩

Cloudflare에 배포할 때는 Wrangler 바인딩 이름과 Nitro 스토리지 설정을 맞춥니다. KV는 최종 일관성 모델이므로, 금융·재고처럼 강한 일관성이 필요한 경우에는 상위에서 비관적 락·DB 트랜잭션을 고려해야 합니다.

5.3 설계 시 유의점

  • 드라이버 호환: Edge에서 Node 전용 경로에 쓰기 불가할 수 있습니다.
  • 키 네이밍: 테넌트·환경 접두사를 붙여 충돌을 방지합니다.
  • TTL: 세션·캐시에는 만료를 명시하고, 장기 보관 데이터는 KV 대신 관계형/문서 DB를 검토합니다.

6. WebSocket 지원

Nitro는 CrossWSh3를 통해 여러 런타임에서 WebSocket을 지원합니다. 설정에서 기능을 켜고, 라우트 파일에서 defineWebSocketHandler를 export합니다.

6.1 설정

// nitro.config.ts — WebSocket 활성화 (개념 예시)
import { defineNitroConfig } from 'nitro/config';

export default defineNitroConfig({
  features: {
    websocket: true,
  },
});

Nuxt에서는 nitro: { features: { websocket: true } }로 동일 옵션을 전달합니다.

6.2 핸들러와 인증

// routes/chat.ts (순수 Nitro 예시)
import { defineWebSocketHandler } from 'nitro';

export default defineWebSocketHandler({
  upgrade(request) {
    const url = new URL(request.url);
    const token = url.searchParams.get('token');
    if (!token) {
      throw new Response('Unauthorized', { status: 401 });
    }
    return { context: { token } };
  },
  message(peer, message) {
    peer.send({ echo: message.text() });
  },
});

upgrade에서 Response를 throw하면 핸드셰이크가 거절됩니다. 연결 이후에는 peer.send, peer.publish로 브로드캐스트할 수 있습니다. Pub/Sub 토픽은 동일 네임스페이스 내에서만 전파됩니다.

6.3 SSE 대안

실시간이 필요하지만 양방향이 아니라면 Server-Sent Events가 더 단순할 수 있습니다. HTTP 기반이라 일부 프록시·CDN과 궁합이 좋고, 자동 재연결 패턴도 표준화되어 있습니다.


7. 실전 API 서버 구축

7.1 모듈 구조

소규모라면 server/api 아래에 파일을 두면 충분합니다. 규모가 커지면 도메인 폴더로 서비스·검증·저장소를 나눕니다.

server/
  api/
    v1/
      users/
        index.get.ts
        index.post.ts
        [id].get.ts
  middleware/
    auth.ts
  utils/
    db.ts

REST 관례에 맞춰 index.get.ts·index.post.ts처럼 HTTP 메서드별 파일을 쓰면 라우팅 의도가 분명해집니다.

7.2 입력 검증과 오류 응답

import { defineEventHandler, readBody, createError } from 'h3';
import { z } from 'zod';

const BodySchema = z.object({
  email: z.string().email(),
  name: z.string().min(1),
});

export default defineEventHandler(async (event) => {
  const body = await readBody(event);
  const parsed = BodySchema.safeParse(body);
  if (!parsed.success) {
    throw createError({
      statusCode: 400,
      statusMessage: 'Validation Error',
      data: parsed.error.flatten(),
    });
  }
  return { ok: true, user: parsed.data };
});

zod 같은 스키마와 createError를 함께 쓰면 클라이언트에 일관된 오류 포맷을 줄 수 있습니다.

7.3 보안 기본기

  • CORS: 공개 API가 아니라면 출처를 제한합니다.
  • Rate limiting: IP·토큰·세션 키 기준으로 스토리지에 카운터를 두고 차단합니다.
  • 헤더: Content-Security-Policy, X-Content-Type-Options 등은 프론트·API 모두에서 점검합니다.

7.4 관측 가능성

구조화된 로그(JSON 한 줄)와 요청 ID, 외부 호출의 지연 분포를 남기면 장애 분석이 빨라집니다. Nitro·Nuxt 위에서 OpenTelemetry를 붙이는 사례도 늘고 있습니다.


8. 빌드 산출물·런타임 내부와 프로덕션 패턴

nitro build(또는 Nuxt의 nuxt build)는 엔트리 그래프를 단일 번들로 묶고, 프리셋에 따라 서버 핸들러를 람다 핸들러 형태로 쪼개거나 Node listener 로 감쌉니다. 내부적으로 중요한 점은 “소스의 server/api 트리”가 라우트 테이블 + 미들웨어 체인으로 컴파일된다는 것입니다. 그래서 동적 경로·캐시 규칙이 빌드 타임에 고정되는 부분이 있어, Edge 제약(동적 import 제한 등)은 프리셋별로 다르게 드러납니다.

프로덕션에서는 (1) 프리셋을 환경별로 고정하고 CI에서 nitro build --preset을 검증하고, (2) 콜드 스타트가 있는 타겟(Lambda, Workers)에서는 번들 크기·트리 쉐이킹외부 의존성의 순수 JS 여부를 점검하며, (3) Unstorage 드라이버가 해당 런타임에서 실제로 붙는지(예: Edge에서 fs 기반 드라이버 금지)를 통합 테스트로 막습니다.

트러블슈팅

증상점검
로컬은 되는데 배포만 404baseURL·nitro.routeRules·호스팅의 서브패스 배포 불일치
Edge에서 Node API 사용 오류node:*·일부 npm 패키지. 조건부 import 또는 Node 프리셋으로 이동
캐시가 안 먹음swr/isr 규칙과 실제 응답 헤더, CDN이 캐시 키에 무엇을 넣는지
WebSocket만 실패프리셋별 업그레이드·타임아웃; 서버리스는 WS 미지원인 경우가 많음
메모리 급증스트리밍 응답·대용량 readBody 전체 버퍼링. 청크 처리와 한도 검토

9. 정리

Nitro는 “서버 코드의 이식성” 을 현실로 만드는 레이어입니다. 파일 기반 라우팅으로 API를 정의하고, routeRules하이브리드 렌더링·캐시를 설계하며, Unstorage로 환경별 스토리지를 교체하고, WebSocket·SSE로 실시간 요구를 보완할 수 있습니다.

프리셋마다 런타임 제약이 다르므로, 초기에 배포 타겟을 고정하고 제약을 CI에서 검증하며, 캐시·저장소·인증을 경로별로 명시적으로 나누는 것이 프로덕션에서 가장 큰 비용 절감으로 이어집니다.


참고로 읽으면 좋은 글

동일 블로그의 Nuxt 3 완벽 가이드, WebSocket 완벽 가이드, Cloudflare Workers 완벽 가이드를 이어 읽으면 클라이언트·엣지·실시간 계층을 한데 묶는 그림이 선명해집니다.

심화 부록: 구현·운영 관점

이 부록은 앞선 본문에서 다룬 주제(「Nitro 완벽 가이드 | 유니버설 서버 엔진·라우팅·캐시·Edge·실전 API」)를 구현·런타임·운영 관점에서 다시 압축합니다. 도메인별 세부 구현은 글마다 다르지만, 입력 검증 → 핵심 연산 → 부작용(I/O·네트워크·동시성) → 관측의 흐름으로 장애를 나누면 원인 추적이 빨라집니다.

내부 동작과 핵심 메커니즘

flowchart TD
  A[입력·요청·이벤트] --> B[파싱·검증·디코딩]
  B --> C[핵심 연산·상태 전이]
  C --> D[부작용: I/O·네트워크·동시성]
  D --> E[결과·관측·저장]
sequenceDiagram
  participant C as 클라이언트/호출자
  participant B as 경계(런타임·게이트웨이·프로세스)
  participant D as 의존성(API·DB·큐·파일)
  C->>B: 요청/이벤트
  B->>D: 조회·쓰기·RPC
  D-->>B: 지연·부분 실패·재시도 가능
  B-->>C: 응답 또는 오류(코드·상관 ID)
  • 불변 조건(Invariant): 버퍼 경계, 프로토콜 상태, 트랜잭션 격리, FD 상한 등 단계별로 문장으로 적어 두면 디버깅 비용이 줄어듭니다.
  • 결정성: 순수 층과 시간·네트워크·스케줄에 의존하는 층을 분리해야 테스트와 장애 분석이 쉬워집니다.
  • 경계 비용: 직렬화, 인코딩, syscall 횟수, 락 경합, 할당·GC, 캐시 미스를 의심 목록에 둡니다.
  • 백프레셔: 생산자가 소비자보다 빠를 때 버퍼·큐·스트림에서 속도를 줄이는 신호를 어디에 둘지 정의합니다.

프로덕션 운영 패턴

영역운영 관점 질문
관측성요청 단위 상관 ID, 에러율·지연 p95/p99, 의존성 타임아웃·재시도가 대시보드에 보이는가
안전성입력 검증·권한·비밀·감사 로그가 코드 경로마다 일관적인가
신뢰성재시도는 멱등 연산에만 적용되는가, 서킷 브레이커·백오프·DLQ가 있는가
성능캐시·배치 크기·커넥션 풀·인덱스·백프레셔가 데이터 규모에 맞는가
배포롤백 룬북, 카나리/블루그린, 마이그레이션·피처 플래그가 문서화되어 있는가
용량피크 트래픽·디스크·FD·스레드 풀 상한을 주기적으로 검증하는가

스테이징은 데이터 양·네트워크 RTT·동시성을 프로덕션에 가깝게 맞출수록 재현율이 올라갑니다.

확장 예시: 엔드투엔드 미니 시나리오

앞선 본문 주제(「Nitro 완벽 가이드 | 유니버설 서버 엔진·라우팅·캐시·Edge·실전 API」)를 배포·운영 흐름에 맞춰 옮긴 체크리스트입니다. 도메인에 맞게 단계 이름만 바꿔 적용할 수 있습니다.

  1. 입력 계약 고정: 스키마·버전·최대 페이로드·타임아웃·에러 코드를 경계에 둔다.
  2. 핵심 경로 계측: 요청 ID, 단계별 지연, 외부 호출 결과 코드를 로그·메트릭·트레이스에서 한 흐름으로 본다.
  3. 실패 주입: 의존성 타임아웃·5xx·부분 데이터·락 대기를 스테이징에서 재현한다.
  4. 호환·롤백: 설정/마이그레이션/클라이언트 버전을 되돌릴 수 있는지 확인한다.
  5. 부하 후 검증: 피크 대비 p95/p99, 에러율, 리소스 상한, 알림 임계값을 점검한다.
handle(request):
  ctx = newCorrelationId()
  validated = validateSchema(request)
  authorize(validated, ctx)
  result = domainCore(validated)
  persistOrEmit(result, idempotentKey)
  recordMetrics(ctx, latency, outcome)
  return result

문제 해결(Troubleshooting)

증상가능 원인조치
간헐적 실패레이스, 타임아웃, 외부 의존성, DNS최소 재현 스크립트, 분산 트레이스·로그 상관관계, 재시도·서킷 설정 점검
성능 저하N+1, 동기 I/O, 락 경합, 과도한 직렬화, 캐시 미스프로파일러·APM으로 핫스팟 확인 후 한 가지씩 제거
메모리 증가캐시 무제한, 구독/리스너 누수, 대용량 버퍼, 커넥션 미반납상한·TTL·힙/FD 스냅샷 비교
빌드·배포만 실패환경 변수, 권한, 플랫폼 차이, lockfileCI 로그와 로컬 diff, 런타임·이미지 버전 핀
설정 불일치프로필·시크릿·기본값, 리전스키마 검증된 설정 단일 소스와 배포 매트릭스 표준화
데이터 불일치비멱등 재시도, 부분 쓰기, 캐시 무효화 누락멱등 키·아웃박스·트랜잭션 경계 재검토

권장 순서: (1) 최소 재현 (2) 최근 변경 범위 축소 (3) 환경·의존성 차이 (4) 관측으로 가설 검증 (5) 수정 후 회귀·부하 테스트.

배포 전에는 git addgit commitgit pushnpm run deploy 순서를 권장합니다.


자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. Nitro는 Nuxt·Analog의 서버 엔진입니다. 파일 라우팅, 하이브리드 캐시, Storage·KV, WebSocket, Vercel·Netlify·AWS 배포와 실전 API 패턴을 정리합니다. 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


이 글에서 다루는 키워드 (관련 검색어)

Nitro, Server, Nuxt, API, Edge 등으로 검색하시면 이 글이 도움이 됩니다.