-
RESTλ 무μμΈκ°?
- REpresentational State Transferμ μ€μλ§.
- HTTP/1.0 κ³Ό 1.1 μ€ν μμ± λ° μνμΉ HTTP μλ² νλ‘μ νΈμ 곡λ μ€λ¦½μ λ‘μ΄ νλ©μ λ Όλ¬Έμμ μ²μ μκ°λμλ€.
- HTTP νλ‘ν μ½μ μ₯μ μ μ΅λν νμ©ν μ μλ μν€ν μ³λ‘ μκ°λμ΄ HTTP νλ‘ν μ½μ μλμ λ§κ² λμμΈνλλ‘ μ λνκ³ μλ€.
-
μ격ν μλ―Έ vs κ°λ¨ν μλ―Έ
- μ격ν μλ―Έ
λ€νΈμν¬ μν€ν μ³ μ리μ λͺ¨μ, μ¦ μμμ μ μνκ³ μμμ λν μ£Όμλ₯Ό μ§μ νλ λ°©λ² μ λ°μ μλ―Ένλ€. - κ°λ¨ν μλ―Έ
μΉ μμ μλ£λ₯Ό HTTP μμμ λ³λμ μ μ‘κ³μΈ΅ μμ΄ μ μ‘νκΈ° μν μμ£Ό κ°λ¨ν μΈν°νμ΄μ€- SOAP(Simple Object Access Protocol : HTTP, HTTPS λ±μ ν΅ν΄ XML κΈ°λ° λ©μΈμ§λ₯Ό κ΅ννλ νλ‘ν μ½) μ΄λ μΏ ν€λ₯Ό ν΅ν μΈμ νΈλνΉ κ°μ μ μ‘κ³μΈ΅ κ²λ€ μμ΄ ν΅μ
- μ격ν μλ―Έ
-
RESTFulκ³Ό REST APIλ 무μμΈκ°?
- RESTμ κΈ°λ³Έ μμΉμ μ±μ€ν μ§ν¨ μλΉμ€ λ€μ§μΈμ RESTfulνλ€κ³ νννλ€.
- RESTλ₯Ό κΈ°λ°μΌλ‘ μλΉμ€ APIλ₯Ό ꡬνν κ²μ μλ―Ένλ€.
RESTλ HTTPλ₯Ό κΈ°λ°μΌλ‘ ν΄λΌμ΄μΈνΈκ° μλ²μ 리μμ€μ μ κ·Όνλ λ°©μμ κ·μ ν μν€ν μ³κ³ , REST APIλ RESTλ₯Ό κΈ°λ°μΌλ‘ μλΉμ€ APIλ₯Ό ꡬνν κ²μ μλ―Ένλ€.
REST APIλ μμ(resource), νμ(verb), νν(representation)μ μΈκ°μ§ μμλ‘ κ΅¬μ±λλ€. RESTλ μ체 νν κ΅¬μ‘°λ‘ κ΅¬μ±λμ΄ REST API λ§μΌλ‘ HTTP μμ²μ λ΄μ©μ μ΄ν΄ν μ μλ€.
ꡬμ±μμ | λ΄μ© | ννλ°©λ² |
---|---|---|
μμ | μμ | URI(μλν¬μΈνΈ) |
νμ | μμμ λν νμ | HTTP μμ² λ©μλ |
νν | μμμ λν νμμ ꡬ체μ λ΄μ© | νμ΄λ‘λ |
- νμ΄λ‘λ : ν° λ°μ΄ν° μ€μ 'ν₯λ―Έμλ' λ°μ΄ν°λ₯Ό ꡬλ³νλ λ° μ¬μ©.
- νλ‘κ·Έλλ°μμ μ£Όλ‘ λ©μΈμ§ νλ‘ν μ½ μ€μ νλ‘ν μ½ μ€λ²ν€λμ μνλ λ°μ΄ν°(μ¦ νμ΄λ‘λ)λ₯Ό ꡬλΆν λ μ¬μ©νλ€
- μμ - JSON νμμ μΉ μλΉμ€ μλ΅
μ¬κΈ°μμ "Hello, world!"κ° ν΄λΌμ΄μΈνΈκ° κ΄μ¬μ κ°μ§λ νμ΄λ‘λμ΄κ³ , λλ¨Έμ§ λΆλΆμ μ€μνκΈ΄ νμ§λ§ νλ‘ν μ½ μ€λ²ν€λμ΄λ€.{ "status": "OK", "data": { "message": "Hello, world!" } }
μΆμ² : [wiki]https://ko.wikipedia.org/wiki/%ED%8E%98%EC%9D%B4%EB%A1%9C%EB%93%9C_(%EC%BB%B4%ED%93%A8%ED%8C%85)
REST μμ κ°μ₯ μ€μν κΈ°λ³Έμ§μΈ μμΉμ λκ°μ§μ΄λ€!!
1. URIλ 리μμ€λ₯Ό νννλλ° μ§μ€νλ€.
2. HTTP μμ² λ©μλλ₯Ό ν΅ν΄ νμλ₯Ό μ μνλ€.
- URIλ 리μμ€λ₯Ό ννν΄μΌ νλ€.
#bad
GET /getTodos/1 - (1)λ² μμ
GET /todos/show/1 - (2)λ² μμ
# good
GET /todos/1
URIλ 리μμ€λ₯Ό νννλλ°μ μ€μ μ λμ΄μΌ νλ€.
- (1)λ² μμ -> μμμ²λΌ get κ°μ νμμ λν ννμ΄ λ€μ΄κ°μλ μλλ€
- (2)λ² μμ -> 리μμ€λ₯Ό μλ³ν μ μλ μ΄λ¦μ λμ¬λ³΄λ€λ λͺ μ¬λ₯Ό μ¬μ©νλ€.
- 리μμ€μ λν νμλ HTTP μμ² λ©μλλ‘ νννλ€.
HTTP μμ² λ©μλλ ν΄λΌμ΄μΈνΈκ° μλ²μκ² μμ²μ μ’ λ₯μ λͺ©μ (리μμ€μ λν νμ)μ μ리λ λ°©λ²μ΄λ€.
HTTP μμ² λ©μλ | μ’ λ₯ | λͺ©μ | νμ΄λ‘λ |
---|---|---|---|
GET | index / retrieve | λͺ¨λ νΉμ 리μμ€ μ·¨λ | X |
POST | create | 리μμ€ μμ± | O |
PUT | replace | 리μμ€μ μ 체 κ΅μ²΄ | O |
PATCH | modify | 리μμ€μ μΌλΆ μμ | O |
DELETE | delete | λͺ¨λ / νΉμ 리μμ€ μμ | X |
# bad
GET /todos/delete/1 - (1)λ² μμ
# good
DELETE /todos/1
리μμ€μ λν νμλ HTTP μμ² λ©μλλ₯Ό ν΅ν΄ νννλ©°, URIμ νννμ§ μλλ€.
- (1)λ² μμ - GETμ 리μμ€λ₯Ό μ·¨λν λ μ¬μ©νλ λ©μλμ΄λ€. μμ μμ²μ νλ €λ©΄ DELETE λ©μλλ₯Ό μ¬μ©νλ€.
- λ€μ JSON νμΌ λ°μ΄ν°λ₯Ό κΈ°μ€μΌλ‘ todoμ λν λ°μ΄ν°λ₯Ό CRUD ν μ μλ μλ²λΌκ³ μκ°ν΄λ³΄μ.
{
"todos": [
{
"id": 1,
"content": "JS",
"completed": true
},
{
"id": 2,
"content": "React",
"completed": false
},
{
"id": 1,
"content": "FrontEnd",
"completed": false
}
]
}
-
λͺ¨λ todos 리μμ€λ₯Ό μ·¨λ ν λ
const xhr = new XMLHttpRequest(); /**G * 1. νμλ λ©μλλ‘ GET μμ²μΌλ‘ μ·¨λνκ² λ€ * 2. 리μμ€λ URIλ‘ νν, todos 리μμ€λ₯Ό μ·¨λνκ² λ€(index) */ xhr.open("GET", "/todos"); xhr.send(); xhr.onload = () => { if (xhr.status === 200) { console.log(xhr.response); } else { console.error("Error", xhr.status, xhr.statusText); } };
- response
{ "todos": [ { "id": 1, "content": "JS", "completed": true }, { "id": 2, "content": "React", "completed": false }, { "id": 3, "content": "FrontEnd", "completed": false } ] }
- response
-
νΉμ todos 리μμ€λ₯Ό μ·¨λ
const xhr = new XMLHttpRequest(); /** * 1. νμλ λ©μλλ‘ GET μμ²μΌλ‘ μ·¨λνκ² λ€ * 2. 리μμ€λ URIλ‘ νν, todos/1 λ‘ id:1μΈ todo 리μμ€λ₯Ό μ·¨λνκ² λ€ * * todos 리μμ€μμ νΉμ todoλ₯Ό μ·¨λ(retrieve) */ xhr.open("GET", "/todos/1"); xhr.send(); xhr.onload = () => { if (xhr.status === 200) { console.log(xhr.response); } else { console.error("Error", xhr.status, xhr.statusText); } };
-
response
{ "todos": [ { "id": 1, "content": "JS", "completed": true } ] }
-
const xhr = new XMLHttpRequest();
/**
* 1. νμλ λ©μλλ‘ POST μμ²μΌλ‘ μμ±νκ² λ€
* 2. 리μμ€λ URIλ‘ νν, μλ‘μ΄ todoλ₯Ό μμ±νκ² λ€
*/
xhr.open("POST", "/todos");
// μμ² λͺΈμ²΄μ λ΄μ μλ²λ‘ λ³΄λΌ νμ΄λ‘λμ MIME νμ
μ§μ
xhr.setRequestHeader("Content-Type", "application/json");
// νμ΄λ‘λλ₯Ό λ΄μμ μλ²λ‘ μ μ‘
xhr.send(JSON.stringify({ id: "4", content: "Angular", completed: false }));
xhr.onload = () => {
if (xhr.status === 200) {
console.log(xhr.response);
} else {
console.error("Error", xhr.status, xhr.statusText);
}
};
- response
{ "todos": [ { "id": 1, "content": "JS", "completed": true }, { "id": 2, "content": "React", "completed": false }, { "id": 3, "content": "FrontEnd", "completed": false }, { "id": 4, "content": "Angular", "completed": false } ] }
const xhr = new XMLHttpRequest();
/**
* 1. νμλ λ©μλλ‘ PUT μμ²μΌλ‘ 리μμ€μ 체λ₯Ό κ΅μ²΄νκ² λ€
* 2. 리μμ€λ URIλ‘ νν, idλ‘ todoλ₯Ό νΉμ νμ¬ idλ₯Ό μ μΈν 리μμ€ μ 체λ₯Ό κ΅μ²΄
*/
xhr.open("PUT", "/todos/4");
// μμ² λͺΈμ²΄μ λ΄μ μλ²λ‘ λ³΄λΌ νμ΄λ‘λμ MIME νμ
μ§μ
xhr.setRequestHeader("Content-Type", "application/json");
// νμ΄λ‘λλ₯Ό λ΄μμ μλ²λ‘ μ μ‘
xhr.send(JSON.stringify({ id: "4", content: "Svelte", completed: false }));
xhr.onload = () => {
if (xhr.status === 200) {
console.log(xhr.response);
} else {
console.error("Error", xhr.status, xhr.statusText);
}
};
- response
{ "todos": [ { "id": 4, "content": "Svelte", "completed": false } ] }
const xhr = new XMLHttpRequest();
/**
* 1. νμλ λ©μλλ‘, PATCH μμ²μΌλ‘ 리μμ€μ 체λ₯Ό κ΅μ²΄νκ² λ€
* 2. 리μμ€λ URIλ‘ νν, idλ‘ todoλ₯Ό νΉμ νμ¬ μνλ λΆλΆλ§ κ΅μ²΄
*/
xhr.open("PATCH", "/todos/2");
// μμ² λͺΈμ²΄μ λ΄μ μλ²λ‘ λ³΄λΌ νμ΄λ‘λμ MIME νμ
μ§μ
xhr.setRequestHeader("Content-Type", "application/json");
// νμ΄λ‘λλ₯Ό λ΄μμ μλ²λ‘ μ μ‘
xhr.send(JSON.stringify({ completed: true }));
xhr.onload = () => {
if (xhr.status === 200) {
console.log(xhr.response);
} else {
console.error("Error", xhr.status, xhr.statusText);
}
};
-
response
{ "todos": [ { "id": 2, "content": "React", "completed": true } ] }
/**
* 1. νμλ λ©μλλ‘ DELETE μμ²μΌλ‘ 리μμ€λ₯Ό μμ νκ² λ€
* 2. 리μμ€λ URIλ‘ νν, idλ‘ todoλ₯Ό νΉμ νμ¬ ν΄λΉ todo μμ
*/
xhr.open("PATCH", "/todos/4");
// νμ΄λ‘λλ₯Ό λ΄μμ μλ²λ‘ μ μ‘
xhr.send(JSON.stringify({ completed: true }));
xhr.onload = () => {
if (xhr.status === 200) {
console.log(xhr.response);
} else {
console.error("Error", xhr.status, xhr.statusText);
}
};
-
response
{}