Fetch API

오민영·2021년 7월 15일
0

Web API

목록 보기
8/9
post-thumbnail

Fetch API는 네트워크 통신을 포함하여 리소스(데이터) 취득을 위한 인터페이스가 정의되어 있다.
Built-in API(자바스크립트 내장 라이브러리)로 별도의 설치 없이 모던 브라우저에서 사용이 가능하다. window Object(객체)에 속해있기 때문에 window.fetch()로 사용되기도 한다.

기존 XMLHttpHttps(XHR)를 대체하는 개념으로 Request / Response를 포함하며, 결과 값으로 Promise 객체를 반환한다. 때문에 XHR에서 Response를 확인하기 위해서 callback이나 event를 사용하던 부분을 .then(), catch()를 사용해서 확인한다.

특징

  • 결과 값인 Promise 객체는 HTTP error 상태를 reject하지 않는다.
  • Status Code가 404 / 500 인 경우에도 거부하지 않고, revolve 처리를 한다. (ok상태가 false인 resolve를 반환)
  • 네트워크 장애 / 요청 미완료 시 reject를 반환한다.
  • Cookies를 보내거나, 받지 않는다.

문법

let promise = fetch(URL, [option]);

//Get방식
fetch('http://example.com/movies.json') //서버 주소를 첫 번째 인자로 넘김
.then(res => console.log(res)) //통신 성공 시 수행 할 코드
.catch(err => console.log(err)); //error 발생 시 예외처리 할 코드

//Post방식
const option = {
  method : "POST",
  body : ...,
  header : {}
}
fetch('http://example.com/movies.json', option) //두 번째 인자에 객체를 인자로 전달한다
.then(res => console.log(res)) //통신 성공 시 수행 할 코드
.catch(err => console.log(err)); //error 발생 시 예외처리 할 코드

첫 번째 인자로 URL, 두 번째 인자로 options 객체를 받고, Promise 객체를 반환한다.

  • URL: 통신 요청할 서버 주소
  • options: 객체를 넘기면서 HTTP방식(method), HTTP요청 헤더(headers), HTTP요청 전문(body)등을 설정해줄 수 있다.

반환된 객체는 API 호출이 성공했을 경우 응답(response) 객체를 resolve하고, 실패했을 경우에는 예외(error) 객체를 reject한다.
응답(Response)객체로부터는 HTTP응답 상태(status), HTTP응답 헤더(headers), HTTP응답 전문(body) 등을 읽어올 수 있다.

Fetch API 인터페이스 + 메소드

Headers

  • 클라이언트-서버 간에 HTTP 요청과 응답 header에 다양한 액션을 할 수 있도록 돕는다.
  • let myHeaders = new Headers();와 같이 new Headers()(생성자 함수) 생성자를 사용해서 헤더 객체를 생성할 수 있다.
  • key-value로 이루어진 multi-map구조이다.
  • append(), delete(), entries(), forEach(), get()... 등의 메소드를 사용해서 header에 여러가지 속성을 추가 / 제거 / 조회 등을 할 수 있다.
// 1. set(), append() 메소드를 사용하여 property를 추가
let myHeaders = new Headers();
myHeaders.append("Content-Length", "Hello World".length.toString());
myHeaders.set("Content-Type", "text/plain"); //기존의 동일한 Property가 존재해도, 덮어쓸 수 있다.

// 2. 생성자에 인자로 전달
myHeaders = new Headers({
  "Content-Type" : "text/plain",
  "Content-Length" : "Hello World".length.toString()
})

// 3. has(), get(), getAll() 메소드로 value 확인하기
myHeaders.has("Content-Type"); // true
myHedaers.has("Set-Cookie"); // false
myHeaders.get("Content-Length"); // 11
myHeaders.append("X-Custom-Header", "AnotherValue");
myHeaders.getAll("X-Custom-Header") // ["ProcessThisImmediately", "AnotherValue"]

//4. delete()로 삭제
myHeaders.delete("X-Custom-Header");

Body

  • Request, Response 의 body를 나타내는 객체이며, Content-Type과 그것이 어떻게 처리되어야 할 지를 정의할 수 있도록 하는 인터페이스

  • body는 아래에 기술한 타입들 중 하나의 인스턴스이다.

    • ArrayBuffer
    • ArrayBufferView
    • Blob/File
    • String
    • URLSearchParams
    • FormData
let form = new FormData(document.getElementByID('login-form'));

fetch('/login', {
  method:'POST',
  body: form
}

Requests

  • 요청에 대한 리소스(데이터 정보)를 담고 있는 객체
  • fetch()에 직접 URL, options 입력하는 것을 대체해준다.
//Request(URL, [option])
//URL : 서버 주소
//option : method, headers, body... etc fetch의 두 번째 인자를 대체

const req = new Request("/api/posts", {
  method: "GET",
  headers: new Headers({ //Headers 인터페이스 사용 or 직접 객체입력
	  "content-type": "application/json",
  }),
  body: { 
      //Body 인터페이스로 대체 가능
	  name: "LeeHanur",
  }
});

fetch(req)
.then(res => console.log(res))
.catch(err => console.log(err);

Response

  • fetch()에서는 resolve 됐을 때 response 인스턴스를 반환한다. (request에 대한 response 정보를 담고 있는 객체이다.)
  • 생성자 함수(new Response())로 객체 생성이 가능하지만, 굳이 생성하지 않는다.
  • 보통 fetch한 이후 .then()에서 .then((response) => {let data=response.json()}) 과 같은 코드를 통해 응답 데이터를 json형태로 변환하는데, 이게 response가 아닐까 싶다.
// Response 상수
Response.status // HTTP status의 정수치, 기본값 200
Response.statusText // HTTP status 코드의 메서드와 일치하는 문자열, 기본값 "OK"
Response.ok // HTTP status 코드가 200 ~ 299 값 인지에 대하여 Boolean으로 반환한다.

var myResponse = new Response(body, [init]);
// body: null 허용, Blob|BurfferSourse ... etc 응답된 body 의 typedmf wjddml
// init: status, statusText, headers 3가지 property 설정 가능

var myBlob = new Blob();
var init = {"status": 200, "statusText": "SuperSmashingGreat!"}

var myResponse = new Response(myBlob, init);

fetch()

  • fetch()메소드는 리소스(데이터)에 대한 요청(request)을 보내고, 응답(response)을 받으면 이를 fullfilled(성공)된 상태의 Promise에 담아 다시 return 시키는 역할을 한다.

  • fetch()메소드가 리턴하는 Promise는 HTTP에러(예: 404에러)에 대해서는 reject되지 않으며, 오직 네트워크 요청 실패에 대해서만 reject된다. HTTP 에러에 대해서는 ok상태가 false인 resolve가 반환된다.

  • HTTP 에러를 확인하려면 .then()을 이용해서 확인한다 .then(response => if(response.status === '404'){//...}

  • fetch()의 첫번째 인자로는 요청할 대상 resource를 반드시 전달해줘야 한다. 이 resource는 URL과 같은 주소도 가능하고, 따로 생성한 Request 객체를 전달하는 것도 가능하다.

GET 호출

원격 API에 있는 데이터(리소스)를 가져올 때 쓰이는 GET 방식의 HTTP 통신으로, 단순히 특정 API에 저장된 데이터를 보여주는 웹페이지나 애플리케이션에서는 GET 방식의 HTTP 통신으로 충분하다.
fetch(url, [options]에서 options에 아무것도 넘기지 않으면, 요청은 GET메서드로 진행되어 url로부터 콘텐츠(데이터)가 다운로드 된다.

대부분의 REST API들은 JSON 형태의 데이터를 응답하기 때문에, 응답(response)객체는 json() 메서드를 제공한다.

fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(response => response.json())
  .then(json => console.log(json))

<!--
{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit↵suscipit recusandae consequuntur …strum rerum est autem sunt rem eveniet architecto"
}
-->

POST 호출

원격 API에서 관리하고 있는 데이터를 생성해야 한다면 POST 방식의 HTTP 통신이 필요하다.

method옵션을 POST로 지정해주고, headers 옵션을 통해 JSON 포멧을 사용한다고 알려줘야 하며, request 전문을 JSON 포멧으로 직렬화하여 가장 중요한 body 옵션에 설정해준다.

  • method: HTTP 메서드(GET, POST, PUT, DELETE...)
  • body: 요청 본문으로 다음 항목 중 하나여야 한다.
    • 문자열 (예: JSON 문자열)
    • FormData객체 - form/multipart형태로 데이터를 전송하기 위해 쓰인다.
    • Blob / BufferSource - 바이너리 데이터 전송을 위해 쓰인다.
    • URLSearchParams

대부분은 JSON을 요청 본문에 실어서 보낸다.

let user = {
  name: 'oh',
  subNamd: 'Minyoung'
}

fetch('/article/fetch/post/user', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  },
  body: JSON.stringfy(user)
}).then((response) => console.log(response))

// Response {type: "cors", url: "https://jsonplaceholder.typicode.com/posts", redirected: false, status: 201, ok: true, …}

// json() 메서드 호출시, 응답 전문을 객체 형태로 얻을 수 있다.
fetch("https://jsonplaceholder.typicode.com/posts", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "Test",
    body: "I am testing!",
    userId: 1,
  }),
})
  .then((response) => response.json())
  .then((data) => console.log(data));

// {title: "Test", body: "I am testing!", userId: 1, id: 101}

PUT, DELETE 호출

GET과 POST 만큼은 아니지만, 원격 API에서 관리하는 데이터의 수정과 삭제를 위해서 PUT과 DELETE 방식의 HTTP 호출을 사용할 때가 있다.

PUT방식은 method 옵션만 PUT 으로 설정한다는 점 빼놓고는 POST 방식과 매우 흡사하다.

DELETE방식은 보낼 데이터가 없고, 삭제만 하기 때문에 headersbody 옵션이 필요가 없다.

fetch("https://jsonplaceholder.typicode.com/posts/1", {
  method: "DELETE",
})
  .then((response) => response.json())
  .then((data) => console.log(data));

//{}

Reference

참고
참고
참고
참고
참고

profile
이것저것 정리하는 공간

0개의 댓글