📝

Fetch & Axios

1. Fetch 시작하기1.1 Fetch 등장 배경1.2 Fetch 사용 이유2. Fetch 문법2.1 Response 프로퍼티와 메서드2.1.1 Response 프로퍼티와 메서드를 설명하기 앞선 간략한 promise 설명 예제2.1.2 Response 프로퍼티와 메서드를 설명하기 앞선 간략한 then 함수 설명 예제2.1.3 Response property에 대한 설명과 예제2.1.4 Response method란?[2]2.2 fetch() 메서드2.2.1 fetch()의 기본적인 사용방법2.2.2 Request() 생성자2.2.3 fetch()의 options 3. Fetch 사용해보기❗실습 전 참고사항실습용 API 사이트 이용 방법브라우저 콘솔창으로 성공 확인 방법실습시 사용할 fetch()의 기본 구조3.1 GET 요청3.1.1 GET이란?3.1.2 사용방법3.1.3 실습 예제3.2 POST 요청3.2.1 POST란?3.2.2 사용 방법3.2.3 실습 예제3.3 PUT 요청3.3.1 PUT이란?3.3.2 PUT의 사용 방법3.3.3 실습 예제3.4 PATCH 요청3.4.1 PATCH란?3.4.2 사용방법3.4.3 실습 예제3.5 DELETE 요청3.5.1 DELETE란?3.5.2 사용방법3.5.3 예제4. Fetch를 통한 API를 불러오는 방법4.1 API란 무엇일까?4.2 API 호출하기4.3 GET, POST 사용해보기5. Fetch 성공 여부 확인 및 에러처리5.1 Fetch 성공 여부 확인5.2 에러 처리6. 요청객체를 생성하고 전송하기6.1. Request() 생성자로 생성한 요청 객체를 인자로 전달6.1.1 Request() 생성자6.1.2 왜 써야할까?7. Axios 시작하기7.1 Axios 사용 이유7.1.1 Axios 정의7.1.2 Axios 사용 이유7.2 Axios와 Fetch의 차이7.2.1 Axios와 Fetch에 대해서7.2.2 Axios와 Fetch의 기능 차이JSON 데이터 변환자동 문자열 반환7.2.3 Request 취소 및 Timeout 설정7.2.4 브라우저 지원7.2.5 Axios와 Fetch 중 어떤 것을 써야 할까7.3 Axios 시작하기7.3.1 Node.js 개발 환경에서 설치/사용7.3.2 브라우저 환경에서 설치/사용8. Axios 문법8.1 Axios API8.1.1 요청 config 옵션들 8.1.2 Config 전역 기본값 설정8.2 Axios 응답 스키마8.2.1 요청했을 때 응답 스키마 종류 및 예제 [1]9. Axios 사용해보기9.1 GET 요청9.1.1 Axios의 GET이란?9.1.2 사용 방법9.1.3 실습 예제9.2 POST 요청9.2.1 Axios의 POST란?9.2.2 사용 방법9.2.3 실습 예제9.3 PUT 요청9.3.1 Axios의 PUT이란?9.3.2 사용방법9.3.3 실습 예제9.4 PATCH 요청9.4.1 Axios의 PATCH란?9.4.2 사용방법9.4.3 예제9.5 DELETE 요청9.5.1 Axios의 DELETE란?9.5.2 사용방법9.5.3 실습 예제10. Axios 성공 여부 확인하기, 에러 처리10.1 Axios 성공 여부 확인하기10.2 에러 처리11. 참고자료
 

1. Fetch 시작하기

1.1 Fetch 등장 배경

Fetch 사용 이유에 대해 알기 위해서는 비동기통신의 역사에 대해 간략하게 알고 넘어갈 필요가 있다. Fetch가 나오기 전까지는 JS에서 Ajax를 사용하기는 굉장히 번거로웠다. XMLHttpRequest API(이하 XHR)를 사용하여 XML 데이터를 주고받았는데 코드가 복잡해 가독성도 떨어지고 서버의 동작을 파악하기 힘들었다. 이러한 불편함을 해소하기 위해 Fetch API가 ES6부터 등장하며 XHR를 사용하던 방식보다 직관적이며 가독성이 더욱 좋아지게 되었다.

1.2 Fetch 사용 이유

Fetch는 네트워크 통신을 포함한 리소스를 가지고 오기 위한 인터페이스를 제공해 주는 API이다. XHR과 기능은 같지만 확장 가능하며 효과적으로 구성되어 있고,[1] 내장기능이라 라이브러리 업데이트에 따른 에러를 걱정하지 않아도 된다.

2. Fetch 문법

2.1 Response 프로퍼티와 메서드

2.1.1 Response 프로퍼티와 메서드를 설명하기 앞선 간략한 promise 설명 예제

let promise = fetch('연습 url') console.log(promise)
notion imagenotion image
Promise는 앞에서 살펴 봤듯이 fetch를 사용했을 때 실행 결과에 대한 상태를 반환해 주는 약속된 객체이다. Promise에는 3가지 상태 pending, fulfilled, reject가 존재한다. pending은 진행 중, fullfilled는 완료, rejected는 실패를 의미한다. 위 console 창을 확인해 보면 PromiseState의 상태는 fullfilled, fetch를 해오는 것에 성공한 것을 확인할 수 있다.
 

2.1.2 Response 프로퍼티와 메서드를 설명하기 앞선 간략한 then 함수 설명 예제

let promise = fetch("연습 URL").then(function (response) { console.log(response); });
notion imagenotion image
자바스크립트는 then() 메서드를 제공한다. then() 메서드 안에 ‘연습 URL’의 응답값을 담을 수 있는 콜백 함수를 만들어 놓고 정상적으로 응답이 들어왔을 경우 응답값을 처리할 수 있다.

2.1.3 Response property에 대한 설명과 예제

Response는 자바스크립트의 객체이다. Response는 성공과 실패에 대한 중요한 정보를 담고 있다. 본격적으로 Response의 프로퍼티를 알아보자.
  • Response.body - 읽을 수 있는 스트림의 내용을 의미한다.
  • Response.bodyUsed - Response.body 내용을 읽었는지를 확인하는 boolean 값이다. 2.1.2 예제에서는 연습의 body 내용을 읽지 못했지만 2.1.3 예제에서는 blob()이라는 메서드를 사용해 true의 값이 반환되는 것을 볼 수 있다. blob() 메서드는 스트림을 가져와 완료할 때까지 읽어 반환하는 메서드이다.
let promise = fetch("연습 url").then(function (response) { console.log(response); response.blob(); });
notion imagenotion image
  • Response.header - Response와 연결된 headers의 객체이다.
  • Response.ok - 응답이 성공했는지 범위의 상태 여부를 나타내는 boolean 값이다. HTTP 상태 코드가 200~299 사이일 경우 true를 나타내고 응답이 실패했을 경우 false를 나타낸다.
  • Response.redirect - 응답이 새 URL로 리디렉션하고 새 URL을 지정하였는지 상태 여부를 나타내는 boolean 값이다.
  • Response.status - HTTP 상태 코드를 의미한다. 값은 짧은 숫자로 설정되어 있다. 범위는 아래와 같이 되어 있지만 자세한 것은 [1]MDN 공식 문서와 HTTP파트의 응답 부분을 참고하길 바란다.
    • 1) Informational responses (100-199)
      2) Successful responses (200-299)
      3) Redirection messages (300-399)
      4) Client error responses (400-499)
      5) Server error responses (500-599)
  • Response.StatusText - 상태 코드에 해당하는 메세지를 의미한다.
  • Response.Type - 응답 Type을 의미한다. 예로 basic과 col, opaque가 있다. 이것은 리소스의 출처를 나타내며 응답 객체를 처리하는 방법을 알려주는 것에 사용할 수 있다.
  • Response.url - 응답 url이다.
 

2.1.4 Response method란?[2]

💡
Response의 반환 method는 한번만 사용이 가능하다. 예로 response.text()를 사용해 본문을 읽고 텍스트로 반환했다면 모든 데이터들은 처리된 상태가 된다. 따라서 추후에 또 다른 Response 반환 method를 사용해서 본문을 반환하지 못한다.
  • Response.json() - 응답된 본문의 텍스트를 JSON 형식으로 파싱한다.
  • Response.text() - 응답된 본문을 읽고 텍스트 형식으로 반환한다.
  • Response.redirect(url, status) - URL로 redirection하는 결과를 반환한다. url은 새 응답이 시작되는 URL이다. 괄호 속에 들어가는 status는 응답에 대한 코드이다.
  • Response.formData() - 응답된 것을 formData 형식으로 반환한다.
  • Response.blob() - 스트림을 가져와 완료할 때까지 읽어 반환하는 메서드이다.
  • Response.arrayBuffer() - 응답된 것을 arrayBuffer 형식으로 반환한다.
  • Response.clone() - 다른 변수에 저장되는 응답 객체의 복제본을 만든다.
  • Response.error() - 네트워크 오류와 관련된 응답의 새로운 객체를 반환한다.
 
 

2.2 fetch() 메서드

2.2.1 fetch()의 기본적인 사용방법

Fetch API 를 이용해 리소스를 얻어오기 위해서 fetch()를 이용하는데 fetch()의 첫 번째 인자는 필수 매개변수이다. 이곳에는 두 가지가 형태가 올 수 있는데 첫 번째 형태는 가져오려는 리소스의 URL을 나타내는 문자열 또는 객체이고 두 번째 형태는 Request() 생성자로 생성된 객체가 올 수 있다.
💡
resource 와 fetch 의미 resource : 요청에 따라 반환되는 식별가능한 데이터(문서, 사진 등등)를 의미한다. fetch : 사전적 의미는 ‘다른곳으로 가서 물건이나 누군가를 데러오는 것’ 이다. 여기서는 resource 를 가져온다고 할 수 있다.
기본적인 사용 문법과 예시는 아래와 같다.
fetch(url) fetch(new Request() 로 생성된 request 객체) fetch(url, [options])
fetch("https://jsonplaceholder.typicode.com/posts/1");
첫번째 인자에 url 만 입력
const request = new Request("https://jsonplaceholder.typicode.com/post/1"); fetch(request)
첫번째 인자에 Request로 생성된 객체 사용
fetch("https://jsonplaceholder.typicode.com/posts",{ method: "POST", headers: "Content-Type": "application/json", body: { title: "foo", body: "bar", userId: 1 } });
url 과 options 같이 사용

2.2.2 Request() 생성자

우리가 fetch() 호출할때 리소스 경로를 제공하는 대신에 Request() 생성자로 생성한 요청 객체를 통해 인자로 전달하여 사용할 수 있다. 그렇다면 Request() 생성자란 무엇일까?Request()생성자는 새로운 Request 객체를 생성할 수 있다. fetch() 메서드의 매개변수와 동일하게 첫번 째 인자 값 input에는 접근하고자 하는 URL 을 담고, 두 번째 인자 값 init에는 method나 header, body 등의 옵션을 지정할 수 있다.
const myRequest = new Request(input, init);
예시
const myRequest = new Request("https://jsonplaceholder.typicode.com/posts/1", { headers: { "Content-Type": "application/json", }, }); fetch(myRequest) .then(res => res.json()) .then(data => console.log(data));
 
기존에 존재하는 요청 객체를 전달해서 복사본을 생성하는 것이 가능하다. 이렇게 복사본 생성을 해두면 다시 기존에 생성해둔 요청과 응답 객체를 다시 사용할 수 있다. 또한 다시 사용하되, init 옵션만 따로 교체할 수도 있다. 하지만 이미 본문을 읽은 요청 또는 응답을 복사할 수 없다. 즉 복사본은 원본 본문을 읽기전에 생성해야 한다.
const copyRequest = new Request(myRequest);
💡
참고로, 오직 복사본 생성을 위한 clone() 메서드도 존재한다. 현재 Request 객체의 복사본을 만드는 clone 메서드 또한 마찬가지로 요청 본문이 이미 사용된 경우 TypeError를 발생시킨다. 앞서 배운 Request 생성자와 동일하게 복사본을 생성할 수 있지만 clone메서드의 주된 목적은 body의 object의 다중 사용을 위함이고, 요청을 수정하려는 경우에는 Request 생성자를 더 선호한다.

2.2.3 fetch()의 options

두 번째 인자 options선택 매개변수로 method나 body 등 요청을 커스텀 할 수 있는 Request 생성자의 인스턴스 초기화에 사용된다. fetch()의 두 번째 인자로 options 객체를 줬는데 Request 생성자가 나오는 이유는 WHATWG 문서의 fetch() 부분을 살펴보면 fetch() 메서드가 다음과 같은 형태로 되어있기 때문이다.
fetch(RequestInfo input, optional RequestInit init = {})
출처 [2.2.3] : https://fetch.spec.whatwg.org/#fetch-method
 
notion imagenotion image
 
fetch()를 호출하면 내부적으로 Request 생성자를 호출해서 input, [init]에 입력한 인자를 던져주고 request객체를 생성한다. 이때 두 번째 인자가 없으면 기본값으로 초기화된다. fetch()첫 번째 인자만 주어졌을 때 요청이 GET으로 전달되는 것도 requestmethod속성 기본값이 GET이기 때문이다.
두번 째 인자로 설정가능 한 옵션들은 다음과 같다. 먼저 Request 생성자url만 집어넣고 로그를 확인해보면 옵션들의 기본값이 들어간 것을 확인할 수 있다.
req = new Request("https://jsonplaceholder.typicode.com/posts");
notion imagenotion image
옵션들의 자세한 내용은 출처[2.2.3] 에서 확인할 수 있다.
method HTTP요청 메서드[1.3. HTTP요청 메서드 챕터 참고] 와 동일하다. 소문자로 작성해도 자동으로 대문자로 변환된다. 기본값은 GET이다.
headers new Header(init)생성자로 객체를 만들어서 넣을 수도 있고 객체 리터럴을 그대로 넣어서 설정 할 수도 있다. 아래와 같이 사용 한다.
let headers = new Headers({ "Content-Type": "text/xml" }); // 객체 리터럴을 생성자에 전달해서 생성할 수 있다 headers.append["Content-Type","application/json"] // 메소드들을 이용해 추가, 제거, 조회 등이 가능하다 fetch("https://jsonplaceholder.typicode.com/posts",{headers}); // url과 options 에 생성한 headers 객체를 넣어서 fetch 요청
notion imagenotion image
개발자도구 → 네트워크 탭에서 요청 헤더를 찾아보면 설정한 부분이 들어간 것을 확인할 수 있다. 만든 객체를 append(), delete(), get(), has(), set(), for() 같은 메소드들을 사용해 속성들을 추가, 삭제, 조회할 수 있다.
body : 요청에 추가할 본문 형식 Blob, Array Buffer, TypeArray, DataView, FormData URLsearchParams 문자열 개체, 리터럴, ReadableStream 이 될 수 있다. 요청 헤더의 Content-Type 과 같아야 한다. GET 요청에서는 사용할 수 없고 기본값은 undefined 이다.
mode : 어떤 CORS 정책을 사용할지 설정한다
  • cors[기본값] : 제삼자가 제공하는 다양한 API를 사용하는데 제한이 없어진다.
  • same-origin : 현재 Origin과 같은 Origin에만 요청할 수 있다.
  • no-cors : 메소드가 HEAD GET 또는 POST가 아닌 다른 것이 되는 것을 방지하고 Accept, Accept-Language, Content-Type 값으로 application/x-www-form-urlencoded multpart/formdata, text/plain의 지정된 헤더만 사용할 수 있다.
credentials
  • omit : 자격 증명을 전송하지 않도록 한다.
  • same-origin[기본값] : 요청 URL이 같은 출처일 때만 자격 증명을 전송한다.
  • include : fetch 메서드에 자격증명 정보를 함께 전송한다. (서버에서도 응답에서 처리를 해줘야 한다) 자격 증명이 함께 전송되는 요청을 보낼 땐 Access-Control-Allow-Origin : * 을 지정하지 못한다.
cache : 기본값은 default 으로 표준 HTTP-cache 정책과 헤더들을 사용한다. 다른 설정으로 no-store, reload, no-cache, force-cache, or only-if-cached 의 옵션들이 있다.
redirect : 리다이렉트 응답을 어떻게 처리할지 설정한다.
  • follow[기본값] : 리다이렉트 응답을 허용한다.
  • error : 리다이렉트 응답을 에러로 처리한다.
  • manual : 리다이렉트를 허용하지 않는다.
referrer : 자동으로 네트워크 요청을 처음 시작한 페이지의 정보를 담고 있다.
referrerPolicy :요청에 적용 할 레퍼러 정책을 설정한다. no-referrer[기본값], *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url의 옵션이 있다.
integrity : 응답이 미리알려진 체크섬과 일치하는지 확인할 수 있는 설정이다.
keepalive : 기본값은 false로 요청이 페이지를 나와서도 유지할 수 있게 해주는 설정이다.
signal : fetch 요청을 AbortController 을 사용해 중단시킬 수 있는 AbortSignal 객체이다.
💡
AbortController 은 하나 이상의 웹 요청을 취소할 수 있게 해주는 인터페이스 이다. AbortSignal 객체는 AbortController() 생성자로 생성한 DOM 요청과 통신하거나 취소하는데 사용되는 객체 인터페이스이다.

3. Fetch 사용해보기

실습 전 참고사항

실습용 API 사이트 이용 방법

우리는 실습을 위해 {JSON} Placeholder(https://jsonplaceholder.typicode.com/)를 이용할 것이다. {JSON} Placeholder는 무료로 가상데이터를 이용할 수 있는 API 제공 사이트이다.
 
앞으로 Fetch 실습에 사용할 API 주소는 다음과 같다.
 
위 주소를 들어가 보면 다음과 같은 데이터를 볼 수 있다.
{ userId: 1, id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit suscipit recusandae consequuntur expedita et cum reprehenderit molestiae ut ut quas totam nostrum rerum est autem sunt rem eveniet architecto", }
 
우리는 앞으로 이 가상 데이터에 Fetch를 이용하여 GET, POST, PUT, PATCH, DELETE 요청을 각각 해주었을때 데이터가 어떻게 변화하는지 실습을 할 것이다.
하지만 위 사이트는 API 실습용 사이트이기 때문에 HTTP 메소드를 통해 내부 데이터에 CRUD를 하려고 해도 실제로 데이터에 아무런 변화가 없다. 따라서 실습 후 해당 API주소를 들어가 데이터가 변경되지 않았다고 당황하지 않길 바란다. 대신 우리는 브라우저의 콘솔창으로 데이터를 확인할 것이다.
 

브라우저 콘솔창으로 성공 확인 방법

Fetch 실습 성공은 브라우저 콘솔에서 확인할 수 있다. 아래 이미지와 같은 내용이 출력된다면 성공적으로 통신에 성공했다고 할 수 있다.
 
notion imagenotion image
 

실습시 사용할 fetch()의 기본 구조

앞서 살펴보았듯이 Fetch API 를 이용해 리소스를 얻어오기 위해서 fetch() 를 이용한다. 우리는 실습을 할 때 resource 와 options를 입력하는 아래와 같은 구조로 사용할 것이다.
fetch("https://jsonplaceholder.typicode.com/posts",{ method: "POST", headers: "Content-Type": "application/json", body: { title: "foo", body: "bar", userId: 1 } });
 
Fetch를 사용하여 method, headers, body로 이루어진 요청 객체에 담아서 보낸다. 단, POST 요청에서는 body를 필수로 넣어줘야 한다.
{ method: "GET/POST/PUT/PATCH/DELETE 중 택일", // 사용하고자 하는 메서드의 이름을 명시 headers:, // 서버에 전송할 데이터에 대한 정보를 작성 body:, // 서버에 전송할 데이터를 작성 }
method에는 메서드의 이름을 명시해주어야 한다.
headers 안에는 서버에 전송할 데이터의 양식을 Content-Type 으로 명시해주어야 한다. 인증이 필요한 경우 Authentification 에 토큰을 적어주기도 한다.
body에는 서버에 전송할 데이터를 적어준다. 순수 텍스트로 전송하기도 하지만, <form> 등의 HTML 양식이나 JSON 양식으로 전송하기도 한다.

3.1 GET 요청

 

3.1.1 GET이란?

GET 요청은 특정한 리소스를 가져오도록 요청한다. 데이터를 가져올 때만 사용해야 하며, data를 body 에 담지 않고 URL에서 데이터를 포함시켜 요청한다. 따라서 보안에 취약하기 때문에 민감한 정보는 담지 않아야한다.
 

3.1.2 사용방법

fetch함수에서 method를 입력하지 않으면 기본값은 GET 이다.
fetch(API_url, {method: "GET"})
 

3.1.3 실습 예제

https://jsonplaceholder.typicode.com/에서 posts의 1번 게시물을 가져와 보겠다. 먼저 fetch 를 이용해 결과값을 콘솔에 찍어보자.
 
예제1. 요청 파라미터를 사용한 Fetch
function getData(url = "") { fetch(url, { method: "GET", headers: { "Content-Type": "application/json", }, }) .then((res) => res.json()) .then((res) => console.log(res)) .catch((error) => console.log(error.message)); } getData("https://jsonplaceholder.typicode.com/posts/1");
 
예제2. async/await을 사용한 Fetch
async function getData(url = ""){ try{ const response = await fetch(url); const res = await response.json(); console.log(res); } catch(error){ console.log(error); } } getData("https://jsonplaceholder.typicode.com/posts/1");
 
예제3. async/await으로 만든 함수를 호출 후 then으로 결과 출력한 Fetch
async function getData(url = "") { try { const response = await fetch(url, { method: "GET", headers: { "Content-Type": "application/json", }, }); return response.json(); } catch (error) { console.log(error.message); } } getData("https://jsonplaceholder.typicode.com/posts/1", { }).then((data) => { console.log(data); });
위 예제들의 결과는 다음과 같다.
notion imagenotion image
이렇게 posts의 1번게시물의 data가 잘 불러와진 것을 알 수 있다.
 

3.2 POST 요청

3.2.1 POST란?

POST는 서버로 데이터를 전송하는 HTTP 메서드이다.[1] 주로 서버에 데이터를 생성할 때 사용한다.
GET 메서드로도 서버에 데이터를 전송할 수 있지만, POST 메서드는 대용량의 데이터도 전송할 수 있고 전송할 데이터의 내용이 URL에 나타나지 않기 때문에 데이터의 전송에는 POST가 훨씬 적합하다.
 

3.2.2 사용 방법

POST 요청에서는 서버에 생성할 데이터를 body에 담아주어야 한다.
fetch(API_url, {method: "POST", body: 데이터})
 

3.2.3 실습 예제

POST를 이용하여 아래와 같은 데이터를 https://jsonplaceholder.typicode.com/posts 에 생성하는 실습을 해 보자.
{ title: "Post test", body: "fetch의 Post 메소드를 테스트 중입니다.", userId: 2, }
 
예제1. 요청 파라미터를 사용한 Fetch
function postData(url = "", data = {}) { fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }) .then((res) => res.json()) .then((res) => console.log(res)) .catch((error)=>console.log(error.message)); } postData("https://jsonplaceholder.typicode.com/posts", { title: "Post test", body: "fetch의 Post 메소드를 테스트 중입니다.", userId: 2, });
 
예제2. async/await을 사용한 Fetch
async function postData(url = "", data = {}) { try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); const res = await response.json(); console.log(res); } catch (error) { console.log(error.message); } } postData("https://jsonplaceholder.typicode.com/posts", { title: "Post test", body: "fetch의 Post 메소드를 테스트 중입니다.", userId: 2, })
 
예제3. async/await으로 만든 함수를 호출 후 then으로 결과 출력한 Fetch
async function postData(url = "", data = {}) { try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); return response.json(); } catch (error) { console.log(error.message); } } postData("https://jsonplaceholder.typicode.com/posts", { title: "Post test", body: "fetch의 Post 메소드를 테스트 중입니다.", userId: 2, }).then((data) => { console.log(data); });
함수를 실행하고 결과를 확인해 보자. 콘솔에 아래와 같이 출력된다면 성공이다.
notion imagenotion image
 

3.3 PUT 요청

3.3.1 PUT이란?

PUT은 새로운 데이터를 생성하는 POST와 달리 기존에 있는 데이터를 수정(Update)하고싶을 때 사용한다. PUT을 실행하면 이후 POST가 실행하는 형태로 POST와 PUT은 생김새가 아주 비슷하다. PUT과 POST의 차이점을 알아보자.

3.3.2 PUT의 사용 방법

PUT을 간단하게 사용할 때는 method, headers, body로 구성한다. 각각 method‘PUT’으로, json 형식을 사용하면 headers'Content-Type': 'application/json'으로, body에는 JSON.stringify(전송할데이터)를 작성한다. 여기서 주의할 것은 headers 에 설정한 타입과 body 의 타입이 같아야 한다는 점이다. 주로 사용하는 메소드는 다음과 같다.
{ method: "PUT", // “PUT”라고 메서드의 이름을 명시 headers:, // 서버에 전송할 데이터의 양식을 "Content-Type"으로 명시 body:, // 서버에 전송할 데이터를 작성 }
 
POST와 PUT의 비교
PUT의 예제는 앞서 소개한 POST와 PUT을 비교하여 알아보겠다. 서버 주소method에 주목하자.
async function postData(url = "", data = {}) { try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); return response.json(); } catch (error) { console.log(error.message); } } postData("https://jsonplaceholder.typicode.com/posts", { title: "Post test", body: "fetch의 Post 메소드를 테스트 중입니다.", userId: 2, }).then((data) => { console.log(data); });
POST 방식
전송한 데이터가 잘 출력되는 모습을 다음과 같이 확인할 수 있다.
notion imagenotion image
 
다음은 PUT 방식으로 작성한 코드이다.
async function putData(url = "", data = {}) { try { const response = await fetch(url, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); return response.json(); } catch (error) { console.log(error.message); } } putData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, title: "Put test", body: "fetch의 Put 메소드를 테스트 중입니다.", userId: 1, }).then((data) => { console.log(data); });
PUT 방식
PUT에서도 다음과 같이 전송한 데이터를 확인할 수 있다.
notion imagenotion image
 
위의 두 예제를 비교하면 method와 서버주소가 다르다는 사실을 확인 할 수 있다. POST의 서버 주소는 "https://jsonplaceholder.typicode.com/posts" 이고 PUT의 서버 주소는 "https://jsonplaceholder.typicode.com/posts/1" 이다. 두 주소의 차이점은 /posts 뒤에 /1 의 유무이다. 만약 PUT에 POST의 서버 주소를 작성한다면 어떤 결과가 나타날까? PUT 메소드에 POST와 같은 주소를 넣으면 아래와 같은 에러가 발생한다.
notion imagenotion image
404 에러 코드는 서버를 찾았으나 해당 서버 내에 필요한 파일을 찾지 못했을 때 발생하는 오류코드이다.
이것이 의미하는 바를 한번 생각해보자. POST의 경우에는 요청 할 때 마다 새로운 데이터를 생성하여 특정 파일을 찾지 않아도 되는 반면 PUT은 기존의 데이터를 수정해야 하기 때문에 특정 파일을 지정해주어야 동작할 수 있다. 그래서 에러가 발생했고, POST뒤에 게시물의 id 값인 /1을 지정해야 하는 이유이다.

3.3.3 실습 예제

다음은 PUT의 다양한 작성방법이다. 출력 결과는 앞에 설명했던 예시와 같다.
 
예제1. 요청 파라미터를 사용한 Fetch
function putData(url = "", data = {}) { fetch(url, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }) .then((res) => res.json()) .then((res) => console.log(res)) .catch((error)=>console.log(error.message)); } putData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, title: "Put test", data: "fetch의 Put 메소드를 테스트 중입니다.", userId: 1, });
예제2. async/await을 사용한 Fetch
async function putData(url = "", data = {}) { try { const response = await fetch(url, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); const res = await response.json(); console.log(res); } catch (error) { console.log(error.message); } } putData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, title: "Put test", data: "fetch의 Put 메소드를 테스트 중입니다.", userId: 1, });
예제3. async/await으로 만든 함수를 호출 후 then으로 결과 출력한 Fetch
async function putData(url = "", data = {}) { try { const response = await fetch(url, { method: 'PUT', headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); return response.json(); } catch (error) { console.log(error.message); } } putData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, title: "Put test", body: "fetch의 Put 메소드를 테스트 중입니다.", userId: 1, }).then((data) => { console.log(data); });
 
위 3가지 예제의 결과는 다음과 같다.
notion imagenotion image
 

3.4 PATCH 요청

3.4.1 PATCH란?

PATCH란 위에 상술한 것과 같이 데이터를 부분 변경 해주는 HTTP 메소드이다. PUT도 데이터를 변경해주는 HTTP 메소드이지만, 데이터를 전체 변경해주기 때문에 PATCH와는 변경하는 내용에 차이가 있다.
 

3.4.2 사용방법

사용 방법은 아래와 같이 작성하면 된다. 즉, fetch함수에서 method를 PATCH로 입력해주면 된다. 자세한 사용 방법은 아래 예제를 통해 살펴보자.
fetch(API_url,{method: "PATCH"})
 

3.4.3 실습 예제

 
예제1. 요청 파라미터를 사용한 Fetch
function patchData(url = "", data = {}) { fetch(url, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }) .then((res) => res.json()) .then((res) => console.log(res)) .catch((error)=>console.log(error.message)); } patchData("https://jsonplaceholder.typicode.com/posts/1", { title: "Patch test", });
fetch("https://jsonplaceholder.typicode.com/posts/1", { method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify({ title: "fetch_patch test", }), }) .then((response) => response.json()) .then((data) => console.log(data));
 
예제2. async/await을 사용한 Fetch
async function patchData(url = "", data = {}) { try { const response = await fetch(url, { method: "PATCH", headers: { "content-type": "application/json" }, body: JSON.stringify(data), }); const res = await response.json(); console.log(res); } catch (error) { console.log(error); } } patchData("https://jsonplaceholder.typicode.com/posts/1", { title: "Patch test", });
 
 
예제3. async/await으로만든 함수를 호출 후 then으로 결과 출력한 Fetch
async function patchData(url = "", data = {}) { try { const response = await fetch(url, { method: "PATCH", headers: { "Content-Type": "application/json", }, body: JSON.stringify(data), }); return response.json(); } catch (error) { console.log(error.message); } } patchData("https://jsonplaceholder.typicode.com/posts/1", { title: "Patch test", }).then((data) => { console.log(data); });
콘솔창의 결과를 통해 title에 대한 값이 "sunt aut facere repellat provident occaecati excepturi optio reprehenderit” 에서 "Patch test"로 변경(Update) 된 것을 확인할 수 있다.
notion imagenotion image
 

3.5 DELETE 요청

3.5.1 DELETE란?

DELETE는 지정한 리소스를 삭제할 때 사용한다. 서버에 저장할 데이터를 전달하지 않기 때문에 POST 및 PUT보다 비교적 간단하다.
 

3.5.2 사용방법

DELETE 요청을 만드는 것은 POST 및 PUT와 유사하며, Fetch 호출에서 두 번째 인수 위치에 있는 객체에 DELETE 를 지정한다.
fetch(API_url, {method:"DELETE"})
 

3.5.3 예제

실습에서 사용할 API 주소(https://jsonplaceholder.typicode.com/posts/1)를 들어가면 다음과 같은 데이터를 확인할 수 있다.
{ "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }
 
위의 데이터를 바탕으로 posts의 1번 게시물을 삭제하는 다양한 예제들을 살펴보자.
 
예제1. 요청 파라미터를 사용한 Fetch
function deleteData(url = "") { fetch(url, { method: "DELETE", headers: { "Content-Type": "application/json", }, }) .then((res) => res.json()) .then((res) => console.log(res)) .catch((error)=>console.log(error.message)); } deleteData("https://jsonplaceholder.typicode.com/posts/1");
 
예제2. async/await을 사용한 Fetch
async function deleteData(url = "") { try { const response = await fetch(url, { method: "DELETE", headers: { "Content-Type": "application/json", }, }); const res = await response.json(); console.log(res); } catch (error) { console.log(error.message); }} deleteData("https://jsonplaceholder.typicode.com/posts/1");
 
예제3. async/await으로 만든 함수를 호출 후 then으로 결과 출력한 Fetch
async function deleteData(url = "") { try { const response = await fetch(url, { method: "DELETE", headers: { "Content-Type": "application/json", } }); return response.json(); } catch (error) { console.log(error.message); } } deleteData("https://jsonplaceholder.typicode.com/posts/1") .then((data) => { console.log(data); });
 
DELETE 요청을 한 후 결과를 확인했을 때 콘솔에 아래의 내용이 출력된다면 성공이다.
notion imagenotion image

4. Fetch를 통한 API를 불러오는 방법

4.1 API란 무엇일까?

Wikipedia[1]에서는 다음과 같이 설명하고 있다. API란 응용 프로그램 프로그래밍 인터페이스(Application Programming Interface)이다. 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다. 주로 파일 제어, 창 제어, 화상 처리, 문자 제어 등을 위한 인터페이스를 제공한다. 이론적인 설명은 어려우니, 그림을 보며 쉽게 이해해 보자.
API 예시 시각화(1)API 예시 시각화(1)
API 예시 시각화(1)
위 그림처럼 손님은 음식을 먹기 위해선 4단계를 거쳐야 한다. 손님이 주문을 하면, 웨이터는 냉장고에서 음식을 찾는다. 음식을 찾으면가져오고, 나름의 조리를 통해 서빙한다. API 동작도 이와 매우 유사하다.
API 예시 시각화(2)API 예시 시각화(2)
API 예시 시각화(2)
위 그림을 통해 브라우저와 서버, 데이터베이스의 동작들을 하나씩 떼서 비교해 보자. 웹브라우저는 손님이 음식을 요청하는 것처럼 데이터를 요청한다. 그래서 웹브라우저를 Client 라고 부를 수 있다. 서버는 주문받은 음식(데이터)를 전달해 주는 역할을 한다. 그리고 데이터베이스는 음식들(데이터들)이 보관되어 있는 냉장고와 같다.
API 예시 시각화(3)API 예시 시각화(3)
API 예시 시각화(3)
최종적으로 위 그림에서 Query는 검색, 질의를 뜻한다. 여기서 responserequest를 잘 기억하자. 자, 그러면 관점을 나누어 생각해보자. 우선 Client 관점에서 생각하자.
API 요청 Client 관점 시각화API 요청 Client 관점 시각화
API 요청 Client 관점 시각화
Client 관점에서는 클라이언트와 서버단에서 그림 4.4의 Request(1)Response(4)에 대해서만 알면 된다. 이렇게 RequestResponse 즉, 데이터를 요청하고 전달받는 것을 API 호출이라고 한다. API 라는 것은 쉽게 말해서 웹브라우저와 서버 간의 사이처럼 프로그램과 프로그램 사이의 연결 다리이자 대화를 할 수 있는 방법으로 볼 수 있다. 예를 들면, “API를 호출한다” 라는 뜻은 “다른 프로그램에서 데이터를 받기 위해 말을 건다.” 라고 이해 할 수 있다.
그렇다면 결국, API를 호출하는 것은 다른 프로그램으로부터 데이터를 받기 위한 정확한 목적이 있다고 볼 수 있는데 이건 함수와 비슷하다고 생각할 수 있다. 함수 또한 호출을 통해 원하는 데이터를 반환받는다. 하지만 API 호출이 자바스크립트의 함수와 가지는 가장 큰 차이점은 응답(Response)를 언제 받을지 확실히 알 수 없다는 점이다.
API 호출은 항상 컴퓨터 내에서 일어나지 않는다. Client Server 컴퓨터가 다를 수 있고, 보통 다른 경우가 많다. 그리고 데이터를 요청했을 때, Server에서 데이터를 응답해 주는 시간은 인터넷의 속도, 서버의 부하 상태 등으로 예상할 수 없고 때로는 실패하기도 한다. 그래서 이전에 배운 ‘Promise’ 객체에 ‘Rejected’ 라는 상태가 존재한다. 그래서 언제 끝날지 모르는 이 상태들을 동기적으로 처리해선 안되는 이유가 성립된다. 그래서 API 호출을 Promise 객체를 이용해 비동기적으로 호출하게 된다.

4.2 API 호출하기

이제 특정 서버에 데이터를 요청하고 API 호출하는 실습을 진행해 보자. API를 아무렇게나 호출해선 안되고 인증된 상태의 서버에 호출을 해야 한다. {json}placeholder[2](API 연습용 서버, 조건 없이 더미 데이터를 제공해 주는 서비스 : OPEN API)를 이용해 실습해 보자.
{json}placeholder 웹사이트 내의 Resources 파트{json}placeholder 웹사이트 내의 Resources 파트
{json}placeholder 웹사이트 내의 Resources 파트
페이지 내에서 스크롤을 내리면 그림 4.5와 같이 “Resource” 파트가 보일 것이다. 여기서 “/posts”를 클릭하면 아래 그림과 같은 객체 형식을 지닌 json 데이터 리스트를 확인할 수 있다. response 즉, 응답값을 json 형태로 반환하고 있는 것을 확인할 수 있다. (json 데이터의 모습이 정렬되어있지 않은 경우, chrome extension “JSON View”를 다운받아 사용하면 그림 4.6과 같이 정렬된 데이터를 확인할 수 있다.)
"https://jsonplaceholder.typicode.com/posts" 접속 시 나타나는 json 데이터"https://jsonplaceholder.typicode.com/posts" 접속 시 나타나는 json 데이터
"https://jsonplaceholder.typicode.com/posts" 접속 시 나타나는 json 데이터
그렇다면, 이 json 파일을 불러와 보자.
"https://jsonplaceholder.typicode.com/posts"
URL 주소
API 를 호출하기 위해선 URL주소를 알아야 한다. URL주소는 위 코드 블럭과 같다. 위와 같은 주소로 말을 걸겠다라는 의미이다.
let response = fetch("https://jsonplaceholder.typicode.com/posts"); // response라는 변수는 다음과 같다 -> let response: Promise<Response>
‘response’라는 변수 생성
그럼 자바스크립트로 API 를 호출해보자. 위 코드와 같이, 응답을 response 라는 변수에 저장하겠다. fetch 라는 내장함수를 사용했다. fetchAPI를 호출할 수 있도록 도와주는 비동기 JavaScript 내장함수이다.
let response = fetch("https://jsonplaceholder.typicode.com/posts") .then((res) => console.log(res));
then을 사용하여 console에 res를 출력
Promise를 반환하는 함수는 비동기 처리를 하는 함수이다. 그리고, 이 함수의 처리결과는 then을 통해서 처리가 가능하다.
위 코드를 크롬 개발자 도구의 콘솔 창에 실행해 보자.
콘솔창에 예제 코드 4.3 를 입력했을 경우 나타나는 결과값콘솔창에 예제 코드 4.3 를 입력했을 경우 나타나는 결과값
콘솔창에 예제 코드 4.3 를 입력했을 경우 나타나는 결과값
위 콘솔 창과 같이 성공된 상태값인 “status:200”을 가져오는 것을 알 수 있다. 그런데, 정말 많은 데이터들을 불러오는 것을 확인할 수 있다. 그 이유는 fetch를 통해 데이터를 불러오게 되면, 데이터의 결과값을 반환하는 게 아니라 그 API의 객체 자체를 반환하기 때문에 Response라는 객체를 반환하게 된다. 우리가 편지를 보냈다고 예를 들어보자. 현재 fetch를 통해 불러온 것은 편지와 내용물을 감싼 편지 봉투라고 보면된다. 즉, 결과값의 포장지이다. 그렇다면, json 데이터 파일에서 원하는 데이터를 가져와보자.이번에는 async, await을 사용해보겠다.
async function getData() { let rawResponse = await fetch("https://jsonplaceholder.typicode.com/posts"); }
async, await을 사용해 getData 함수 생성
위 코드처럼 fetch를 이용해 getData 함수를 만들었다. 변수명이 “rawResponse”인 이유는 위 그림처럼 “Response”라는 rawData가 날아오기 때문이다. 그러면 json 데이터만 가져와보기로 하자.
async function getData() { let rawResponse = await fetch("https://jsonplaceholder.typicode.com/posts"); let jsonResponse = await rawResponse.json(); console.log(jsonResponse); } getData();
json() 메소드 사용
json 데이터만 가져오기 위해서는 fetch API에 내장된 메서드인 “json()”를 사용해 주어야 한다. 불러온 전체 데이터(”rawResponse”)에서 json()을 붙여준 것을 “jsonResponse”라는 변수에 담아 콘솔에 출력해 보자.
위 예제 코드를 실행한 결과의 콘솔 창위 예제 코드를 실행한 결과의 콘솔 창
위 예제 코드를 실행한 결과의 콘솔 창
결괏값은 위 콘솔 창과 같다. 배열에 100개의 데이터가 담겨 날아왔다. 그리고 하나씩 까보면 데이터가 정상적으로 잘 들어와있음을 확인할 수 있다. 이런 식으로 fetch를 통해 API를 호출하는 기본적인 방법에 대해 알아보았다.

4.3 GET, POST 사용해보기

이번에는 “get” 방식과 “post” 방식을 사용하면서 API를 이용해 데이터를 불러와보자. API는 위의 예시들과 같이 "{json} placeholder"라는 페이지를 이용하지만, 이번엔 “/posts” 가 아닌 “/todos” 데이터를 사용해 보자.
fetch("https://jsonplaceholder.typicode.com/todos/1") .then(response => response.json()) .then(data => console.log(data))
'https://jsonplaceholder.typicode.com/todos/1' 의 데이터를 불러오는 코드.
위와 같이, 데이터를 불러온다. “default” 즉, 기본값은 get방식이다. 순서는 다음과 같다.
  1. fetch를 이용해 todos의 1번 객체 데이터를 불러온다.
  1. then 메서드를 통해 응답 값을 json 형식으로 변환한다.
  1. then 메서드를 통해 그 값(data)을 console에 출력한다.
위 예제 코드의 결과의 콘솔 창위 예제 코드의 결과의 콘솔 창
위 예제 코드의 결과의 콘솔 창
다음과 같이 데이터를 잘 불러오는 것을 확인할 수 있다. 그렇다면, 이번엔 POST 방식으로 데이터를 전달해 보자. POST 방식에서는 “fetch(’URL’, {})”처럼 URL뒤의 두 번째 인자도 중요하다.
fetch("https://jsonplaceholder.typicode.com/posts", { method: 'POST', headers:{ "Content-Type" : "application/json" }, body: JSON.stringify({ title: "foo", body: "bar", userId: 1, }) })
POST 방식을 이용한 fetch API 요청 코드
서버에서 우리가 얻고자 하는 데이터가 json 형태인지 알기 위해서, methodheaders를 알맞게 기입해 주어야 한다. body에 JSON 메서드인 “JSON.stringify()”를 통해 데이터를 json 문자열 형식으로 꼭 변환해서 보내주어야 한다. 그리고 결과를 확인해 보자.
위 예제 코드를 실행한 결과의 콘솔 창위 예제 코드를 실행한 결과의 콘솔 창
위 예제 코드를 실행한 결과의 콘솔 창
위 콘솔 창과 같이 fetch 함수를 사용한 결과가 콘솔 창에 나타냈다. http 상태 코드 201은 “성공적으로 요청되었으며 서버가 새 리소스를 작성했다”라고 이해하면 된다. 그렇다면, POST로 서버에 보낸 우리의 데이터가 잘 있는지 확인해 보자.
fetch("https://jsonplaceholder.typicode.com/posts", { method: 'POST', headers:{"Content-Type" : "application/json"}, body: JSON.stringify({ title: "foo", body: "bar", userId: 1, }) }) .then(res => res.json()) .then(data => console.log(data))
POST 로 보낸 데이터의 결과를 json데이터로 다시 바꾸어 새로 입력된 데이터를 불러오기
위 코드에 더하여, GET 방식과 마찬가지로, 응답 값을 json 형식으로 바꾸고, 그 데이터를 콘솔에 불러오면 된다.
위 예제 코드를 실행한 결과의 콘솔 창위 예제 코드를 실행한 결과의 콘솔 창
위 예제 코드를 실행한 결과의 콘솔 창
결과는 위와 같이 잘 나오는 것을 볼 수 있고, 서버에서 id 값을 101로 부여한 것을 확인할 수 있다.
 

5. Fetch 성공 여부 확인 및 에러처리

5.1 Fetch 성공 여부 확인

fetch를 사용할 때 주의할 점이 있다. 다음 예제를 살펴보고 결과를 예측해보자.
fetch("https://jsonplaceholder.typicode.com/no-exist") .then(() => console.log("ok")) .catch(() => console.log("error")); // GET https://jsonplaceholder.typicode.com/no-exist 404 // ok
존재하지 않는 URL 요청 및 결과
위 예제에서는 존재하지 않는 URL이 사용되었기 때문에 404 에러가 발생하고 catch에 의해 ‘error’가 출력될 것으로 예상되지만 ‘ok’가 출력된다. 모든 에러가 catch에서 처리되면 좋겠지만 그렇지 않다. HTTP 요청을 보낼 수 없는 상태, 즉 네트워크 장애나 CORS 에러에 의해 요청이 완료되지 못한 경우에만 catch에서 ‘error’를 출력한다. 그래서 위와 같은 방식으로는 404 에러와 500 에러(내부 서버 오류)를 판단할 수 없다.
💡
CORS란 Cross-Origin Resource Sharing(교차 출처 자원 공유방식)의 약자로, 서로 다른 출처 간에 리소스를 공유하는 것을 의미한다. 도메인, 프로토콜, 포트 중 하나라도 다르면 서로 다른 출처이며, 추가적인 헤더를 사용해 다른 출처로 접근할 수 있는 권한을 부여받는다.
 
fetch 함수를 사용할 때는 아래과 같이 fetch 함수가 반환한 ok 상태를 확인해 에러를 처리해야 한다. Response 객체의 ok에는 요청에 대한 응답이 성공했는지 여부, 즉 상태코드 200번대 여부를 나타내는 불리언(boolean) 값이 담겨있다. Response의 ok 값이 true가 아니라면 throw 문을 통해 에러 객체를 던져 404 에러와 500 에러를 처리할 수 있게 된다.
fetch("https://jsonplaceholder.typicode.com/no-exist") .then(response => { if (!response.ok) throw new Error("404 or 500 error"); return response.json(); }) .then(users => console.log(users)) .catch(error => console.log(error)); // GET https://jsonplaceholder.typicode.com/no-exist 404 // Error: 404 or 500 error
Response 객체의 ok 속성을 활용한 에러 처리
 
위 예제의 Response 객체에 어떤 내용이 있는지 확인하기 위해 콘솔 창에 아래 코드를 입력 후 결과를 확인해보자.
fetch("https://jsonplaceholder.typicode.com/no-exist") .then(response => { if (!response.ok) return console.log(response); })
Response 객체 내용 확인하기
Response 객체의 ok 상태 확인하기Response 객체의 ok 상태 확인하기
Response 객체의 ok 상태 확인하기
Response 객체의 ok 상태가 false인 것을 확인할 수 있다. 이처럼 fetch 함수는 HTTP 에러 상태를 reject하지 않는 대신 응답의 상태가 200번대를 벗어날 경우 ok 속성이 false로 반환되는 속성이 있어 이를 활용해 에러를 처리할 수 있다.
 

5.2 에러 처리

에러는 그 발생 시점에 따라 ‘컴파일 에러’와 ‘런타임 에러’로 분류된다. ‘컴파일 에러’는 코드가 컴파일(Compile) 될 때 컴파일러가 해석하지 못해서 발생하는 에러이고 ‘런타임 오류’는 프로그램이 동작할 때 발견할 수 있는 에러다. 이중 ‘런타임 오류’를 자바스크립트에서 ‘예외(Exception)’라고도 부른다.
에러를 처리하기 위해 우선 if 문을 통해 에러를 개별적으로 처리하는 방법이 있을 것이다. 하지만 if 문으로 한 에러를 처리했다고 하더라도 또 어떤 오류가 생길지 예측하기 어렵다. 이러한 예측불가능성은 프로그램 강제 종료로 이어지기도 한다. 그래서 자바스크립트는 이러한 상황을 예방하기 위해 예외 처리(Exception handling) 장치로 try catch finally를 마련했다. try catch finally 에러 처리를 위한 코드를 미리 등록해 두고, 에러가 발생하면 에러 처리 코드로 넘어가도록 하는 에러 처리 방법이다.
try { // (1) 에러가 발생할 수 있는 코드 } catch (error) { // (2) 에러 발생 시 코드 } finally { // (3) 무조건 한번 실행되는 코드 } // 이후 동작
try catch finally 형식
try 코드블록인 (1)에서는 에러가 나더라도 프로그램이 강제종료 되지 않고 catch 코드블록인 (2)가 실행된다. 즉 (1)에서 예외상황이 발생하면 (2)에서 해당 예외 상황에 대한 동작을 실행하고, 예외 상황이 발생하는지 여부에 상관 없이 finally 코드블록인 (3)이 마지막으로 실행된다.
 
function follower() { const followerCount = 100; try { followerCount = 150; // 변경할 수 없는 값 수정 시도 console.log('skip'); // 실행되지 않음 } catch(e) { console.error(e); // 에러내용 확인 } finally { return followerCount + 1; // 무조건 한번 실행 } }; follower(); // TypeError: Assignment to constant variable. // 101
try catch finally 예제
우선 try 코드블록 내부를 살펴보면, 전역에서 const로 followerCount 값이 선언되었음에도 변경을 시도하고 있다. 이로 인해 에러가 발생하면 console.log('skip')이 실행되지 않는다. 에러 발생 시 바로 catch 문으로 이동하기 때문이다. 그 다음 catch 코드 블록에서 에러 객체를 담기 위한 변수인 e의 내용을 확인할 수 있고, 에러 발생 여부와 상관없이 finally 코드 블록이 실행된다.
 

6. 요청객체를 생성하고 전송하기

6.1. Request() 생성자로 생성한 요청 객체를 인자로 전달

우리가 fetch() 호출할때 리소스 경로를 제공하는 대신에 Request() 생성자로 생성한 요청 객체를 통해 인자로 전달하여 사용할 수 있다. 그렇다면 Request() 생성자란 무엇일까?

6.1.1 Request() 생성자

Request() 생성자는 새로운 Request 객체를 생성할 수 있다. fetch() 메서드의 매개변수와 동일하게 첫번 째 인자 값 input에는 접근하고자 하는 URL 을 담고, 두 번째 인자 값 init에는 method나 header, body 등의 옵션을 지정할 수 있다.
const myRequest = new Request(input, init);
예시
const myRequest = new Request("https://jsonplaceholder.typicode.com/posts/1", { headers: { "Content-Type": "application/json", }, }); fetch(myRequest) .then(res => res.json()) .then(data => console.log(data));
 

6.1.2 왜 써야할까?

기존에 존재하는 요청 객체를 전달해서 복사본을 생성하는 것이 가능하다. 이렇게 복사본 생성을 해두면 다시 기존에 생성해둔 요청과 응답 객체를 다시 사용할 수 있다. 또한 다시 사용하되, init 옵션만 따로 교체할 수도 있다. 하지만 이미 본문을 읽은 요청 또는 응답을 복사할 수 없다. 즉 복사본은 원본 본문을 읽기전에 생성해야 한다.
const copyRequest = new Request(myRequest);
💡
참고로, 오직 복사본 생성을 위한 clone() 메서드도 존재한다. 현재 Request 객체의 복사본을 만드는 clone 메서드 또한 마찬가지로 요청 본문이 이미 사용된 경우 TypeError를 발생시킨다. 앞서 배운 Request 생성자와 동일하게 복사본을 생성할 수 있지만 clone메서드의 주된 목적은 body의 object의 다중 사용을 위함이고, 요청을 수정하려는 경우에는 Request 생성자를 더 선호한다.
 

7. Axios 시작하기

7.1 Axios 사용 이유

7.1.1 Axios 정의

Axios는 node.js와 브라우저를 위한 Promise기반 HTTP클라이언트 이다. 동일한 코드베이스로 브라우저와 node.js에서 실행할 수 있으며, 서버 사이드에서는 네이티브 node.js의 http모듈을 사용하고, 클라이언트(브라우저)에서는 XMLHttpRequests를 사용한다.[1]
 

7.1.2 Axios 사용 이유

Axios는 return을 promise로 해주기 때문에 response데이터를 처리하는데 수월하고, Fetch API와는 달리 크로스 브라우징에 최적화되어 있어 오래된 브라우저에서도 지원한다. 또한 Fetch에 비해Axios로 에러를 처리하는게 더욱 간결하며, .json() 메서드를 사용하지 않아도 자동으로 JSON 데이터 형식으로 변환된다. 요청을 취소할 수 있고 타임아웃을 걸 수 있으며, CSRF[2] 보호 기능이 내장되어 있어 보안에 더욱 용이하다.

7.2 Axios와 Fetch의 차이

7.2.1 Axios와 Fetch에 대해서

Axios 는 브라우저와 node.js에서 사용할 수 있는 Promise 기반 HTTP 클라이언트 라이브러리이며, npm이나 yarn과 같은 패키지 매니저를 통해 설치할 수 있다.
Fetch 는 API가 제공하는 전역 fetch()메서드를 통해 네트워크의 리소스를 비동기적으로 가져올 수 있다. 그리고, 모던 브라우저에 내장되어 있어 Axios처럼 따로 설치할 필요가 없다.
AxiosFetch 모두 Promise 기반의 HTTP 클라이언트이기 때문에 네트워크 요청시 Promise가 반환되어 데이터 다루기 편리하다.
 

7.2.2 Axios와 Fetch의 기능 차이

JSON 데이터 변환

Axios와 Fetch를 이용해 데이터를 불러올 때 데이터 형식의 차이에 대해서 알아보자.
 
JSONPlaceHolder라는 REST API에 GET 요청으로 데이터를 불러오고 직접 비교해보자. 아래는 FetchGET 요청을 통해 투두 리스트의 첫번째 아이템 데이터를 가져오는 예제이다.
const url = "https://jsonplaceholder.typicode.com/todos/1"; fetch(url) .then((response) => response.json()) .then(console.log);
Fetch GET
결과는 다음과 같다.
notion imagenotion image
fetch()JSON 데이터의 포맷이 아닌 형태로 응답 데이터를 반환한다. 그래서, 응답객체의 .json()메서드를 호출하여 JSON형식의 데이터로 된 또 다른 데이터를 반환해야 한다.
 
아래 코드는 같은 요청을 Axios로 수행하는 코드이다.
const url = "https://jsonplaceholder.typicode.com/todos/1"; axios(url) .then((response) => console.log(response.data));
Axios GET
Axios기본적으로 JSON 타입으로 된 응답 데이터를 반환한다. 응답 객체의 data 프로퍼티를 통해서 응답 데이터를 사용할 수 있다.
 

자동 문자열 반환

이번에는 AxiosFetch 의 데이터를 문자열로 변환해주는 방법의 차이에 대해서 알아보자.
 
아래는 FetchPUTAxiosPUT을 비교하는 예제이다. FetchPUT 요청을 통해서 데이터를 변환하자. Fetch 챕터의 PUT에서 사용한 예제를 기반으로 비교해보자. (9.3 Axios PUT 요청을 참조.)
async function putData(url = '', data = {}, token = '') { try { const response = await fetch(url, { //1️⃣ method: 'PUT', headers: { 'Content-Type': 'application/json', Authorization: token, }, body: JSON.stringify(data), //2️⃣ }); return response.json(); } catch (error) { console.log(error); } } putData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, title: "Put test", body: "fetch의 Put 메소드를 테스트 중입니다.", userId: 1, }).then((data) => { console.log(data); });
Fetch PUT
결과는 다음과 같다.
notion imagenotion image
Fetch 에서는 JSON.stringify() 를 사용해서 객체를 문자열로 변경해주고, body 에 할당해야 한다.
 
아래 코드는 같은 요청을 Axios로 수행하는 코드이다.
async function putData(url = '', data = {}, token = '') { try { const response = await axios(url, { //1️⃣ method: 'PUT', headers: { 'Content-Type': 'application/json', Authorization: token, }, data: data, //2️⃣ }) .then((response) => console.log(response.data)); } catch (error) { console.log(error); } } putData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, title: "Put test", body: "axios의 Put 메소드를 테스트 중입니다.", userId: 1, }).then((data) => { console.log(data); });
Axios PUT
결과는 다음과 같다.
notion imagenotion image
Axios 에서는 자동으로 데이터를 문자열로 변환되어 데이터 형식을 변환하는 함수를 사용할 필요가 없으며, 변경하고자 하는 데이터는 data 프로퍼티에 할당한다.
 
둘의 차이를 주석에 적혀진 1️⃣, 2️⃣를 비교하며 알아보자. 1️⃣은 fetchaxios 로 바뀌었고, 2️⃣는 변경하고자 하는 데이터는 bodydata로 할당되었으며 데이터 형식을 변환하는 함수인 JSON.stringify() 는 따로 적어주지 않는다.
 

7.2.3 Request 취소 및 Timeout 설정

HTTP 요청 시간이 초과 될 경우 요청을 취소하기 위해서 어떻게 처리해야하는지 살펴보자.
 
const url = "https://jsonplaceholder.typicode.com/todos/2"; axios .get(url, { timeout: 10, // 요청이 0.01초이상 걸리면 종료하고 error 띄우기 }) .then((response) => console.log(response.data)) .catch((error) => { console.log(error.message); });
Axios: 시간내에 요청을 종료하지 못했을 때, 요청을 취소함Axios: 시간내에 요청을 종료하지 못했을 때, 요청을 취소함
Axios: 시간내에 요청을 종료하지 못했을 때, 요청을 취소함
Axios: 시간 내에 요청을 수행했을 때, 정상적으로 데이터를 불러옴Axios: 시간 내에 요청을 수행했을 때, 정상적으로 데이터를 불러옴
Axios: 시간 내에 요청을 수행했을 때, 정상적으로 데이터를 불러옴
Axios에서는 timeout 속성으로 간단하게 요청 종료시간을 지정할 수 있다.
 
아래 코드는 같은 요청을 Fetch로 수행하는 코드이다.
const url = "https://jsonplaceholder.typicode.com/todos/2"; const abortcontroller = new AbortController(); const signal = abortcontroller.signal; setTimeout(() => abortcontroller.abort(), 10); fetch(url, { signal: signal, }) .then((response) => response.json()) .then(console.log) .catch((err) => { console.error(err.message); });
Fetch: 시간 내에 요청을 종료하지 못했을 때, 요청을 취소함Fetch: 시간 내에 요청을 종료하지 못했을 때, 요청을 취소함
Fetch: 시간 내에 요청을 종료하지 못했을 때, 요청을 취소함
Fetch: 시간 내에 요청을 수행했을 때, 정상적으로 데이터를 불러옴Fetch: 시간 내에 요청을 수행했을 때, 정상적으로 데이터를 불러옴
Fetch: 시간 내에 요청을 수행했을 때, 정상적으로 데이터를 불러옴
 
Fetch에서는 AbortController 인터페이스를 사용하여 요청 종료시간을 지정할 수 있다.
abortcontroller 객체 생성 뒤, signal 객체와 abort()메서드에 접근했다. signal 객체를 설정 옵션에 추가하여 서버가 지정한 시간 이내에 응답하지 않으면 fetch 요청이 종료된다.
 

7.2.4 브라우저 지원

Axios는 크로스 브라우징 최적화로 폭넓은 브라우저 호환성을 보장한다.
Fetch는 크롬 42, edge 14, Firefox 39, Opera 29, Safari 10.1에서 지원한다. 하지만, Internet Explorer에서는 지원하지 않는데, 이는 polyfill을 이용해서 사용이 가능하다.
 

7.2.5 Axios와 Fetch 중 어떤 것을 써야 할까

개인의 사용 편의성에 따라서 달라질 수 있다. Axios는 따로 설치를 해야하지만, 위와 같이 여러 기능을 간단하게 사용할 수 있는 장점이 있다. Fetch는 별도의 설치 없이 바로 사용할 수 있지만, Axios에서 쉽게 구현이 가능한 기능이 fetch에서는 직접 구현해야 하는 번거로움이 있다. 이러한 특성을 고려하여 본인에게 편리한 것을 선택하여 사용하는 것이 좋다.
 

7.3 Axios 시작하기

 
Axios를 사용하기 위하여 먼저 Axios를 설치해주어야 한다. Axios를 설치하는 방법은 아래와 같이 크게 2가지가 있다.
 

7.3.1 Node.js 개발 환경에서 설치/사용

 
Node.js 개발 환경에서 설치를 하기 위해서 먼저 Node.js를 설치해주어야 한다. (설치 링크: https://nodejs.org/ko/) Node.js 설치 완료 후, 에디터의 터미널 창에 아래와 같은 명령어를 입력하여 Axios를 설치해 준다.
 
npm install axios
yarn add axios
 
위 두 가지 명령어 중 한가지를 선택하여 사용하면 된다. 단 npm과 yarn의 패키지 관리방식은 차이가 있기 때문에 혼용하면 충돌이 일어날 수 있다. 따라서 가급적 혼용하지 않도록 한다.
 

7.3.2 브라우저 환경에서 설치/사용

 
브라우저 환경에서 Axios를 설치 및 사용하기 위하여 CDN을 사용한다. 아래와 같은 Axios CDN링크가 들어간 스크립트를 추가해 준다.
 
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 

8. Axios 문법

8.1 Axios API

Axios API 의 사용 방법은 기본적으로 아래와 같다.
axios(config) axios(url, [config]) axios.요청메서드(url, [, data[,config]])
 
axios({ method: "get", url: "https://jsonplaceholder.typicode.com/post/1", ... (추가하고 싶은 옵션들) })
config 를 전달해서 요청하는 방법
 
axios("https://jsonplaceholder.typicode.com/posts/1",{ method: "get", })
url 을 전달하고 선택적으로 config 객체를 전달하여 요청하는 방법
 
axios.get("https://jsonplaceholder.typicode.com/posts/1",{ data(POST, PUT, PATCH 만) , {config} }
요청메서드를 이용해 요청하는 방법
 
notion imagenotion image
notion imagenotion image

8.1.1 요청 config 옵션들

사용 가능한 config 의 설정옵션들 중 자주쓰이는 것들을 골라보았다. 나머지 옵션들과 default값 은 axios 깃헙 [8.8.1]에서 볼 수 있다.
URL 요청에 사용될 서버 URL 이고 config 에서 필수로 들어가야한다. 아래와 같이 사용한다.
axios({ url: "https://jsonplaceholder.typicode.com/post/1" })
baseURL URL의 기본값을 설정할 수 있다. URL이 절대값이 아닌경우 URL 앞에 붙는다. 아래 사용예제 처럼 baseURL 을 설정되어있을 때 URL 이 절대값이 아닌경우 URL 앞에 붙어서 처리된다.
axios({ method: "get", url: "/posts/1", baseURL : "https://jsonplaceholder.typicode.com" }) // 이렇게 baseURL 을 주고 url 로 다른 경로를 주면 url로 대체된다. axios({ method: "get", url: "https://jsonplaceholder.typicode.com/posts/1", baseURL : "https://jsonplaceholder.typicode.com" })
headers 사용자 지정 헤더 , 아래와 같이 사용해서 설정 할 수 있다.
headers: {'Content-Type': 'application/json'}
💡
전송하고자 하는 데이터가 JSON 형식일 경우 Axios는 기본적으로 JSON 형태의 데이터를 사용하기 때문에, Axios에 자바스크립트 객체를 전달해주면 Axios는 자동적으로 해당 객체를 직렬화(serialize)하고, content-type 헤더를 별도로 지정해주지 않아도 자동적으로 application/json 으로 설정해준다. 하지만 에러에 대비하여 헤더를 지정해주는 것이 권장되므로, 이는 [9.2.3] 챕터의 예제3에서 더욱 자세히 살펴보도록 하겠다.
params 요청과 함께 전송되는 url 파라미터이다. 반드시 일반 객체URLSearchParams 객체여야 한다. URLSearchParams객체는 주로 application/x-www-form-urlencoded 포맷을 보내는데 사용된다.
paramsSerializer params의 시리얼라이즈를 어떻게 처리할 지 설정해주는 선택옵션이다.
data data는 요청 본문으로 전송할 데이터이고 PUT, POST, PATCH 메서드에만 적용가능하다. transformRequst 가 설정되지 않은 경우 다음 유형 중 하나여야 한다. string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams, FormData, File, Blob, 아래와 같이 사용할 수 있다.
axios({ method: "POST", url: "https://jsonplaceholder.typicode.com/posts" headers : { "Content-Type" : "application/json", }, data: (업로드할 데이터) // 위에 설명한 유형 중 하나여야 한다. })
withCredentials 기본값은 false 이고 자격 증명을 사용하여 CORS 요청이 필요한 경우 설정한다.
responseType 서버에서 응답할 데이터 타입을 설정한다. 기본값은 json 이고 arraybuffer, blob, document, json, text, stream 이 있다.
timeout 요청이 타임 아웃되는 밀리 초(ms)를 설정한다. 요청이 설정 시간보다 지연 될 경우, 요청은 중단된다. 기본값은 0이다. (타임아웃 없음)

8.1.2 Config 전역 기본값 설정

모든 요청에 적용되는 config 기본값들을 설정할 수 있다. 아래와 같이 사용해서 요청 config의 기본값을 설정해서 반복적으로 쓰지 않고 사용할 수 있다.
axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com'; axios.defaults.headers.common['Authorization'] = 'test'; axios({ url: "/posts/1" }).then(response => console.log(response));
notion imagenotion image
기본값으로 baseURLheadersAuthorization 값을 설정해주고 URL만 넣어서 요청해주면 사진과 같이 설정값으로 요청이 가는 것을 확인할 수 있다. baseURL을 설정하고 URL에서 경로를 다르게 넣어줄 수도 있다.
axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com'; axios({ url: "https://mandarin.api.weniv.co,kr/user" }).then(response => console.log(response));
notion imagenotion image
baseURL대신 URL 에 입력한 값으로 요청을 보내고 값이 다른 것을 확인할 수 있다. 또한 아래처럼 axios.create 로 생성한 인스턴스에도 설정해서 사용할 수있다.
const instance = axios.create({ baseURL: "https://jsonplaceholder.typicode.com" }); instance.defaults.timeout = 2500; instance.get('/posts/1').then(response => console.log(response));
notion imagenotion image
처음 instance를 생성할 때 설정한 baseURL와 나중에 설정해준 timeout이 들어간 결과를 확인할 수 있다. config 설정의 적용에는 우선순위가 존재하는데 요청 config, 생성한 인스턴스의 기본값, 초기설정의 기본값 전자부터 순서대로 우선순위가 높다. 위 예제에서 제일 우선순위가 높은 요청 config 내의 설정값으로 timeout 값을 조정해보겠다. 자세한 우선순위는 axios 깃헙에서 참고 [8.1.2] 할 수 있다.
const instance = axios.create({ baseURL: "https://jsonplaceholder.typicode.com" }); instance.defaults.timeout = 2500; instance.get('/posts/1',{ timeout: 4000 }).then(response => console.log(response));
notion imagenotion image
바꿔준 대로 timeout의 값이 4000으로 설정된 것을 확인할 수 있다.

8.2 Axios 응답 스키마

8.2.1 요청했을 때 응답 스키마 종류 및 예제 [1]

const getData = () => { axios .get("https://exampleURL/user") .then(function (response) { console.log(response); }); }; getData();
notion imagenotion image
코드를 보면 response를 console.log로 찍은 것을 볼 수 있다. console 창을 확인해 보면 6가지의 axios 응답 스키마가 출력되었다.
  • config : 요청을 위한 Axios가 제공하는 구성이다.
  • data : 서버가 제공하는 응답 데이터이다.
  • headers : HTTP 헤더이다. 모든 헤더 이름은 소문자이고, 괄호 표기법으로 접근이 가능하다. 예로 response.headers["content-type"]
  • request : 응답으로 생성된 요청이다. node.js에서 마지막 ClientRequest 인스턴스고 브라우저에서 XMLHttpRequest이다.
  • status : status는 HTTP 상태 코드이다. HTTP 상태 코드는 HTTP 공식 문서[2] 또는 앞선 HTTP 응답 부분을 확인바란다.
  • statusText : HTTP 상태 코드에 대한 메세지이다.
 

9. Axios 사용해보기

9.1 GET 요청

9.1.1 Axios의 GET이란?

AxiosGET은 앞서 Fetch에서 언급한 GET과 동일한 RESTful API 기반 메서드로, Axios에 내장되어 있다. 데이터를 가져올 때(Read) 사용한다.

9.1.2 사용 방법

기본으로 사용하는 문법은 다음과 같다.
axios({ method: "GET", url: "url", });
별칭 메소드 사용시 단축 문법은 다음과 같다. url 에는 연결하고자 하는 서버 주소 , config 에는 request header를 파라미터로 넣어준다.
axios.get(url[, config])
axios.get("연결하고자 하는 서버 주소", request header)

9.1.3 실습 예제

Fetch에서의 실습과 동일하게 https://jsonplaceholder.typicode.com/에서 posts의 1번 게시물을 가져와 보자.
 
예제1. 요청 파라미터를 사용한 Axios GET
axios({ method: "get", url: "https://jsonplaceholder.typicode.com/posts/1", headers: { "Content-Type": "application/json", }, }) .then(function (response) { console.log(response); }) .catch(function(error){ console.log(error); })
 
예제2. 단축 메서드를 사용한 Axios GET
axios.get("https://jsonplaceholder.typicode.com/posts/1",{ headers: { "Content-Type": "application/json", }, } ) .then(function(response){ console.log(response); }) .catch(function(error){ console.log(error); })
 
예제3 . async/await을 사용한 Axios GET
async function axiosGet() { try{ const response= await axios.get("https://jsonplaceholder.typicode.com/posts/1",{ headers: { "Content-Type": "application/json", } }) console.log(response); } catch (error){ console.log(error); } } axiosGet();
 
예제4. async/await으로만든 함수를 호출 후 then으로 결과 출력한 Axios GET
async function getData(url='') { try { const response = await axios(url, { method: 'get' }); console.log(response); return response; } catch (error) { console.log(error); } } getData("https://jsonplaceholder.typicode.com/posts/1") .then((response) => { console.log(response); });
 
위 예제들의 결과 다음과 같다.
notion imagenotion image
 

9.2 POST 요청

9.2.1 Axios의 POST란?

AxiosPOST는 앞서 fetch에서 살펴보았던 POST와 동일한 RESTful API 기반의 메서드로, Axios API에도 내장되어 있다. 서버에 비교적 용량이 큰 데이터를 전송하거나 해당 데이터를 url에 나타내지 않고 전송할 때 사용한다.
fetch와 비교해보면, JSON 메서드를 사용하지 않아도 되는 점, 요청 헤더가 자동으로 설정되는 점 덕분에 훨씬 간결한 문법과 편리함을 엿볼수 있다. 아래 예제로 살펴보자.

9.2.2 사용 방법

기본으로 사용하는 문법은 다음과 같다.
axios({ method: "POST", // 요청 방법 url: "url", // 요청할 서버 주소 data: { } // 서버에 POST하고자 하는 데이터 });
별칭 메서드 사용시 단축 문법은 아래와 같다. 요청할 서버 주소인 url, 서버에 전송하고자 하는 데이터, config 에는 request 헤더를 각각 파라미터로 넣어주면 된다.
axios.post(url[, data[, config]])
axios.post("요청할 서버 url", 서버에 POST하고자 하는 데이터, request 헤더)

9.2.3 실습 예제

Fetch에서의 실습과 동일하게 POST를 이용하여 아래와 같은 데이터를 https://jsonplaceholder.typicode.com/posts 에 생성하는 실습을 해 보자.
const postTestData = { title: "Post test", body: "axios의 Post 메소드를 테스트 중입니다.", userId: 2, };
 
예제1. 요청 파라미터를 사용한 Axios POST
axios({ method: "post", url: "https://jsonplaceholder.typicode.com/posts/", headers: { "Content-Type": "application/json", }, data: postTestData, }) .then(function (response) { console.log(response); .catch(function(error){ console.log(error) })
 
예제2. 단축 메서드를 사용한 Axios POST
axios.post("https://jsonplaceholder.typicode.com/posts/", postTestData, {headers: { "Content-Type": "application/json", }, }) .then(function (response) { console.log(response) }) .catch(function (error) { console.log(error) })
 
예제3 . async/await을 사용한 Axios POST
async function axiosPost() { try { const response = await axios.post("https://jsonplaceholder.typicode.com/posts", postTestData, {headers: { "Content-Type": "application/json", }, }); console.log(response.data); } catch (error) { console.error(error.message); } } axiosPost();
 
또한 앞서 간단히 언급한 바와 같이, 만약 content-type 헤더를 별도로 지정해주지 않아도 자동적으로 application/json 으로 설정해주는 것을 확인할 수 있다.
async function axiosPost2(){ try { const response = await axios.post("https://jsonplaceholder.typicode.com/posts", postTestData); console.log(response.data); console.log(response.headers["content-type"]); // "application/json;charset=utf-8" } catch(error){ console.error(error.message); } axiosPost2();
notion imagenotion image
 
예제4. async/await으로만든 함수를 호출 후 then으로 결과 출력한 Axios POST
async function postData(url="", data={}) { try { const response = await axios.post(url, data); console.log(response); } catch (error) { console.log(error); } } postData("https://jsonplaceholder.typicode.com/posts", postTestData) .then((response) => { console.log(response); });
 
위 예제들의 결과는 다음과 같다.
notion imagenotion image
 
  • 전송하고자 하는 데이터가 이미지 혹은 영상인 경우
request 헤더의 content-type 값이 multipart/form-data 로 자동적으로 설정되지만, 만일 데이터가 제대로 전송되지 않는 에러를 대비하여 한번 더 지정해주는 것이 권장된다.
imgConfig = { headers: { 'content-type': 'multipart/form-data' } } const result = await axios.post('url', formData 객체에 담긴 이미지 데이터, imgConfig);
 

9.3 PUT 요청

9.3.1 Axios의 PUT이란?

AxiosPUT은 앞서 Fetch에서 언급한 PUT과 동일한 RESTful API 기반 메서드로, Axios에 내장되어 있다. 데이터를 수정(Update)할 때 사용한다.

9.3.2 사용방법

기본으로 사용하는 문법은 다음과 같다.
axios({ method: "PUT", // 전송 방법 url: "url", // 연결하고자 하는 서버 주소 data: {data}, // 전송하고자 하는 데이터 }).then(function (response) { // response Action });
별칭 메소드 사용시 단축 문법은 다음과 같다. url 에는 연결하고자 하는 서버 주소, data에는 전송하고자 하는 data, config 에는 request header를 파라미터로 넣어준다.
axios.put(url[, data[, config]])
axios.put("연결하고자 하는 서버 주소", Put하고자 하는 data, request header])

9.3.3 실습 예제

다음은 Axios PUT의 다양한 작성방법이다.
 
예제1. 요청 파라미터를 사용한 Axios PUT
axios({ method: "PUT", url: "https://jsonplaceholder.typicode.com/posts/1", data: { id: 1, title: "Put test", data: "axios의 Put 메소드를 테스트 중입니다.", userId: 1, } }) .then(function (response) { console.log(response); }) .catch(function(error){ console.log(error) })
 
예제2. 단축 메서드를 사용한 Axios PUT
axios.put("https://jsonplaceholder.typicode.com/posts/1",{ id: 1, title: "Put test", body: "axios의 Put 메소드를 테스트 중입니다.", userId: 1, }) .then(function(response){ console.log(response) return response; }) .catch(function(error){ console.log(error) })
 
예제3. async/await을 사용한 Axios PUT
async function axiosPut() { try{ const response= await axios.put("https://jsonplaceholder.typicode.com/posts/1",{ id: 1, title: "Put test", body: "axios의 Put 메소드를 테스트 중입니다.", userId: 1, }) console.log(response); return response; } catch (error){ console.log(error); } } axiosPut();
예제4. async/await으로만든 함수를 호출 후 then으로 결과 출력한 Axios PUT
async function putData(url = "", data = {}) { try { const response = await axios .put(url, data, { headers: { 'Content-Type': 'application/json', }) console.log(response.data) return response; } catch (error) { console.log(error); } } putData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, title: "Put test", body: "axios의 Put 메소드를 테스트 중입니다.", userId: 1, }) .then((data) => { console.log(data); });
 
위 3개의 예제의 결과는 다음과 같다.
notion imagenotion image

9.4 PATCH 요청

9.4.1 Axios의 PATCH란?

AxiosPatch 는 앞서 Fetch에서 언급한 Patch 와 동일한 RESTful API 기반 메서드로, Axios에 내장되어 있다. 데이터를 수정(Update)할 때 사용한다. Put 과 다르게 일부분만 수정할 때 사용한다.

9.4.2 사용방법

기본으로 사용하는 문법은 다음과 같다.
axios({ method: "PATCH", // 전송 방법 url: "url", // 연결하고자 하는 서버 주소 data: {data}, // 전송하고자 하는 데이터 })
별칭 메소드 사용시 단축 문법은 다음과 같다. url 에는 연결하고자 하는 서버 주소, data에는 전송하고자 하는 data, config 에는 request header를 파라미터로 넣어준다.
axios.patch(url[, data[, config]])
axios.patch("연결하고자 하는 서버 주소", Patch하고자 하는 data, request header])
 

9.4.3 예제

다음은 Axios PATCH의 다양한 작성방법이다.
 
예제1. 요청 파라미터를 사용한 Axios PATCH
axios({ method: "patch", url: "https://jsonplaceholder.typicode.com/posts/1", headers: { "Content-Type": "application/json", }, data: { title: 'patch 테스트 입니다." }, }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
 
예제2. 단축 메서드를 사용한 Axios PATCH
axios .patch("https://jsonplaceholder.typicode.com/posts/1", { headers: { "Content-Type": "application/json", }, title: "patch 테스트입니다.", }) .then(function (res) { console.log(res); }) .catch(function (error) { console.log(error); });
 
예제3. async/await을 사용한 Axios PATCH
async function axiosPatch() { try { const response = await axios.patch( "https://jsonplaceholder.typicode.com/posts/1", { headers: { "Content-Type": "application/json", }, title: "patch 테스트 입니다.", } ); console.log(response); } catch (error) { console.log(error); } } axiosPatch();
 
예제4. async/await으로만든 함수를 호출 후 then으로 결과 출력한 Axios PATCH
async function patchData(url = "", data = {}) { try { const response = await axios.patch(url, data); console.log(response); return response; } catch (error) { console.log(error); } } patchData("https://jsonplaceholder.typicode.com/posts/1", { title: "patch 테스트 입니다.", }).then((response) => { console.log(response); });
 
위 4개의 예제의 결과는 다음과 같다.
notion imagenotion image

9.5 DELETE 요청

9.5.1 Axios의 DELETE란?

AxiosDELETEFetch 에서 언급한 DELETE 와 동일한 RESTful API 기반 메서드로, Axios에 내장되어 있다. url에 표기된 query문에 해당하는 리소스를 삭제(Delete)할 때 사용한다.
다른 메서드들과 달리 DELETE는 일반적으로 body 부분이 비어있는 형태이다. 하지만 많은 데이터를 요청할 경우에는 두 번째 인자 값에 data를 추가해줄 수도 있다.

9.5.2 사용방법

기본으로 사용하는 문법은 다음과 같다.
axios({ method: "delete", // 전송 방법 "delete" url: "url", // 연결하고자 하는 서버 주소 }).then(function (response) { // response Action });
별칭 메서드 사용시 단축 문법은 다음과 같다. url 에는 연결하고자 하는 서버 주소 , config 에는 request header를 파라미터로 넣어준다.
axios.delete(url[, config])
axios.delete("연결하고자 하는 서버 주소", request header)
 
3.4.1에서 언급했던 내용처럼 두번째 인자값에 data를 추가해서 사용하는 다음과 같은 방법도 있다.
axios.delete("url", { data: { data... } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); })
 

9.5.3 실습 예제

Fetch에서의 실습과 동일하게 https://jsonplaceholder.typicode.com/에서 posts의 1번 게시물을 삭제해보자.
 
예제1. 요청 파라미터를 사용한 Axios DELETE
axios({ method: "delete", // "delete" 메서드의 이름을 명시 url: "https://jsonplaceholder.typicode.com/posts/1", // 1번 posts에 대한 요청 headers: { "Content-Type": "application/json", }, }) .then(function (response) { // 응답 console.log(response); });
 
예제2 . async/await을 사용한 Axios DELETE
axios.delete("https://jsonplaceholder.typicode.com/posts/1", headers: { "Content-Type": "application/json", }, ) .then(function (response) { console.log(response); // 성공 응답 출력 }) .catch(function (error) { console.log(error); // 에러 응답 출력 })
 
예제3. 단축 메서드를 사용한 Axios DELETE
async function DeleteAxios() { try { const response = await axios.delete("https://jsonplaceholder.typicode.com/posts/1", headers: { "Content-Type": "application/json", }, ); console.log(response); } catch (error) { console.log(error); } }
 
예제4. async/await으로만든 함수를 호출 후 then으로 결과 출력한 Axios DELETE
async function DeleteData(url = "", data = {}) { try { const response = await axios(url, { method: "delete", }); console.log(response); return response; } catch (error) { console.log(error); } } DeleteData("https://jsonplaceholder.typicode.com/posts/1", { id: 1, }).then((response) => { console.log(response); });
 
위 예제들의 결과는 다음과 같다.
notion imagenotion image
콘솔 창의 응답 결과에서 data값은 비어있지만, HTTP 상태코드인 status가 200이므로 delete가 성공적으로 잘 처리된 것을 알 수 있다.
 

10. Axios 성공 여부 확인하기, 에러 처리

10.1 Axios 성공 여부 확인하기

네트워크 장애나 CORS 에러에 의해 요청이 완료되지 못한 경우에만 프로미스를 reject 하는 fetch 함수와 달리 axios를 사용하게 된다면 성공 여부를 쉽게 확인할 수 있다. 다음 두 가지 예제를 통해 이를 알아보자.
axios.get("https://jsonplaceholder.typicode.com/posts/1") .then((response) => { console.log(response); }) .catch((error) => console.error(error));
1번 코드
notion imagenotion image
axios.get("https://jsonplaceholder.typicode.com/wrong") .then((response) => { console.log(response); }) .catch((error) => console.log(error));
2번 코드
notion imagenotion image
1번 코드는 정상적인 URL을 입력해 response가 출력되고, 2번 코드는 부적절한 URL를 입력해 error가 출력되는 것을 확인할 수 있다.
이처럼 axios는 fetch 함수를 이용한 코드에서 resolve한 ok 상태를 확인하고 명시적으로 에러를 처리했던 과정 없이 간단하게 성공 여부를 확인할 수 있고, 에러가 어떤 이유로 발생했는지에 대해까지 판단할 수 있게 해준다.

10.2 에러 처리

axios가 정상적으로 작동했을 때 요청에 대한 응답은 6가지의 스키마를 제공한다. 비정상적으로 작동했을 때도 마찬가지로 6가지의 스키마를 제공하는데 이를 이용해 다양한 방식으로 에러를 처리할 수 있다. 먼저 다음 예제에서 에러가 발생했을 때 error를 콘솔창에 출력한 결과를 보자.
axios.get("https://jsonplaceholder.typicode.com/wrong") .then((response) => { console.log(response); }) .catch(function (error) { console.log(error); });
notion imagenotion image
출력 결과인 error 객체의 response를 이용하면 서버에 요청이 이루어지고 서버가 ‘2xx’를 넘어가는 상태 코드(’5xx’, ‘4xx’)로 응답했을 때에 대해 에러 처리가 가능하고, request를 이용하면 서버에 요청이 이뤄졌으나 응답을 받지 못한 경우에 대한 에러 처리가 가능하다. 이를 다음 예제와 같은 코드로 작성이 가능하다.
axios.get("https://jsonplaceholder.typicode.com/wrong") .then((response) => { console.log(response); }) .catch(function (error) { if (error.response) { console.log(error.response.status); } else if (error.request) { console.log(error.request); } else { console.log(error.message); } });
responserequest를 이용하기 위해 if 조건문을 사용했고, 마지막 else의 경우 요청을 설정하는데 문제가 발생한 경우를 처리하게 된다.
또한, axios는 응답 시간초과 설정을 기본적으로 제공한다. 이를 이용해 요청을 하고 일정 시간이 지나면 에러 처리를 하도록 할 수 있다.
axios({ method: "get", timeout: 1, url: "https://jsonplaceholder.typicode.com/posts/1", }) .then((response) => { console.log(response); }) .catch(function (error) { console.log(error); });
notion imagenotion image
위 예제에서는 axios 의 요청 파라미터의 timeout값을 1로 입력해 응답 시간을 1ms로 설정했다. 그 뒤 예시 API에 get 요청을 하게 되면, 당연히 예시 API는 1ms 안에 응답을 할 수 없으므로 시간이 초과되었다는 에러를 콘솔창에 출력하는 것을 확인할 수 있다.
 

11. 참고자료

1.[1] https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Basic_concepts 2.1.[1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Status 2.1.[2] https://developer.mozilla.org/en-US/docs/Web/API/Response 2.2.[1] https://fetch.spec.whatwg.org/#fetch-method 2.2.[2] https://fetch.spec.whatwg.org/#headers-class 2.2.[3] https://fetch.spec.whatwg.org/#request-class 3.1.[1] https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch 3.1.[2] https://jsonplaceholder.typicode.com/ 3.2.[1] https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/POST 3.4.[1] https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch 3.4.[2] https://jsonplaceholder.typicode.com/ 3.5.[1] https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch 3.5.[2] https://jsonplaceholder.typicode.com/ 4.[1] https://en.wikipedia.org/wiki/API 4.[2] https://jsonplaceholder.typicode.com/ 7.1.[1]https://axios-http.com/kr/docs/intro 7.1.[2] CSRF - 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행동(수정, 삭제, 등록 등)을 하여 특정 웹사이트에 요청하게 하는 공격을 말한다. 7.3.[1] https://axios-http.com/kr/docs/intro 8.1.[1] https://github.com/axios/axios/blob/v1.x/lib/defaults/index.js 8.1.[2] https://jsonplaceholder.typicode.com/ 8.1.[3] https://github.com/axios/axios/blob/v1.x/lib/defaults/index.js 8.2.[1] https://axios-http.com/kr/docs/res_schema 8.2.[2] https://developer.mozilla.org/en-US/docs/Web/HTTP/Status 9.2.[1] https://developer.mozilla.org/ko/docs/Web/API/FormData