본문 바로가기
nextjs

route handlers

by dev__log 2024. 3. 15.

next.js 는 풀스택을 지원하는데, route hander는 API 요청에 대한 내용을 작성하여 백엔드 로직을 수행한다. 

app 디렉토리 하위에 route.js(ts) 파일을 만나면 next.js 는 route handlers로 인식한다. 

보통 app/api/ 의 경로에 폴더별로 구분하여 구성한다. 

 

아래는 todo list를 만들면서 작성한 route 파일과 폴더 구조이다.

 

 

route 파일 안의 함수명은 POST, GET, PUT, DELETE 등의 메소드 이름으로 대문자 형식으로 만들어야 컴포넌트에서 보낸 요청이 연결된다.

 

app/api/todos/route.ts

export async function GET(request: Request) {
  try {
    const response = await fetch("http://localhost:4000/todos");
    const todos = await response.json();

    if (!todos) {
      return new Response("todos is not found", {
        status: 404
      });
    }

    return Response.json(todos);
  } catch (error) {
    // 에러 처리
    console.error("An error occurred while fetching todos:", error);
    return new Response("An error occurred while fetching todos", {
      status: 500
    });
  }
}

export async function POST(request: Request) {
  try {
    const { title, contents } = await request.json();

    if (!title) {
      return new Response("title is not found", {
        status: 404
      });
    }

    if (!contents) {
      return new Response("contents is not found", {
        status: 404
      });
    }

    const response = await fetch("http://localhost:4000/todos", {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({ title, contents, isDone: false })
    });

    const todo = await response.json();
    return Response.json(todo);
  } catch (error) {
    // 에러 처리
    console.error("An error occurred while fetching todos:", error);
    return new Response("An error occurred while fetching todos", {
      status: 500
    });
  }
}

 

이렇게 작성된건 page.tsx에서 useQuery, useMutation을 통해 요청을 보낸다.

 

 

 

/src/components/TodoForm.tsx 코드의 일부분

"use client";

import { useMutation, useQueryClient } from "@tanstack/react-query";
import React, { useRef } from "react";

export const TodoForm = () => {
  const titleRef = useRef<HTMLInputElement>(null);
  const contentsRef = useRef<HTMLInputElement>(null);
  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn: async (newTodo: { title: string; contents: string }) => {
      const response = await fetch("http://localhost:3000/api/todos", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify(newTodo)
      });
      return await response.json();
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["todos"] });
    }
  });
  return (
   ..생략
  )
};

 

http://localhost:3000/api/todos

todo를 등록하는 POST 요청을 보내는데 주소가 json-server(4000)가 아닌 현재 프로젝트가 실행중인 3000번으로 route.ts 파일을 작성한 경로로 요청을 보낸다는 점이 중요하다! 

route.ts 파일도 page.tsx 파일처럼 라우팅에 관련이 있기 때문에 app의 하위 폴더에 위치하고, 그 외에 컴포넌트는 app 밖에 경로에 위치한다는 것을 알 수 있다.

 

또한 useQuery, useMutation 을 사용하는 CSR 렌더링 방식이기 때문에 상단에  'use client' 를 선언하여 CSR 렌더링 방식으로 만들어준다.

'nextjs' 카테고리의 다른 글

next.js 기초  (0) 2024.03.13