Skip to content

Latest commit

Β 

History

History
436 lines (336 loc) Β· 12.8 KB

File metadata and controls

436 lines (336 loc) Β· 12.8 KB

REST API

REST API 의 탄생
REST λŠ” 2000λ…„ λ°œν‘œ λ‹Ήμ‹œμ˜ 웹이 HTTP λ₯Ό μ œλŒ€λ‘œ μ‚¬μš©ν•˜μ§€ λͺ»ν•˜κ³  μžˆλŠ” 상황을 보고 HTTP 의 μž₯점을 μ΅œλŒ€ν•œ ν™œμš©ν•  수 μžˆλŠ” μ•„ν‚€ν…μ²˜λ‘œμ„œ μ†Œκ°œλ˜μ—ˆλ‹€.
REST λŠ” HTTP ν”„λ‘œν† μ½œμ„ μ˜λ„μ— 맞게 λ””μžμΈν•˜λ„λ‘ μœ λ„ν•˜κ³  μžˆλ‹€.
REST 의 κΈ°λ³Έ 원칙을 μ„±μ‹€νžˆ 지킨 μ„œλΉ„μŠ€ λ””μžμΈμ„ "RESTful😴" 이라고 ν‘œν˜„ν•œλ‹€.

REST λŠ” REpresentational State Transfer (μƒνƒœ 전이 ν‘œν˜„) 의 μ•½μžλ‘œ μ›Ή μ„œλΉ„μŠ€ κ°„μ˜ 톡신을 μœ„ν•œ μ†Œν”„νŠΈμ›¨μ–΄ μ•„ν‚€ν…μ²˜ μŠ€νƒ€μΌ 쀑 ν•˜λ‚˜μ΄λ‹€. μžμ›μ„ ν‘œν˜„ν•˜κ³  μƒνƒœ 전이λ₯Ό 톡해 데이터λ₯Ό μ£Όκ³ λ°›λŠ” 방식을 μ˜λ―Έν•œλ‹€. λ‹€μ–‘ν•œ ν΄λΌμ΄μ–ΈνŠΈ μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό μ„œλ²„ κ°„μ˜ 데이터 톡신을 κ°€λŠ₯ν•˜κ²Œ ν•œλ‹€.

API λŠ” Application Programming Interface 의 μ•½μžλ‘œ, μ‘μš© ν”„λ‘œκ·Έλž¨ κ°„μ˜ μƒν˜Έμž‘μš©μ„ μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ˜λ―Έν•œλ‹€. λ‹€λ₯Έ μ‘μš© ν”„λ‘œκ·Έλž¨μ΄λ‚˜ μ„œλΉ„μŠ€μ˜ κΈ°λŠ₯κ³Ό 데이터에 μ ‘κ·Όν•  수 μžˆλ„λ‘ μ •μ˜λœ λ©”μ„œλ“œ, κ·œμ•½, 도ꡬ λ“±μ˜ 집합이닀. API λŠ” λ‹€μ–‘ν•œ ν˜•νƒœλ‘œ 제곡될 수 μžˆλŠ”λ°, REST API λŠ” μ›Ή μ„œλΉ„μŠ€μ—μ„œ μ‚¬μš©λ˜λŠ” 것 쀑 ν•˜λ‚˜λ‘œ, μƒνƒœ 전이 ν‘œν˜„ ( REST ) 의 원칙을 λ”°λ₯΄λŠ” API 이닀.

πŸ“’πŸ’ REST λŠ” HTTP λ₯Ό 기반으둜 ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ˜ λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•˜λŠ” 방식을 κ·œμ •ν•œ μ•„ν‚€ν…μ²˜μ΄κ³ , REST API λŠ” REST λ₯Ό 기반으둜 μ„œλΉ„μŠ€ API λ₯Ό κ΅¬ν˜„ν•œ 것을 μ˜λ―Έν•œλ‹€.


44.1 REST API 의 ꡬ성

REST API λŠ” μžμ› resource, ν–‰μœ„ verb, ν‘œν˜„ representations 의 3κ°€μ§€ μš”μ†Œλ‘œ κ΅¬μ„±λœλ‹€. 자체 ν‘œν˜„ ꡬ쑰둜 κ΅¬μ„±λ˜μ–΄ REST API 만으둜 HTTP μš”μ²­μ˜ λ‚΄μš©μ„ 이해할 수 μžˆλ‹€.

ꡬ성 μš”μ†Œ λ‚΄μš© ν‘œν˜„ 방법 μ˜ˆμ‹œ
μžμ›
Resource
μžμ› URI(μ—”λ“œν¬μΈνŠΈ) μ‚¬μš©μž 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” μžμ›μ— μ ‘κ·Όν•˜κΈ° μœ„ν•¨
/users: μ‚¬μš©μž 정보에 μ ‘κ·Ό
/users/1: IDκ°€ 1인 μ‚¬μš©μž 정보에 μ ‘κ·Ό
ν–‰μœ„
Verb
μžμ›μ— λŒ€ν•œ ν–‰μœ„ HTTP μš”μ²­ λ©”μ„œλ“œ GET,POST,PUT,DELETE
ν‘œν˜„
Representation
μžμ›μ— λŒ€ν•œ ν–‰μœ„μ˜ ꡬ체적 λ‚΄μš© νŽ˜μ΄λ‘œλ“œ μžμ›μ— λŒ€ν•œ ν–‰μœ„μ˜ ꡬ체적인 λ‚΄μš©μ„ λ‹΄λŠ” 데이터

44.2 REST API 의 섀계 원칙

RESTful😴 ν•˜κΈ° μœ„ν•œ κ·œμΉ™ πŸ’

  1. URI λŠ” λ¦¬μ†ŒμŠ€λ₯Ό ν‘œν˜„ν•˜λŠ”λ° μ§‘μ€‘ν•˜κ³ 
  2. ν–‰μœ„μ— λŒ€ν•œ μ •μ˜λŠ” HTTP μš”μ²­ λ©”μ„œλ“œλ₯Ό 톡해 ν•œλ‹€.

πŸ“Œ 1. URI λŠ” λ¦¬μ†ŒμŠ€λ₯Ό ν‘œν˜„ν•΄μ•Ό ν•œλ‹€.

λ¦¬μ†ŒμŠ€λ₯Ό 식별할 수 μžˆλŠ” 이름은 λ™μ‚¬λ³΄λ‹€λŠ” λͺ…사λ₯Ό μ‚¬μš©ν•œλ‹€. 이름에 get 같은 ν–‰μœ„μ— λŒ€ν•œ ν‘œν˜„μ΄ λ“€μ–΄κ°€μ„œλŠ” μ•ˆ λœλ‹€.

# BAD πŸ˜žπŸ‘Ž
GET / getTodos/1

# GOOD πŸ˜ŠπŸ‘
GET / todos/1

πŸ“Œ 2. λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ ν–‰μœ„λŠ” HTTP μš”μ²­ λ©”μ„œλ“œλ‘œ ν‘œν˜„ν•œλ‹€.

HTTP μš”μ²­ λ©”μ„œλ“œλŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλ²„μ—κ²Œ μš”μ²­μ˜ μ’…λ₯˜μ™€ λͺ©μ μ„ μ•Œλ¦¬λŠ” 방법이닀. 주둜 5κ°€μ§€ μš”μ²­ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ CRUD λ₯Ό κ΅¬ν˜„ν•œλ‹€.

HTTP μš”μ²­ λ©”μ„œλ“œ μ’…λ₯˜ λͺ©μ  νŽ˜μ΄λ‘œλ“œ
GET index/retrieve λͺ¨λ“ /νŠΉμ • λ¦¬μ†ŒμŠ€ 취득 X
POST create λ¦¬μ†ŒμŠ€ 생성 O
PUT replace λ¦¬μ†ŒμŠ€μ˜ 전체 ꡐ체 O
PATCH modify λ¦¬μ†ŒμŠ€μ˜ 일뢀 μˆ˜μ • O
DELETE delete λͺ¨λ“ /νŠΉμ • λ¦¬μ†ŒμŠ€ μ‚­μ œ X

retrieve : νŠΉμ • λ¦¬μ†ŒμŠ€λ₯Ό κ°€μ Έμ˜€λŠ” 것 νŽ˜μ΄λ‘œλ“œ : μš”μ²­μ˜ 본문에 λ‹΄κΈ°λŠ” 데이터

λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ ν–‰μœ„λŠ” HTTP μš”μ²­ λ©”μ„œλ“œλ₯Ό 톡해 ν‘œν˜„ν•˜λ©° URI 에 ν‘œν˜„ν•˜μ§€ μ•ŠλŠ”λ‹€.

# 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 μ„€μΉ˜

mksir json-server-exam && json-server-exam
pnpm init-y
pnpm install json-server--save-dev


44.3.2 db.json 파일 생성

ν”„λ‘œμ νŠΈ 루트 폴더에 db.json νŒŒμΌμ„ μƒμ„±ν•œλ‹€. λ¦¬μ†ŒμŠ€λ₯Ό μ œκ³΅ν•˜λŠ” λ°μ΄ν„°λ² μ΄μŠ€ 역할을 ν•œλ‹€.

44-01

{
  "todos": [
    {
      "id": 1,
      "content": "HTML",
      "completed": true
    },
    {
      "id": 2,
      "content": "CSS",
      "completed": false
    },
    {
      "id": 3,
      "content": "Javascript",
      "completed": true
    }
  ]
}

44.3.3 JSON Server μ‹€ν–‰

$ json-server--watch db.json
db.json 파일의 변경을 κ°μ§€ν•˜κΈ° μœ„ν•΄ watch μ˜΅μ…˜μ„ μΆ”κ°€ν•œλ‹€.

$ json-server--watch db.json --port 5000
κΈ°λ³Έ 포트 (3000) 변경을 μœ„ν•΄ port μ˜΅μ…˜μ„ μΆ”κ°€ν–ˆλ‹€.

맀번 λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•˜λŠ” λ²ˆκ±°λ‘œμ›€μ„ 덜기 μœ„ν•΄ package.json 파일의 scripts λ₯Ό μ•„λž˜μ™€ 같이 μˆ˜μ •ν•œλ‹€.

44-02

{
  "name": "json-server-exam",
  "version": "1.0.0",
  "scripts": {
    "start": "json-server --watch db.json"
  },
  "devDependencies": {
    "json-server": "^0.16.1"
  }
}

κ·Έ ν›„ ν„°λ―Έλ„μ—μ„œ pnpm start λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•΄ JSON Server λ₯Ό μ‹€ν–‰ν•œλ‹€.


44.3.4 GET μš”μ²­

todos λ¦¬μ†ŒμŠ€μ—μ„œ λͺ¨λ“  todo λ₯Ό 취득(index) ν•œλ‹€.

JSON Server 의 루트 폴저에 public 폴더λ₯Ό μƒμ„±ν•˜κ³  JSON Server λ₯Ό μ€‘λ‹¨ν•œ ν›„ μž¬μ‹€ν–‰ν•œλ‹€. 그리고 public 폴더에 μ•„λž˜ get_index.html 을 μΆ”κ°€ν•˜κ³  λΈŒλΌμš°μ €μ—μ„œ http:/localhost:3000/get_index.html 둜 μ ‘μ†ν•œλ‹€.

44-03

<!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>

todos λ¦¬μ†ŒμŠ€μ—μ„œ id λ₯Ό μ‚¬μš©ν•˜μ—¬ νŠΉμ • todo λ₯Ό 취득(retrieve)ν•œλ‹€. public 폴더에 μ•„λž˜ get_retrieve.html 을 μΆ”κ°€ν•˜κ³  λΈŒλΌμš°μ €μ—μ„œ http://localhost:3000?get_retrieve.html 둜 μ ‘μ†ν•œλ‹€.

44-04

<!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 = () => {
      // status ν”„λ‘œνΌν‹° 값이 200이면 μ •μƒμ μœΌλ‘œ μ‘λ‹΅λœ μƒνƒœλ‹€.
      if (xhr.status === 200) {
        document.querySelector('pre').textContent = xhr.response;
      } else {
        console.error('Error', xhr.status, xhr.statusText);
      }
    };
  </script>
</body>
</html>
{
  "id": 1,
  "content": "HTML",
  "completed": true
}

μœ„μ˜ 정보가 보이게 λœλ‹€.


44.3.5 POST μš”μ²­

todos λ¦¬μŠ€νŠΈμ— μƒˆλ‘œμš΄ todo λ₯Ό μƒμ„±ν•œλ‹€. setRequestHeader λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ μ„œλ²„λ‘œ 전솑할 νŽ˜μ΄λ‘œλ“œμ˜ MIME νƒ€μž…μ„ μ§€μ •ν•΄μ•Ό ν•œλ‹€.

public 폴더에 μ•„λž˜ post.html 을 μΆ”κ°€ν•˜κ³  λΈŒλΌμš°μ €μ—μ„œ http://localhost:3000/post.html 둜 μ ‘μ†ν•œλ‹€.

44-05 : post.html

<!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>
{
  "id": 4,
  "content": "Angular",
  "completed": false
}

μœ„μ™€ 같이 정보가 λ“€μ–΄κ°€κ²Œ λœλ‹€.


44.3.6 PUT μš”μ²­

PUT 은 νŠΉμ • λ¦¬μ†ŒμŠ€ 전체λ₯Ό ꡐ체할 λ•Œ μ‚¬μš©ν•œλ‹€. todos λ¦¬μ†ŒμŠ€μ—μ„œ id 둜 todo λ₯Ό νŠΉμ •ν•˜μ—¬ id λ₯Ό μ œμ™Έν•œ λ¦¬μ†ŒμŠ€ 전체λ₯Ό κ΅μ²΄ν•œλ‹€. PUT μš”μ²­μ‹œμ—λŠ” setRequestHeader λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ μ„œλ²„λ‘œ 전솑할 νŽ˜μ΄λ‘œλ“œμ˜ MIME νƒ€μž…μ„ μ§€μ •ν•΄μ•Ό ν•œλ‹€.

public 폴더에 μ•„λž˜ put.html 을 μΆ”κ°€ν•˜κ³  λΈŒλΌμš°μ €μ—μ„œ http://localhost:3000/put.html둜 μ ‘μ†ν•œλ‹€.

44-06

<!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>
{
  "id": 4,
  "content": "React",
  "completed": true
}

μœ„μ™€ 같은 정보λ₯Ό 확인할 수 μžˆλ‹€.


44.3.7 PATCH μš”μ²­

PATCH λŠ” νŠΉμ • λ¦¬μ†ŒμŠ€μ˜ 일뢀λ₯Ό μˆ˜μ •ν•  λ•Œ μ‚¬μš©ν•œλ‹€. λ‹€μŒ μ˜ˆμ œμ—μ„œλŠ” todos λ¦¬μ†ŒμŠ€μ˜ id둜 todo λ₯Ό νŠΉμ •ν•˜μ—¬ completed 만 μˆ˜μ •ν•œλ‹€. PATCH μš”μ²­ μ‹œμ—λŠ” setRequestHeader λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μš”μ²­ λͺΈμ²΄μ— λ‹΄μ•„ μ„œλ²„λ‘œ 전솑할 νŽ˜μ΄λ‘œλ“œμ˜ MIME νƒ€μž…μ„ μ§€μ •ν•΄μ•Ό ν•œλ‹€.

public 폴더에 μ•„λž˜ patch.html을 μΆ”κ°€ν•˜κ³  λΈŒλΌμš°μ €μ—μ„œ http://localhost:3000/patch.html둜 μ ‘μ†ν•œλ‹€.

44-07

<!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>
{
  "id": 4,
  "content": "React",
  "completed": false
}

μœ„μ™€ 같이 completed 의 정보가 false 둜 바뀐 것을 확인할 수 μžˆλ‹€.


44.3.8 DELETE μš”μ²­

todos λ¦¬μ†ŒμŠ€μ—μ„œ id λ₯Ό μ‚¬μš©ν•˜μ—¬ todo λ₯Ό μ‚­μ œν•œλ‹€. public 폴더에 λ‹€μŒ delete.html을 μΆ”κ°€ν•˜κ³  λΈŒλΌμš°μ €μ—μ„œ http://localhost:3000/delete.html둜 μ ‘μ†ν•œλ‹€.

44-08

<!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>
{}

μœ„μ™€ 같이 정보가 μ‚­μ œλ˜μ—ˆλ‹€.