티스토리 뷰

Next.js

NextJS 14 NextApiRequest vs NextRequest (feat.request.json 타입 지정하기)

YG - 96년생 , 강아지 있음, 개발자 희망 2023. 12. 7. 01:51

request.json의 값을 타입 지정하고 싶었습니다.

 

검색하여서 적용한 방법. (NextApiRequest를 확장하여 사용하는 방법)

interface CategoryApiRequest extends NextApiRequest {
  body: {
    name: string;
    description?: string;
  };
}

export async function POST(request: CategoryApiRequest) {
  const { name, description } = request.body;

 

 

비슷하게 생긴 NextRequest와 NextApiRequest 둘의 차이가 무엇인지 알아보려고 합니다.

 

NextRequest

Request는 NodeJs의 Request를 확장하여 만든 클래스였습니다. 그래서 interface, type으로 이루어진 타입이 아닌 class로 이루어져 있었습니다. 

export declare const INTERNALS: unique symbol;
export declare class NextRequest extends Request {
    [INTERNALS]: {
        cookies: RequestCookies;
        geo: RequestData['geo'];
        ip?: string;
        url: string;
        nextUrl: NextURL;
    };
    constructor(input: URL | RequestInfo, init?: RequestInit);
    get cookies(): RequestCookies;
    get geo(): {
        city?: string | undefined;
        country?: string | undefined;
        region?: string | undefined;
        latitude?: string | undefined;
        longitude?: string | undefined;
    } | undefined;
    get ip(): string | undefined;
    get nextUrl(): NextURL;
    /**
     * @deprecated
     * `page` has been deprecated in favour of `URLPattern`.
     * Read more: https://nextjs.org/docs/messages/middleware-request-page
     */
    get page(): void;
    /**
     * @deprecated
     * `ua` has been removed in favour of \`userAgent\` function.
     * Read more: https://nextjs.org/docs/messages/middleware-parse-user-agent
     */
    get ua(): void;
    get url(): string;
}

interface Request extends NodeJS.fetch._Request {}
declare var Request: typeof globalThis extends {
    onmessage: any;
    Request: infer T;
} ? T
    : typeof import("undici-types").Request;

 

 

이것만으로는 정보가 부족해서 공식 문서를 찾아봤습니다.

 

NextRequest는 Request에서 Next에서 편의성을 추가한 클래스이고, Middleware에서 사용한다.라고 Pages Router 방식에서는 설명하고 있습니다.

 

 

 

Functions: NextRequest and NextResponse | Next.js

Learn about the server-only helpers for Middleware and Edge API Routes.

nextjs.org

 

 

App Router 방식에서는 이제 Route Hanlders , Middleware 모두  NextRequest, NextResponse 방식을 사용한다고 나와있습니다. 기본적으로는 Request, Reponse이지만 NextRequest, NextResponse에서 편리한 메서드를 지원하니 고급 사례에  사용할 수 있다고 알려주고 있었습니다.

 

 

 

 

타입 지정해 주는 방법

 

POST에서 request를 받아 json을 실행하여 읽은 값들의 타입을 지정해주려고 합니다.

 

아래와 같이 타입을 interface로 선언하고 지정해 주면 any 가 아닌 예상하는 타입 값을 확인할 수 있었습니다.

 

interface CategoryApiRequest {
  name: string;
  description?: string;
}

export async function POST(request: NextRequest) {
  const { name, description }: CategoryApiRequest = await request.json();

 

 

 

 

 

NextApiRequest

NextApiRequest는 interface로 이루어진 타입을 위해 선언된 코드였는데요. 주석에 따르면 Next API route request에서 사용하라고 적혀있습니다. 

 

/**
 * Next `API` route request
 */
export interface NextApiRequest extends IncomingMessage {
    /**
     * Object of `query` values from url
     */
    query: Partial<{
        [key: string]: string | string[];
    }>;
    /**
     * Object of `cookies` from header
     */
    cookies: Partial<{
        [key: string]: string;
    }>;
    body: any;
    env: Env;
    draftMode?: boolean;
    preview?: boolean;
    /**
     * Preview data set on the request, if any
     * */
    previewData?: PreviewData;
}

 

 

마찬가지로 공식 문서를 찾아봤습니다.

 

NextApiRequest는 Api route handler에서 사용한다고 나와있습니다. 그리고 Pages Router 방식에서만 사용된다는 것을 알 수 있었습니다.

 

app에서는 결과가 없습니다.
pages에서는 결과가 있습니다.

 

 

 

 

 

Routing: API Routes | Next.js

Next.js supports API Routes, which allow you to build your API without leaving your Next.js app. Learn how it works here.

nextjs.org

 

 

타입 지정하는 방법

 

pages router 방식에서는 req.json으로 읽는 것이 아닌 req.body로 값을 읽는다고 합니다.

 

import type { NextApiRequest, NextApiResponse } from 'next'
 
export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { name, message } = req.body
 
  try {
    await handleFormInputAsync({ name, message })
    res.redirect(307, '/')
  } catch (err) {
    res.status(500).send({ error: 'Failed to fetch data' })
  }
}

 

 

그래서 타입 지정을 해주려면 아래와 같이 NextApiRequest를 확장하여서 타입 지정을 해줄 수 있었습니다.

자동 완성이 잘 되는 모습

 

결론

NextRequest

 

- app router 방식에서 Route Handler, Middleware 방식에서 모두 사용된다.

- pages router 방식에서 Middleware 방식 등에 사용된다.

 

 

 

NextApiRequest

- app router 방식에서는 사용되지 않는다.

- pages router 방식에서는 Route Handler 방식에서 사용된다.

 

 

NextJS가 App Router 방식과 Pages Router 방식이 모두 존재해서 헷갈리네요!

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함