🔥 학습목표
- REST API가 무엇인지에 대해 공부한다.
- HTTP 메서드에 대해 학습한다.
- JavsScript에서 사용할 수 있는 HTTP 클라이언트 라이브러리에 무엇이 있는지 확인한다.
- 각 HTTP 클라이언트 라이브러리에 대한 사용법에 익숙해진다.
REST API(Representational Programming Interface)란, REST라는 아키텍처 스타일을 따르는 API. API 개발자는 REST를 제외하고도 여러 아키텍처를 사용해 API를 설계할 수 있다.
다른 소프트웨서 시스템과 통신하기 위해 따라야 하는 규칙이나 형식
서로 다른 애플리케이션 또는 장치가 서로 데이터나 기능을 교환하고 상호작용 할 수 있도록 돕는다.
API는 컴퓨터나 소프트웨어끼리만 사용되는 인터페이스다.
즉, 사용자가 직접 보거나 조작할 수 없고, 개발자가 소프트웨어에 포함해야 한다.
API의 작동 방식에 대한 조건을 부과하는 소프트웨어 아키텍처
└▶ 인터넷과 같은 복잡한 네트워크에서 통신을 관리하기 위한 지침으로 만들어졌다.
고유 리소스 식별자 (url
) - 리소스에 대한 경로를 지정하며 웹페이지를 방문하기 위해 브라우저에 입력하는 주소와 유사하다. 클라이언트가 요구하는 사항을 서버에 명확하게 지정한다.
메서드 - HTTP를 사용하여 Rest API를 구현한다. HTTP 메서드는 리소스에 수행해야 하는 작업을 서버에 알려준다.
HTTP 헤더 - 요청 헤더는 클라이언트와 서버 간 교환되는 메타 데이터이다.
/users/{id}
의 경우 {id}
가 경로 파라미터/users?role=admin
혹은 /board?offset=100&limit=50
같은 것.GET
- 리소스를 조회하는 메서드. 서버의 상태를 변경시키지 않으므로 멱등하다. 여러 번 요청하더라도 결과가 같다.
POST
- 새로운 리소스를 생성하거나 기존 리소스에 데이터를 추가하는 메서드. 서버의 상태를 변경시키므로 안전하지 않고 멱등하지 않다. 요청 바디에 데이터를 포함한다.
PUT
- 기존의 리소스를 전체적으로 수정하거나 새로운 리소스를 생성. 요청 바디에 데이터를 포함한다. 멱등x
PATCH
- 기존의 리소스를 부분적으로 수정하는 메서드. 수정할 데이터만 요청 바디에 포함할 수 있다. 멱등x
DELETE
- 기존의 리소스를 삭제하는 메서드. 동일한 요청을 여러 번 수행해도 결과가 같으므로 멱등하다. 하지만 서버 상태를 변경시킬 수 있기 때문에 안전하지 않다.
HTTP 프로토콜을 사용하여 웹 서버와 통신할 수 있도록 도와주는 소프트웨어 라이브러리
브라우저에서 제공하는 가장 기본적인 HTTP 클라이언트 라이브러리. 하지만 콜백 함수 기반의 코드가 복잡해서 최근엔 거의 쓰지 않는다.
브라우저에서 제공하는 라이브러리.
아직 모든 브라우저에서 완벽하게 지원되지 않아 호환성 문제가 있을 수 있다.
node.js와 브라우저에서 사용할 수 있는 외부 라이브러리. jQuery 라이브러리에 종속적이므로 이를 먼저 로드해야 한다.
가상 돔을 사용하는 라이브러리나 프레임워크가 등장한 후부터 상대적으로 무겁고 비효율적인 jQuery의 사용이 줄어들었다.
Promise 기반의 외부 HTTP 클라이언트 라이브러리. Fetch API와 비슷한 기능을 제공한다.
Fetch API의 기능 외에 추가로 제공하는 고급 기능에는 요청 중단이나 진행 상황 보고와 같은 기능이 있다.
HTTP 에러 상태에 대해 프로미스를 거부하기 때문에 에러 처리가 쉽다.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300) {
console.log(this.responseText);
} else {
console.error(this.statusText);
}
}
};
xhr.onerror = function() {
console.error(this.statusText);
};
xhr.open("GET", "https://example.com/posts/1", true);
xhr.send();
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300) {
console.log(this.responseText);
} else {
console.error(this.statusText);
}
}
};
xhr.onerror = function() {
console.error(this.statusText);
};
xhr.open("POST", "https://example.com/posts", true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}));
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300) {
console.log(this.responseText);
} else {
console.error(this.statusText);
}
}
};
xhr.onerror = function() {
console.error(this.statusText);
};
xhr.open("PUT", "https://example.com/posts/1", true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(JSON.stringify({
id: 1,
title: 'foo',
body: 'bar',
userId: 1
}));
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status >= 200 && this.status < 300) {
console.log(this.responseText);
} else {
console.error(this.statusText);
}
}
};
xhr.onerror = function() {
console.error(this.statusText);
};
xhr.open("DELETE", "https://example.com/posts/1", true);
xhr.send();
fetch('https://example.com/posts/1')
.then(response => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
})
.then(json => console.log(json))
.catch(error => console.error(error))
fetch('https://example.com/posts', {
method: 'POST',
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}),
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
})
.then(response => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
})
.then(json => console.log(json))
.catch(error => console.error(error))
fetch('https://example.com/posts/1', {
method: 'PUT',
body: JSON.stringify({
id: 1,
title: 'foo',
body: 'bar',
userId: 1
}),
headers: {
'Content-type': 'application/json; charset=UTF-8'
}
})
.then(response => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
})
.then(json => console.log(json))
.catch(error => console.error(error))
fetch('https://example.com/posts/1', {
method: 'DELETE'
})
.then(response => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
})
.then(json => console.log(json))
.catch(error => console.error(error))
const $ = require('jquery');
$.ajax({
url: 'https://example.com/posts/1',
type: 'GET',
success: function(data) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error(textStatus);
}
});
const $ = require('jquery');
$.ajax({
url: 'https://example.com/posts',
type: 'POST',
data: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
}),
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(data) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error(textStatus);
}
});
const $ = require('jquery');
$.ajax({
url: 'https://example.com/posts/1',
type: 'PUT',
data: JSON.stringify({
id: 1,
title: 'foo',
body: 'bar',
userId: 1
}),
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(data) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error(textStatus);
}
});
const $ = require('jquery');
$.ajax({
url: 'https://example.com/posts/1',
type: 'DELETE',
success: function(data) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown) {
console.error(textStatus);
}
});
const axios = require('axios');
axios.get('https://example.com/posts/1')
.then(response => console.log(response.data))
.catch(error => console.error(error))
const axios = require('axios');
axios.post('https://example.com/posts', {
title: 'foo',
body: 'bar',
userId: 1
})
.then(response => console.log(response.data))
.catch(error => console.error(error))
const axios = require('axios');
axios.put('https://example.com/posts/1', {
title: 'foo',
body: 'bar',
userId: 1
})
.then(response => console.log(response.data))
.catch(error => console.error(error))
const axios = require('axios');
axios.delete('https://example.com/posts/1')
.then(response => console.log(response.data))
.catch(error => console.error(error))