티스토리 뷰

반응형

[nextjs+ts]프로젝트 06. api request middleware 만들기(nextjs)

 

nextjs의 장점은 서버와 클라이언트를 모두 한곳에서 운용이 가능하다는 것이다.

nestjs혹은 spring이나 asp.net에서 제공하는 middleware 기능을을 nextjs에서 또한 구현할 수있다.

 

#useMutation 구현(api 호출을 hook으로 구현)

import { useState } from "react";

interface UseMutationState {
  loading: boolean;
  data?: object;
  error?: object;
}
type UseMutationResult = [(data: any) => void, UseMutationState];

export default function useMutation(url: string): UseMutationResult {
  const [state, setState] = useState<UseMutationState>({
    loading: false,
    data: undefined,
    error: undefined,
  });
  function mutation(data: any) {
    setState((prev) => ({ ...prev, loading: true }));
    fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(data),
    })
      .then((response) => response.json().catch(() => {}))
      .then((data) => setState((prev) => ({ ...prev, data }))) //...prev,data:data
      .catch((error) => setState((prev) => ({ ...prev, error })))//...prev,data:error
      .finally(() => setState((prev) => ({ ...prev, loading: false })));
  }
  return [mutation, { ...state }];
}

 

#로그인 페이지 구현 

-useMutation을 사용하여, enter 함수 구현(api 호출)

import type { NextPage } from "next";
import { useRouter } from "next/router";
import { useForm } from "react-hook-form";
import Button from "../../components/Button";
import Input from "../../components/Input";
import useMutation from "../../libs/client/userMutation";
const Test: NextPage = () => {
  const router = useRouter();

  const [enter, { loading, data, error }] = useMutation("/api/users/enter");

  const goMainPage = () => {
    router.push("/");
  };

  interface EnterForm {
    email?: string;
    password?: string;
  }

  const onValid = (validForm: EnterForm) => {
    console.log('wow');
    if (loading) return;
    enter(validForm);
  };

  const { register, handleSubmit, reset, watch } = useForm<EnterForm>();
  console.log(watch());
  return (
    <div className="flex flex-col items-center rounded-3xl bg-white pb-10">
      <div className=" p-10 text-2xl font-bold">
        <span>@SamsungEngineering CMS</span>
      </div>
      <form onSubmit={handleSubmit(onValid)}>
        <Input
          register={register("email", {
            required: true,
          })}
          name="아이디를 입력해주세요"
          label="아이디"
          type="text"
          required
        />
        <Input
          register={register("password", {
            required: true,
          })}
          name="패스워드를 입력해주세요"
          label="패스워드"
          type="password"
          required
        />
        <div className="mt-5 flex items-center   justify-center ">
          <Button text={"로그인"} />
        </div>
      </form>
      <div className="mt-8 flex flex-col items-center justify-center">
        <span className="text-sm">
          문의가 있는 경우, 아래의 이메일로 연락부탁드립니다.
        </span>
        <span className="text-sm">test@gmail.com</span>
      </div>
    </div>
  );
};

export default Test;

 

#호출 받은 api(/api/users/enter)

기본 처리를 하기전에 withHandler(middleware) 를 호출

import { NextApiRequest, NextApiResponse } from "next";
import client from "../../../libs/server/client";
import withHandler from "../../../libs/server/withHandler";

 async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  console.log(req.body);
  return res.status(200).end();
}
export default withHandler("POST",handler);

 

#method 상태를 받아 온 후 중간에 제약 추가 관리를 진행한다. 지금같은 경우 POST를 제외한 method를 제한한다.

import { NextApiRequest, NextApiResponse } from "next";

export default function withHandler(
  method: "GET" | "POST" | "DELETE",
  fn: (req: NextApiRequest, res: NextApiResponse) => void
) {
  return async function (req: NextApiRequest, res: NextApiResponse) {
    if (req.method !== method) {
      console.log('405');
      return res.status(405).end();
    }
    try {
      console.log('200');
      await fn(req, res);
    } catch (error) {
      console.log(error);     
      return res.status(500).json({ error });
    }
  };
}

 

#react #nextjs #react-hook-form #리액트 #로그인 #login #form #hook #middleware 

반응형
댓글
반응형