ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

REST API(REpresentational State Transfer)๋ž€?

REST๋Š” HTTP๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์˜ ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ์‹์„ ๊ทœ์ •ํ•œ ์•„ํ‚คํ…์ฒ˜๊ณ , REST API๋Š” REST๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์„œ๋น„์Šค API๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

  • *๋กœ์ด ํ•„๋”ฉ์ด ์ž์‹ ์˜ 2000๋…„ ๋…ผ๋ฌธ์—์„œ ๋ฐœํ‘œ ๋‹น์‹œ ์›น HTTP๋ฅผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๊ณ  ์žˆ๋Š” ์ƒํ™ฉ์„ ๋ณด๊ณ  ์†Œ๊ฐœํ•จ
  • HTTP์˜ ์žฅ์ ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•„ํ‚คํ…์ฒ˜
  • HTTP ํ”„๋กœํ† ์ฝœ์„ ์˜๋„์— ๋งž๊ฒŒ ๋””์ž์ธํ•˜๋„๋ก ์œ ๋„ํ•จ
  • REST์˜ ๊ธฐ๋ณธ ์›์น™์„ ์„ฑ์‹คํžˆ ์ง€ํ‚จ ์„œ๋น„์Šค ๋””์ž์ธ์„ "RESTful"์ด๋ผ๊ณ  ํ‘œํ˜„

*๋กœ์ด ํ•„๋”ฉ : ์•„ํŒŒ์น˜ HTTP ์„œ๋ฒ„ ํ”„๋กœ์ ํŠธ์˜ ๊ณต๋™ ์„ค๋ฆฝ์ž๋กœ HTTP/1.0๊ณผ 1.1์˜ ์ŠคํŽ™ ์ž‘์„ฑ์— ์ฐธ์—ฌํ•จ


REST API์˜ ๊ตฌ์„ฑ

REST API๋Š” ์ž์›(resorce), ํ–‰์œ„(verb), ํ‘œํ˜„(representations)์˜ 3๊ฐ€์ง€ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ REST๋Š” ์ž์ฒด ํ‘œํ˜„ ๊ตฌ์กฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด REST API๋งŒ์œผ๋กœ HTTP ์š”์ฒญ์˜ ๋‚ด์šฉ์„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ตฌ์„ฑ ์š”์†Œ ๋‚ด์šฉ ํ‘œํ˜„ ๋ฐฉ๋ฒ•
์ž์› ์ž์› URL(์—”๋“œํฌ์ธํŠธ)
ํ–‰์œ„ ์ž์›์— ๋Œ€ํ•œ ํ–‰์œ„ HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ
ํ‘œํ˜„ ์ž์›์— ๋Œ€ํ•œ ํ–‰์œ„์˜ ๊ตฌ์ฒด์  ๋‚ด์šฉ ํŽ˜์ด๋กœ๋“œ

REST API์˜ ์„ค๊ณ„ ์›์น™

REST์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ธฐ๋ณธ์ ์ธ ์›์น™์€ 2๊ฐ€์ง€๋กœ, URL๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•˜๊ณ  ํ–‰์œ„์— ๋Œ€ํ•œ ์ •์˜๋Š” HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ•˜๋Š” ๊ฒƒ์ด RESTful API๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ์ค‘์‹ฌ ๊ทœ์น™์ž…๋‹ˆ๋‹ค.

 

1. URL๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ํ‘œํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

URL๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ํ‘œํ˜„ํ•˜๋Š”๋ฐ ์ค‘์ ์„ ๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ์†Œ์Šค๋ฅผ ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฆ„์€ ๋™์‚ฌ๋ณด๋‹ค๋Š” ๋ช…์‚ฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์— get ๊ฐ™์€ ํ–‰์œ„์— ๋Œ€ํ•œ ํ‘œํ˜„์ด ๋“ค์–ด๊ฐ€์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

 

๋”๋ณด๊ธฐ

# bad

GET /getTodos/1

GET /todos/show/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

 

๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ํ–‰์œ„๋Š” HTTP ์š”์ฒญ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํ‘œํ˜„ํ•˜๋ฉฐ URL์— ํ‘œํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฆฌ์†Œ์Šค๋ฅผ ์ทจ๋“ํ•˜๋Š” ๊ฒฝ์šฐ GET, ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒฝ์šฐ DELETE๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ํ–‰์œ„๋ฅผ ๋ช…ํ™•ํžˆ ํ‘œํ˜„ํ•ฉ๋‹ˆ๋‹ค.

 

๋”๋ณด๊ธฐ

# bad

GET /getTodos/delete/1

 

# good

DELETE /todos/1


JSON Server๋ฅผ ์ด์šฉํ•œ REST API ์‹ค์Šต

HTTP ์š”์ฒญ์„ ์ „์†กํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›๊ธฐ ์œ„ํ•ด์„  ์„œ๋ฒ„๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ JSON Server๋ฅผ ์‚ฌ์šฉํ•ด ๊ฐ€์ƒ REST API ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ•˜์—ฌ HTTP ์š”์ฒญ์„ ์ „์†กํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. 

 

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-dever --save-dev

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
    }
  ]
}

 

JSON Server ์‹คํ–‰

ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜์—ฌ JSON Server๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. JSON Server๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ญํ• ์„ ํ•˜๋Š” db.json ํŒŒ์ผ์˜ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด watch ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ํฌํŠธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด port ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

 

๋”๋ณด๊ธฐ

## ๊ธฐ๋ณธ ํฌํŠธ(3000) ์‚ฌ์šฉ / watch ์˜ต์…˜ ์ ์šฉ
json-server --watch db.json

 

## ํฌํŠธ ๋ณ€๊ฒฝ / watch ์˜ต์…˜ ์ ์šฉ

json-server --watch db.json --port 5000

 

์œ„์™€ ๊ฐ™์ด ๋งค๋ฒˆ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ์€ ๋ฒˆ๊ฑฐ๋กœ์šฐ๋‹ˆ package.json ํŒŒ์ผ์˜ scripts๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์—ฌ ํ„ฐ๋ฏธ๋„์—์„œ npm start ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด JSON Server๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

 

GET ์š”์ฒญ

todos ๋ฆฌ์†Œ์Šค์—์„œ ๋ชจ๋“  todo๋ฅผ ์ทจ๋“(index)ํ•ฉ๋‹ˆ๋‹ค.

 

JSON Server์˜ ๋ฃจํŠธ ํด๋”(/json-server-exam)์— public ํด๋”๋ฅผ ์ƒ์„ฑํ•˜๊ณ  JSON Server๋ฅผ ์ค‘๋‹จํ•œ ํ›„ ์žฌ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  public ํด๋”์— ๋‹ค์Œ get_index.html์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ http://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>

todos ๋ฆฌ์†Œ์Šค์—์„œ id๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŠน์ • todo๋ฅผ ์ทจ๋“(retrieve)ํ•˜๊ธฐ ์œ„ํ•ด์„  public ํด๋”์— ๋‹ค์Œ get_retrieve.html์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:3000/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 = () => {
      // status ํ”„๋กœํผํ‹ฐ ๊ฐ’์ด 200์ด๋ฉด ์ •์ƒ์ ์œผ๋กœ ์‘๋‹ต๋œ ์ƒํƒœ๋‹ค.
      if (xhr.status === 200) {
        document.querySelector('pre').textContent = xhr.response;
      } else {
        console.error('Error', xhr.status, xhr.statusText);
      }
    };
  </script>
</body>
</html>

POST ์š”์ฒญ

todos ๋ฆฌ์†Œ์Šค์— ์ƒˆ๋กœ์šด todo๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. POST ์š”์ฒญ ์‹œ์—๋Š” setRequestHeader ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MIME ํƒ€์ž…์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

public ํด๋”์— ๋‹ค์Œ post.html์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:3000/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>

 

PUT ์š”์ฒญ

PUT์€ ํŠน์ • ๋ฆฌ์†Œ์Šค ์ „์ฒด๋ฅผ ๊ต์ฒดํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ์—์„œ๋Š” todos ๋ฆฌ์†Œ์Šค์—์„œ id๋กœ todo๋ฅผ ํŠน์ •ํ•˜์—ฌ id ๊ฐ’์„ ์ œ์™ธํ•œ ๋ฆฌ์†Œ์Šค ์ „์ฒด๋ฅผ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค. PUT ์š”์ฒญ ์‹œ์—๋Š” setRequestHeader ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MIME ํƒ€์ž…์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

public ํด๋”์— ๋‹ค์Œ put.html์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:3000/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('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>

 

PATCH ์š”์ฒญ

PATCH์€ ํŠน์ • ๋ฆฌ์†Œ์Šค ์ผ๋ถ€๋ฅผ ์ˆ˜์ •ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ์—์„œ๋Š” todos ๋ฆฌ์†Œ์Šค์—์„œ id๋กœ todo๋ฅผ ํŠน์ •ํ•˜์—ฌ completed๋งŒ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. PATCH ์š”์ฒญ ์‹œ์—๋Š” setRequestHeader ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ๋ชธ์ฒด์— ๋‹ด์•„ ์„œ๋ฒ„๋กœ ์ „์†กํ•  ํŽ˜์ด๋กœ๋“œ์˜ MIME ํƒ€์ž…์„ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

public ํด๋”์— ๋‹ค์Œ patch.html์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:3000/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('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>

 

DELETE ์š”์ฒญ

todos ๋ฆฌ์†Œ์Šค์—์„œ id๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ todo๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.

 

public ํด๋”์— ๋‹ค์Œ delete.html์„ ์ถ”๊ฐ€ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:3000/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>


[์ถœ์ฒ˜] ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive

https://wikibook.co.kr/mjs/

 

๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Deep Dive: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ๋™์ž‘ ์›๋ฆฌ

269๊ฐœ์˜ ๊ทธ๋ฆผ๊ณผ ์›๋ฆฌ๋ฅผ ํŒŒํ—ค์น˜๋Š” ์„ค๋ช…์œผ๋กœ ‘์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ๋™์ž‘ ์›๋ฆฌ’๋ฅผ ์ดํ•ดํ•˜์ž! ์›นํŽ˜์ด์ง€์˜ ๋‹จ์ˆœํ•œ ๋ณด์กฐ ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ œํ•œ์ ์ธ ์šฉ๋„๋กœ ํƒœ์–ด๋‚œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ณผ๋„

wikibook.co.kr