44장 REST API
- REST는 HTTP를 기반으로 클라이어트가 서버의 리소스에 접근하는 방식을 규정한 아키텍처고, REST API는 REST를 기반으로 서비스 API를 구현한 것을 의미한다.
44.1 REST API의 구성
- REST API는 자원, 행위, 표현의 3가지 요소로 구성된다.
- 자원 : 자원 / URI
- 행위 : 자원에 대한 행위 / HTTP 요청 메서드
- 표현 : 자원에 대한 행위와 구체적 내용 / 페이로드
44.2 REST API 설계 원칙
- URI는 리소스를 표현해야 한다.
- URI는 리소스를 표현하는데 중점을 두어야 한다. 리소스를 식별할 수 있는 이름은 동사보다는 명사를 사용한다.
# bad
GET /getTodos/1
GET /todos/show/1
# good
GET /todos/1
- 리소스에 대한 행위는 HTTP 요청 메서드로 표현한다.
- HTTP 요청 메서드를 사용하여 CRUD를 구현한다.
- GET/POST/PUT/PATCH/DELETE
# bad
GET /todos/delete/1
# good
DELETE /todos/1
44.3 JSON Server를 이용한 REST API 실습
- JSON Server를 사용해 가상 REST API 서버를 구축하여 HTTP 요청을 전송하고 응답을 받는 실습
44.3.1 JSON Server 설치
- JSON Server는 json 파일을 사용하여 가상 REST API 서버를 구축할 수 있는 툴이다.
mkdir json-server-exam && cd json-server-exam
npm init -y
npm install json-server --save-dev
44.3.2 db.json 파일 생성
- 프로젝트 루트 폴더(/json-server-exam)에 db.json 파일을 생성한다.
- db.json 파일은 리소스를 제공하는 데이터베이스 역할을 한다.
{
"todos" [
{
"id": 1,
"content": "HTML",
"completed": true,
},
{
"id": 2,
"content": "CSS",
"completed": false,
},
{
"id": 3,
"content": "JavaScript",
"completed": true,
},
]
}
44.3.3 JSON Server 실행
- 터미널에서 실행.
- 매번 명령어 입력이 번거로우면 package.json 파일의 scripts를 수정하여 실행하면 편하다.
## 기본 포트(3000) 사용 / watch 옵션 적용
json-server --watch db.json
## 포트 변경 / watch 옵션 적용
json-server --watch db.json --port 5000
## package.json
{
"scripts: {
"start": "json-server --watch db.json"
}
}
## package.json 세팅후
npm start
44.3.4 GET 요청
- todos 리소스에서 모든 todo를 취득(index) 한다.
- 루트 폴더(/json-server-exam)에 public 폴더를 생성하고 JSON Server를 중단 후 재 실행한다.
- public 폴더에 get_index.html 을 추가하고, 브라우저에서 http://localhost:3000/get_index.html로 접속한다.
<pre></pre>
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', '/todos');
xhr.open('GET', '/todos/1');
xhr.send();
xhr.onload = () => {
if(xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
44.3.5 POST 요청
<pre></pre>
<script>
const xhr = new XMLHttpRequest();
xhr.open('POST', '/todos');
xhr.setRequestHeader('content-type', 'application/json');
xhr.send(JSON.stringify({id: 4, content: 'Angular', completed: false}));
xhr.onload = () => {
if(xhr.status === 200 || xhr.status === 201) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
44.3.6 PUT 요청
- PUT은 특정 리소스 전체를 교체할 떄 사용.
- PUT 요청 시에는 setRequestHeader 메서드를 사용하여 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정해야 한다.
- public 폴더에 put.html을 추가한다.
<pre></pre>
<script>
const xhr = new XMLHttpRequest();
xhr.open('PUT', '/todos/4');
xhr.setRequestHeader('content-type', 'application/json');
xhr.send(JSON.stringify({id: 4, content: 'React', completed: true}));
xhr.onload = () => {
if(xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
44.3.7 PATCH 요청
- PATCH는 특정 리소스의 일부를 수정할 때 사용한다.
- PATCH 요청 시에는 setRequestHeader 메서드를 사용하여 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정해야 한다.
- public 폴더에 patch.html 을 추가한다.
<pre></pre>
<script>
const xhr = new XMLHttpRequest();
xhr.open('PATCH', '/todos/4');
xhr.setRequestHeader('content-type', 'application/json');
xhr.send(JSON.stringify({completed: false}));
xhr.onload = () => {
if(xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
44.3.8 DELETE 요청
- todos 리소스에서 id를 사용하여 todo를 삭제한다.
- public 폴더에 다음 delete.html을 추가한다.
<pre></pre>
<script>
const xhr = new XMLHttpRequest();
xhr.open('DELETE', '/todos/4');
xhr.send();
xhr.onload = () => {
if(xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>