Notice
Recent Posts
Recent Comments
Link
꾸준한 개발일기
Javascript:: REST API란? (JSON Server 사용하여 실습해보기) 본문
반응형
REST는 HTTP를 기반으로 클라이언트가 서버의 리소스에 접근하는 방식을 규정한 아키텍처이고, REST API는 REST를 기반으로 서비스 API를 구현한 것을 의미한다.
1. REST API의 구성
- REST API는 자원, 행위, 표현의 3가지 요소로 구성된다.
구성요소 | 내용 | 표현 방법 |
자원 | 자원 | URI(엔드포인트) |
행위 | 자원에 대한 행위 | HTTP 요청 메서드 |
표현 | 자원에 대한 행위의 구체적 내용 | 페이로드 |
* 페이로드란?
- 전송되는 데이터를 의미
- 데이터를 전송할 때 헤더와 메타데이터, 에러 체크 비트 등과 같은 다양한 요소들을 함께 보내어 데이터 전송의 효율과 안정성을 높이는데 이 때, 보내고자 하는 데이터 자체를 페이로드라 함
2. REST API 설계 원칙
1. URI는 리소스를 표현해야 한다.
- 리소스를 식별할 수 있는 이름은 동사보다는 명사를 사용함
#bad
GET /getTodos/1
GET /todos/show/1
#good
GET /todos/1
2. 리소스에 대한 행위는 HTTP 요청 메서드로 표현한다.
HTTP 요청 메서드 | 종류 | 목적 | 페이로드 |
GET | index/retrieve | 모든/특정 리소스 취득 | X |
POST | create | 리소스 생성 | O |
PUT | replace | 리소스의 전체 교체 | O |
PATCH | modify | 리소스의 일부 수정 | O |
DELETE | delete | 모든/특정 리소스 삭제 | X |
- HTTP 요청 메서드는 클라이언트가 서버에게 요청의 종류와 목적(리소스에 대한 행위)을 알리는 방법임
# bad
GET /todos/delete/1
# good
DELETE /todos/1
- 리소스에 대한 행위는 HTTP 요청 메서드를 통해 표현하며 URI에 표현하지 않음
3. JSON Server(가상 REST API 서버)를 이용한 REST API 실습
3.1 JSON 서버 설치
$ mkdir json-server-exam && cd json-server-exam
$ npm init -y
$ npm install json-server --save-dev
- JSON 서버는 json 파일을 사용하여 가상 REST API 서버를 구축할 수 있는 툴임
3.2 db.json 파일 생성
{
"todos": [
{
"id": 1,
"content": "HTML",
"completed": true
},
{
"id": 2,
"content": "CSS",
"completed": false
},
{
"id": 3,
"content": "JavaScript",
"completed": true
},
]
}
- 프로젝트 루트 폴터(/json-server-exam)에 다음과 같이 db.json 파일을 생성함
- db.json 파일은 리소스를 제공하는 데이터베이스 역할을 함
3.3 JSON 서버 실행
## 기본 포트(3000) 사용/ watch 옵션 적용
$ json-server --watch db.json
- json server 실행
- db.json 파일의 변경을 감지하게 하려면 watch 옵션 추가
"scripts": {
...생략... ,
"start": "json-server --watch db.json" // 추가
},
- 간편한 서버 실행을 위한 package.json 파일 수정
$ npm start
- 서버 실행 명령어 입력
3.4 GET 요청
1. JSON Server의 루트 폴더(/json-server-exam)에 public 폴더 생성
2. JSON Server 재실행
3. public 폴더에 get_index.html 추가
<!DOCTYPE html>
<html>
<body>
<pre></pre>
<script>
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// todos 리소스에서 모든 todo를 취득(index)
xhr.open('GET', '/todos');
// HTTP 요청 전송
xhr.send();
// load 이벤트는 요청이 성공적으로 완료된 경우 발생함
xhr.onload = () => {
if(xhr.status === 200) {
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태다.
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
</body>
</html>
4. http://localhost:3000/get_index.html로 접속
- todos 리소스에서 모든 todo를 취득(index)함
5. public 폴더에 다음 get_retrieve.html을 추가
<!DOCTYPE html>
<html>
<body>
<pre></pre>
<script>
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// todos 리소스에서 id를 사용하여 특정 todo를 취득(retrieve)
xhr.open('GET', '/todos/1');
// HTTP 요청 전송
xhr.send();
// load 이벤트는 요청이 성공적으로 완료된 경우 발생함
xhr.onload = () => {
if(xhr.status === 200) {
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태다.
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
</body>
</html>
6. http://localhost:3000/get_retrieve.html로 접속
- id를 사용하여 특정 todo를 취득(retrieve)함
3.5 POST 요청
1. public 폴더에 다음 post.html을 추가
<!DOCTYPE html>
<html>
<body>
<pre></pre>
<script>
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// todos 리소스에 새로운 todo를 생성함
xhr.open('POST', '/todos');
// 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정
xhr.setRequestHeader('context-type', 'application/json');
// HTTP 요청 전송
// 새로운 todo를 생성하기 위해 페이로드를 서버에 전송해야 함
xhr.send(JSON.stringify({id: 4, content: 'Angular', completed: false}));
// load 이벤트는 요청이 성공적으로 완료된 경우 발생함
xhr.onload = () => {
if(xhr.status === 200 || xhr.status === 201) {
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태다.
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
</body>
</html>
2. http://localhost:3000/post.html로 접속
- todos 리소스에 새로운 todo를 생성함
3.6 PUT 요청
1. public 폴더에 다음 put.html을 추가
<!DOCTYPE html>
<html>
<body>
<pre></pre>
<script>
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// todos 리소스에서 id로 todo를 특정하여 id를 제외한 리소스 전체를 교체함
xhr.open('PUT', '/todos/4');
// 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정
xhr.setRequestHeader('context-type', 'application/json');
// HTTP 요청 전송
// 새로운 todo를 생성하기 위해 페이로드를 서버에 전송해야 함
xhr.send(JSON.stringify({ id: 4, content: 'React', completed: true }));
// load 이벤트는 요청이 성공적으로 완료된 경우 발생함
xhr.onload = () => {
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태다.
if(xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
</body>
</html>
2. http://localhost:3000/put.html로 접속
- 특정 리소스 전체를 교체할 때 사용함
3.7 PATCH 요청
1. public 폴더에 다음 patch.html을 추가
<!DOCTYPE html>
<html>
<body>
<pre></pre>
<script>
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// todos 리소스의 id로 todo를 특정하여 completed만 수정
xhr.open('PATCH', '/todos/4');
// 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정
xhr.setRequestHeader('context-type', 'application/json');
// HTTP 요청 전송
// 새로운 todo를 생성하기 위해 페이로드를 서버에 전송해야 함
xhr.send(JSON.stringify({ completed: false }));
// load 이벤트는 요청이 성공적으로 완료된 경우 발생함
xhr.onload = () => {
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태다.
if(xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
</body>
</html>
2. http://localhost:3000/patch.html로 접속
- 특정 리소스의 일부를 수정할 때 사용함
3.8 DELETE 요청
1. public 폴더에 다음 delete.html을 추가
<!DOCTYPE html>
<html>
<body>
<pre></pre>
<script>
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// todos 리소스에서 id를 사용하여 todo를 삭제함
xhr.open('DELETE', '/todos/4');
// HTTP 요청 전송
xhr.send();
// load 이벤트는 요청이 성공적으로 완료된 경우 발생함
xhr.onload = () => {
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태다.
if(xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
}
</script>
</body>
</html>
2. http://localhost:3000/delete.html로 접속
- todos 리소스에서 id를 사용하여 todo를 삭제함
참고자료
- 모던 자바스크립트 Deep Dive: 자바스크립트의 기본 개념과 동작 원리 (이웅모 저)
반응형
'JS > JavaScript' 카테고리의 다른 글
Javascript:: Babel과 Webpack을 이용한 ES6+/ES.NEXT 개발 환경 구축 (1) | 2022.12.04 |
---|---|
Javascript:: Math란? (0) | 2022.11.07 |
Javascript:: 클로저란? (1) | 2022.10.30 |
Javascript:: 객체의 키와 값을 배열로 얻기(Object.keys(), Object.values(), filter, map으로 새로운 데이터 생성 etc.) (0) | 2022.10.24 |
Javascript:: 실행 컨텍스트(2) (0) | 2022.10.22 |
Comments