44장 REST API
44.1 REST API의 구성
- 자원, 행위, 표현의 3가지 요소로 구성
44.2 REST API 설계 원칙
- URI는 리소스를 표현하는데 집중, 행위에 대한 정의는 HTTP 요청 메서드를 통해 하는 것이 RESTful API설계의 중심 규칙
44.3 JSON Server를 이용한 REST API 실습
- JSON Server를 사용해 가상 REST API 서버를 구축하여 HTTP 요청을 전송하고 응답을 받는 실습을 해보자
44.3.1 JSON Server 설치
-
JSON Server는 json 파일을 사용하여 가상 REST API 서버를 구축할 수 있는 툴이다
-
우선 npm을 이용해 JSON Server를 설치하자. 터미널에 아래 설치 mkdir json-server-exam && cd json-server-exam npm init -y npm install json-server–save-dev
44.3.2 db.json 파일 생성(44-01)
-
프로젝트 루트 폴더(/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 실행(44-02)
-
터미널에서 다음을 입력. watch는 db.json 파일 변경을 감지 1.기본 포트(3000) 사용 / watch 옵션 적용 json-server –watch db.json 2.포트를 만약 변경하려면 port 옵션 추가 json-server –watch db.json –port 5000
-
위와 같이 매번 입력은 번거로우니 package.json 파일의 scripts를 다음과 같이 수정해서 JSON Server 실행하자
-
실행은 터미널에서 다음 코드 입력 npm start
{
"name": "json-server-exam",
"version": "1.0.0",
"scripts": {
"start": "json-server --watch db.json"
},
"devDependencies": {
"json-server": "^0.16.1"
}
}
44.3.4 GET 요청(44-03)
-
todos 리소스에서 모든 todo를 취득(index)한다
-
JSON Server의 루트 폴더에 public 폴더 생성후 JSON Server를 중단하고 재실행. 그리고 그 폴더에 get_index.html을 추가하고 브라우저에서 localhost:3000/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 = () => {
// status 프로퍼티 값이 200이면 정상적으로 응답된 상태다.
if (xhr.status === 200) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
};
</script>
</body>
</html>
44-04
-
위 예제에선 todos로 전체 데이터를 다 가져왔음(db.json내용 의미)
-
아래 예제에선 todos에 id 이용해서 특정 todo만 취득해보겠음. 마찬가지로 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'); // "id" : 1 내용 취득(HTML이였음)
// 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>
44.3.5 POST 요청(44-05)
-
todos 리소스에 새로운 todo를 생성. POST 요청은 setRequestHeader 메서드를 사용해 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 지정
-
마찬가지로 post.html 추가해서 접속하자
-
결과로 “id”: 4 로 만든부분 출력함
<!DOCTYPE html>
<html>
<body>
<pre></pre>
<script>
// XMLHttpRequest 객체 생성
const xhr = new XMLHttpRequest();
// HTTP 요청 초기화
// todos 리소스에 새로운 todo를 생성
xhr.open('POST', '/todos');
// 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정
xhr.setRequestHeader('content-type', 'application/json');
// HTTP 요청 전송
// 새로운 todo를 생성하기 위해 페이로드를 서버에 전송해야 한다.
xhr.send(JSON.stringify({ id: 4, content: 'Angular', completed: false }));
// load 이벤트는 요청이 성공적으로 완료된 경우 발생한다.
xhr.onload = () => {
// status 프로퍼티 값이 200(OK) 또는 201(Created)이면 정상적으로 응답된 상태다.
if (xhr.status === 200 || xhr.status === 201) {
document.querySelector('pre').textContent = xhr.response;
} else {
console.error('Error', xhr.status, xhr.statusText);
}
};
</script>
</body>
</html>
44.3.6 PUT 요청(44-06)
-
todos 리소스에 id로 todo를 특정하여 id를 제외한 리소스 전체를 교체. PUT 요청은 setRequestHeader 메서드를 사용해 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 지정
-
결과로 “id”: 4 내용중 Angular가 React로 출력되고, 나머지 id들은 없음
<!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('content-type', 'application/json');
// HTTP 요청 전송
// 리소스 전체를 교체하기 위해 페이로드를 서버에 전송해야 한다.
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>
44.3.7 PATCH 요청(44-07)
-
todos 리소스에 id로 todo를 특정하여 completed만 수정. PATCH 요청은 setRequestHeader 메서드를 사용해 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 지정
-
출력 결과로 “id” : 4만 출력되고 completed 값이 true에서 false
<!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('content-type', 'application/json');
// HTTP 요청 전송
// 리소스를 수정하기 위해 페이로드를 서버에 전송해야 한다.
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>
44.3.8 DELETE 요청(44-08)
-
todos 리소스에서 id를 사용해 todo를 삭제
-
출력(document)엔 빈 객체
<!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>
댓글남기기