TIL 41 | Fetch method(2) - get / post

1차 프로젝트를 진행하면서 가장 큰 수확은 내가 제대로 알지 못했던 '빈틈'이 무엇이었는지 명확해졌다는 사실이다. 마치 모레성에 집을 지은듯한 느낌을 계속해서 받았는데
아무래도 기초 지식의 빈틈이 많았기 때문이었다.

백앤드로부터 데이터를 받아오려면 api를 호출하고 데이터를 응답받는다.
이 때 JS Web API fetch() (= js 내장함수) 함수를 쓰거나 axios 라이브러리를 사용할 수 있는데 현업에 가면 fetch를 많이 사용할 일이 없다고 하지만
fetch를 써봄으로써 http 통신의 요청와 응답에 대한 이해, Promise 개념에 대해서 추가적으로 공부할 수 있는 시간이 될 것 이다.
또한 해당 내용의 예제는 wecode의 수업자료로 쓰여있던 부분을 참고하였다.

참고: https://yeri-kim.github.io/posts/fetch/

1. fetch() 함수 기본

1) fetch() 함수 기본 문법

그림을 보면 2개의 fetch() 함수 기본을 볼 수 있다. 첫번째는 화살표 함수를 통해 간결하게 쓴 부분이고 두번째는 화살표 함수를 풀어서 쓴 함수선언식이다.

2) res의 Local Scope

사진을 보면 3개의 res가 동그라미로 표시되어 있다.
세개의 res는 결코 똑같은 변수가 아니다! 위 코드에서 변수의 scope는 각 함수이므로 첫 번째 then와 두 번째 then 안에 있는 res는 서로 다르다.
자바스크립트에서 함수를 선언하면 함수를 선언할 때마다 새로운 스코프를 생성하게 되며 함수 몸체에 선언한 변수는 해당 함수 몸체 안에서만 접근할 수 있는 Local Scope(지역 변수)이기 때문이다.

참고: 스코프(Scope)란?
https://medium.com/@yeon22/javascript-%EC%8A%A4%EC%BD%94%ED%94%84-scope-%EB%9E%80-bc761cba1023

3) res의 Local Scope

받은 api명세서 (메뉴판!)


base url: https://api.google.com
endpoint: /user/1
method: get
응답형태:
    {
        "success": boolean,
        "user": {
            "name": string,
            "batch": number
        }
    }

end point를 살펴보니 user 뒤에 있는 숫자 1이 있다.
user id에 따라 유동적으로 바뀌는 값이므로 아래 리액트를 통해 고정값이 아닌 유동적인 주소로 바꿔야 할 것 같다.
따라서,

import React, { Component } from 'react';

class User extends Component {
  componentDidMount() {
    // user id가 props를 통해 넘어온다고 가정
    const { userId } = this.props;

    fetch(`https://api.google.com/user/${userId}`)
      .then(res => res.json())
      .then(res => {
        if (res.success) {
            console.log(`${res.user.name}` 님 환영합니다);
        }
      });
  }
}

4) fetch() 함수 - method가 post인 경우

해당 api가 get인지 post인지 알기위해선 해당 메뉴판을 만든 BE개발자와 소통해야 한다. 또한 기본형인 get이랑 다른점이 있는데 그것은 fetch의 두번째 인자에 method와 body를 입력해야 한다는 것 이다.
받은 api명세서 (메뉴판!)

설명: 유저를 저장한다.
base url: https://api.google.com
endpoint: /user
method: post
요청 body:
    {
        "name": string,
        "batch": number
    }

응답 body:
    {
        "success": boolean
    }
fetch('https://api.google.com/user', {
    method: 'post',
    body: JSON.stringify({
        name: "yeri",
        batch: 1
    })
  })
  .then(res => res.json())
  .then(res => {
    if (res.success) {
        alert("저장 완료");
    }
  })

body는 JSON형태로 보내기 위해 JSON.stringfy() 함수에 객체를 인자로 전달하여 JSON형태로 변환하였다.

5) fetch() 함수 - method가 get인데 parameter를 전달해야 하는 경우

BE개발자가 get이지만 path가 아닌 query string으로 넘겨주었을 때는
우리도 parameter를 전달해야 한다.
하는 방법은 굉장히 간단하다. api 주소 뒤에 그냥 붙여주기만 하면 된다.

설명: 유저 정보를 가져온다.
base url: https://api.google.com
endpoint: /user
method: get
query string: ?id=아이디
응답형태:
    {
        "success": boolean,
        "user": {
            "name": string,
            "batch": number
        }
    }
fetch('https://api.google.com/user?id=3')
  .then(res => res.json())
  .then(res => {
    if (res.success) {
        console.log(`${res.user.name}` 님 환영합니다);
    }
  });

6) fetch() 함수 - 첫 번째 then 함수에 추가되는 로직

백앤드에서 응답 body를 안 주는 경우도 많은데 이때 응답 body로 JSON 데이터를 주지 않는데 프론트에서 Response Object의 json()을 호출하면 에러가 난다.
그럴때 어떻게 해야하는지 예제를 통해서 익혀보자.

설명: 유저를 저장한다.
base url: https://api.google.com
endpoint: /user
method: post
요청 body:
    {
        "name": string,
        "batch": number
    }

응답 body:
    1. 제대로 저장했으면 status code를 200 전달. 응답 body는 없음
    2. 권한 오류가 생기면 status code를 403으로 전달하고. 응답 body는 아래와 같음
        {
            success: false,
            message: "권한이 없습니다"
        }

좋은 웹페이지 즐겨찾기