Fetch API

Nina·2020년 11월 22일
0
post-thumbnail

1. fetch()

"The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network."

프론트엔드는 api를 호출해서 백엔드로부터 데이터를 받는다. 이 때 fetch()함수를 사용하여 통신을 한다. fetch()는 web API의 일종으로, 클라이언트 측에서 사용할 수 있는 자바스크립트 내장함수이다.
기본적인 fetch() 함수의 구성은 다음과 같다.

fetch(api 주소)
  .then(function(res) {
    return res.json();
  })
  .then(function(result) {
    console.log(JSON.stringify(result));
  });

상기 코드를 보면 .then이 두 번 있고 첫번째 then에서는 res.json()을 반환한다. 첫번째 then 함수에 전달된 인자인 res는 응답의 정보를 담고있는 객체(response object)이며, 실제 데이터가 아니다. 따라서 응답으로 받는 body 데이터를 사용하기 위해서는 동 response object의 json 함수를 호출, 반환하여야한다.

2. 예시

(1) 백엔드

    @utils.signin_decorator
    def post(self, request):
        try:
            data            = json.loads(request.body)
            user_id         = request.user.id
            chosen_products = data['chosen_product']

            target_cart, flag   = Order.objects.get_or_create(user_id = user_id, 
                                                              order_status_id = 1)
            target_options      = [chosen_products[i]["product_option_id"] 
                                 for i in range(0, len(chosen_products))]

            for option in target_options:
                if OrderProduct.objects.filter(order = target_cart.id, 
                                               product_option = option).exists():

                    return JsonResponse(
                        {'message':'ALREADY_EXISTS'},
                        status=409)

            target_products = [ProductOption.objects.get(id = target_options[i]).product_id 
                              for i in range(0, len(target_options))]

            target_amount   = [chosen_products[i]['amount'] 
                              for i in range(0, len(chosen_products))]

            for j in range(0, len(target_options)):
                OrderProduct(
                    product_amount = target_amount[j],
                    order_id = target_cart.id,
                    product_id = target_products[j],
                    product_option_id = target_options[j]
                ).save()

            return JsonResponse(
                {"message":"PRODUCT_ADDED"},
                status=201
            )

        except KeyError:
            return JsonResponse(
                {"message":"KEY_ERROR"},
                status=400
            )

(2) 프론트엔드

handleCart() {
    console.log("test1", this.state.chosenProduct);
    fetch(`${API_CY}/order/cart`, {
      method: "POST",
      headers: {
        Authorization: localStorage.getItem("token")
      },
      body: JSON.stringify({ chosen_product: this.state.chosenProduct })
    })
      .then(res => res.json())
      .then(res => {
        if (res.message === "ALREADY_EXISTS") {
          alert("이미 장바구니에 담겨있다구!");
        } else {
          alert("장바구니에 저 ! 장 !");
        }
      });
  }

(3) 설명

💻{API_CY}/order/cart

api 주소({API_CY}은 Config 파일에 저장된 내 ip주소)

💻post

post 메소드로 요청 보냄

💻Authorization: localStorage.getItem("token")

로컬 스토리지에 저장된 토큰을 헤더에 담아 보냄. utils.py의 "token =request.headers.get('Authorization', None)"와 연결된다.

💻body: JSON.stringify({ chosen_product: this.state.chosenProduct })

장바구니에 담을 물건들을 body에 담아 보낸다. 내가 쓴 "chosen_products = data['chosen_product']"와 연결됨.

💻.then(res => {if (res.message === "ALREADY_EXISTS") (중략)

내가 쓴 "return JsonResponse({'message':'ALREADY_EXISTS'},status=409)"에서 연결됨. 내가 응답으로 'ALREADY_EXISTS'를 보내는 경우 실행될 함수이다.

💻else {alert("장바구니에 저 ! 장 !");}

그 외 "return JsonResponse({"message":"PRODUCT_ADDED"},status=201)"의 경우 실행될 함수

profile
https://dev.to/ninahwang

0개의 댓글