Vercel Serverless POST, PUT 예제 | Jsonplaceholder

고광필·2022년 7월 19일
1

Front

목록 보기
23/33

Vercel Serverless 예제 이후 바로 프로젝트에 vercel serverless 함수를 적용하려 했으나
post, put method와 body 조작이 필요해서 관련 내용을 git, vercel 배포링크에 추가했습니다
그 내용을 블로그에도 작성하겠습니다

0. vercel dev

npm i -g vercel
vercel dev

명령어로 vercel을 글로벌로 설치한 후
vercel dev 명령어로 serverless 함수가 잘 돌아가는지 확인할 수 있습니다

이걸 몰라서 하나하나 푸시해서 실제 vercel 링크에서 테스트했는데
이제 너무 편합니다

1. 기존 코드 수정

import fetch from 'node-fetch';

// url/api/get
export default async function getTodos(request, response) {
  const res = await fetch(process.env.BASE_URL);
  const data = await res.json();
  // return response.status(200).json({ data });
  return response.status(200).json(data);
}
  • 기존의 getTodos는 객체를 내려주어서 fetch 결과값.data를 사용해야 했습니다
    굳이 이럴 필요가 없으니 데이터를 바로 내려주도록 수정합니다

  • post, put을 추가할 예정이기 때문에 보기 쉽도록 각각 폴더 구조를 만들 계획입니다
    이 코드는 get 폴더로 이동합니다

  • vercel serverless 함수는 handler라는 네이밍을 사용하지 않아도 인식됩니다
    폴더 구조를 통해서 알 수 있지만, 좀 더 직관적이기 위해 함수 이름을 getTodos로 바꿉니다

2. post, put 추가

Jsonplaceholder Guide에 있는 post 사용법입니다
method, body, headers를 설정하면 해당 내용이 처리됩니다
추가한 내용이 응답으로 돌아오지만, 실제로 반영이 되지는 않습니다

body 접근

// /api/post/index.js
import fetch from 'node-fetch';

// url/api/post 처럼 사용
export default async function postTodo(request, response) {
  const { body } = request;
  const res = await fetch(process.env.BASE_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });
  const data = await res.json();
  return response.status(200).json(data);
}

post serverless 함수입니다
request.body를 통해 body에 대한 내용을 넘겨받을 수 있습니다
넘겨받은 body를 jsonplaceholder로 보냅니다

// post code
export const postTodo = async () => {
  const response = await fetch('/api/post', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      userId: 1,
      title: 'new Todo',
      completed: true,
    }),
  });
  const result = response.json();
  return result;
};

body를 넘기는 post 요청 코드입니다
title, completed에 대한 데이터도 인자로 받아도 되지만, 테스트용이기 때문에 이렇게만 사용합니다

PUT도 method만 바꿔서 이와 동일하게 작성합니다

request.js에서 종합 관리

vercel serverless 관련 파일은 api 폴더에서 관리하고 있지만
React에서 요청보내는 코드는 getTodos, getTodo, postTodo, updateTodo가 있기 때문에 한 파일에서 관리할 수 있도록 합니다

// request.js
export const getTodos = async () => {
  const response = await fetch('/api/get');
  const result = response.json();
  return result;
};

export const getTodo = async (id) => {
  const response = await fetch(`/api/get/${id}`);
  const result = response.json();
  return result;
};

export const postTodo = async () => {
  const response = await fetch('/api/post', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      userId: 1,
      title: 'new Todo',
      completed: true,
    }),
  });
  const result = response.json();
  return result;
};

export const updateTodo = async (id) => {
  const response = await fetch(`/api/put/${id}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      userId: 1,
      id,
      title: 'change Todo',
      completed: true,
    }),
  });
  const result = response.json();
  return result;
};

3. method 방어코드 추가

/api/put/1 의 경우 UPDATE 메소드로 접근해야 하는데
POST 메소드로 접근해도 잘 동작합니다

request.method를 통해 적절한 method인지 필터링하도록 코드를 추가합니다

// /api/put/index.js
import fetch from 'node-fetch';

// url/api/put/id 처럼 사용
export default async function updateTodo(request, response) {
  if (request.method !== 'PUT') {
    return response.status(400).json('method Error');
  }

  const { body } = request;
  const { id } = request.query;
  const res = await fetch(`${process.env.BASE_URL}/${id}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(body),
  });
  const data = await res.json();
  return response.status(200).json(data);
}

postman으로 테스트해보면 PUT 요청일 때는 잘 동작하고

POST 요청일 때는 400에러가 발생합니다

최종

github 레포지토리 링크에서 코드를 확인할 수 있고
vercel 배포 링크에서 테스트가 가능합니다

노션 및 다른 프로젝트 배포시에 계속 참고할 예정입니다

참고

Vercel 공식 Docs
Jsonplaceholder 공식 사이트

profile
이해하는 개발자를 희망하는 고광필입니다.

0개의 댓글