[React] HTTP: POST

summereuna🐥·2023년 5월 22일
0

React JS

목록 보기
57/69

실제로 앱에서는 데이터를 가져오는 GET 요청 뿐만 아니라, 서버로 데이터를 보내어 저장하는 POST 요청 작업도 많이 한다.

  • 예) 새로운 사용자 생성, 블로그 글 포스팅 등

현재 사용하고 있는 스타워즈 영화 API는 단순 실습용 더미 API이기 때문에 GET 요청만 가능하고 POST 요청은 사용할 수 없다. 따라서 공짜인 구글의 firebase를 사용하여 POST 요청을 연습해보자.

Firebase: Realtime DB

firebase는 코드 작성 없이도 사용 가능한 백엔드로, firebase는 사실 데이터 베이스는 아니다. 데이터 베이스에 딸린 백엔드지만 요청을 주고 받을 수 있는 완전한 REST API를 재공하는 풀 백엔드 어플리케이션이다.

  1. 먼저 파이어베이스에 접속하여 구글 로그인
  2. 콘솔에서 새로운 프로젝트 추가(구글 통계는 필요 없으므로 비활성화)
  3. 클라우드 Firestore가 기능상 더 강력하긴 하지만 더미 백엔드면 충분하기 때문에 실시간 데이터베이스면 충분
  4. 데이터베이스 생성 > 지역은 아무데나 설정 > Test Mode로 만들것! 그렇게 해야 요청 전송이 가능하다.
  5. URL이 제공된다.
    프론트 앱은 데이터베이스와 직접 소통 불가능하다. 여기서도 마찬가지이다. 이 URL은 Firebase REST API에 대한 URL이며 이 API는 들어오는 요청을 받고 배그라운드의 데이터베이스와 통신한다.
    그냥 보기에 디비랑 직접 소통하는 것 처럼 보일 뿐이지 실제로 그렇지 않다는 사실을 기억하자!
    여튼 이제 이 URL을 통해 firebase의 백엔드인 우리의 디비로 데이터를 보낼 수 있다.

POST 요청 보내기: fetch()

POST 요청도 fetch()로 할 수 있다.
패치 이름만 보면 데이터를 가져올 때만 사용하는 것 같겠지만, 데이터를 전송할 때도 사용한다.

1. 첫 번째 인자: 엔드포인트 설정

  • fetch("URL")
    첫번째 인자로 GET요청을 보냈던 것과 같이 데이터를 가져오는 API URL에 요청을 보내면 된다.
fetch("https://파이어베이스URL/movies.json")
  • 파이어베이스에서 제공한 REST API의 URL/movies.json 세그먼트를 추가하여 데이터 베이스에 새로운 노드를 추가하자.
    이는 동적 REST API로, 서로 다른 세그먼트를 사용하여 데이터베이스의 서로 다른 노드들에 데이터를 저장할 수 있게 설정할 수 있다.
    • 확장자를 꼭 .json으로 해야 한다. firebase는 요청 전달하는 URL 끝에 .json을 추가하라고 말한다.

2. 엔드포인트에 POST 요청 보내기: 두 번째 인자에 method 설정

  • { method: "POST"}
    두 번째 인자로 { method: "POST" }를 보내면 POST 요청을 보낼 수 있다
    두 번째 인자의 디폴트 값은 { method: "GET" }이기 때문에 GET 요청을 보낼때는 두 번째 인자를 생략할 수 있다.

3. body에 리소스 넣어 전달하기

엔드포인트에 POST 요청을 보내면 firebase는 디비에 리소스를 만든다.
POST 요청을 보냈을 때 정확히 어떤일이 일어나는지는 우리가 사용하는 이 백엔드 API 안의 로직에 따라 이루어지기 때문에 어떻게 POST 요청이 이루어지는지는 정확히 알 수는 없지만, POST 요청을 보내면 firebase는 리소스를 생성해 둔다.

  • { body: JSON.stringify(리소스) })
    저장할 리소스는 json으로 두 번째 인자로 보내는 객체 안에 body로 전달하면 된다.
    현재 저장할 movie가 JS 객체이기 때문에 json으로 바꿔서 body에 넣어줘야 한다.
  • json은 데이터 형태로 프론트엔드와 백엔드간에 데이터 교환에 사용되는 유형이다.
  • 📚 JS 객체나 배열을 JSON 형식으로 바꾸는 방법
    • JSON.stringify(JS객체)
      JS 브라우저 안에 내장된 JSON 객체에 stringify를 호출하기

4. 헤더 추가

  • headers: { "Content-Type": "application/json" }
    좀 더 명확히 하기 위해 헤더를 추가한다. 헤더를 추가하면 어떤 컨텐츠가 전달되는지 더 명확하게 알릴 수 있다. 헤더가 없어도 요청은 정상적으로 처리되지만 요청을 받는 대다수의 API는 헤더를 필요로 한다.

5. 비동기 작업 처리 및 반환되는 데이터 json으로 받기

  • async / await
    먼저 비동기 작업이고 프로미스를 돌려받을 것이기 때문에 async, await을 적어주자.

  • const data = await response.json;
    그리고 firebase가 생성한 리소스를 json으로 가져온다.
    전달하는 데이터의 형식은 JSON 형식이기 때문에 json으로 가져오면 된다.

const addMovieHandler = async (movie) => {
  const response = await fetch(
    "https://파이어베이스URL/movies.json",
    {
      method: "POST",
      body: JSON.stringify(movie),
      headers: {
        "Content-Type": "application/json",
      },
    }
  );
  
  //firebase가 전달하는 데이터는 JSON 형식이니까 이렇게 가져오면 된다.
  const data = await response.json;
  console.log(data);
};

GET 요청 부분 수정

디비에서 데이터를 불러오려면 GET요청을 하는 부분에도 수정이 필요하다.

1. fetch URL을 firebase url로 수정한다.

//URL 수정
fetch(
  "https://파이어베이스URL/movies.json"
);

if (!response.ok) {
  throw new Error("Something went wrong!");
}

const data = await response.json();

console.log(data);
  • console.log(data);
    그러고 나서 콘솔에 패치가 반환하는 데이터를 찍어보면 아래 처럼 데이터가 어떻게 생겼는지 알 수 있다.
    암호화된 ID키 안에 영화 데이터가 중첩 객체로 들어가 있다.

  • 그리고 데이터가 배열이 아닌 객체로 들어가 있다.

  • 따라서 새로운 배열을 하나 만들고 map이 아닌 for 루프를 사용하여 객체 데이터 안의 모든 키를 확인하여 데이터의 키-값 조합에 대해 새로운 객체를 새 배열 안으로 푸쉬하는 방법을 사용하자.

const loadedMovies = [];

for (const key in data) {
  loadedMovies.push({
    id: key,
    title: data[key].title,
    openingText: data[key].openingText,
    releaseDate: data[key].releaseDate,
  });
  • 전체 코드
const response = await fetch(
  "https://파이어베이스URL/movies.json"
);

//데이터 파싱 전에 response 체크 하여 오류 메시지 만들기
if (!response.ok) {
  throw new Error("Something went wrong!");
}

const data = await response.json();

console.log(data);
//암화화된 ID키 안에 영화 데이터는 중첩된 객체로 들어가 있음
//배열로 가져오지 않고 객체로 받고 있으므로, 배열을 만들고 map이 아닌 for을 사용
const loadedMovies = [];
//for 루프로 객체 데이터 안의 모든 키 확인
//for 루프 안에서 loadedMovies에 전달받은 데이터의 키-값 조합에 대해 새로운 객체를 푸쉬
for (const key in data) {
  loadedMovies.push({
    id: key,
    title: data[key].title,
    openingText: data[key].openingText,
    releaseDate: data[key].releaseDate,
  });
}

이렇게 하면 중첩된 데이터 잘 꺼낼 수 있다
JS의 속성에 대한 동적 접근 방법으로 중첩 객체의 데이터를 가져올 수 있다.

profile
Always have hope🍀 & constant passion🔥

0개의 댓글