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>

댓글남기기