[WEB] π REST API ꡬμ±/νΉμ§ μ΄ μ 리
REST APIμ νμ
RESTλ Representational State TransferλΌλ μ©μ΄μ μ½μλ‘μ 2000λ λμ λ‘μ΄ νλ© (Roy Fielding)μ λ°μ¬νμ λ Όλ¬Έμμ μ΅μ΄λ‘ μκ°λμμ΅λλ€.
λ‘μ΄ νλ©μ HTTPμ μ£Όμ μ μ μ€ ν μ¬λμΌλ‘ κ·Έ λΉμ μΉ(HTTP) μ€κ³μ μ°μμ±μ λΉν΄ μ λλ‘ μ¬μ©λμ΄μ§μ§ λͺ»νλ λͺ¨μ΅μ μνκΉμνλ©° μΉμ μ₯μ μ μ΅λν νμ©ν μ μλ μν€ν μ²λ‘μ¨ RESTλ₯Ό λ°ννλ€κ³ ν©λλ€.
REST ꡬμ±
μ½κ² λ§ν΄ REST APIλ λ€μμ ꡬμ±μΌλ‘ μ΄λ£¨μ΄μ Έμμ΅λλ€.
- μμ(RESOURCE) - URI
- νμ(Verb) - HTTP METHOD
- νν(Representations)
REST μ νΉμ§
β
1) Uniform (μ λνΌ μΈν°νμ΄μ€)
Uniform Interfaceλ URIλ‘ μ§μ ν 리μμ€μ λν μ‘°μμ ν΅μΌλκ³ νμ μ μΈ μΈν°νμ΄μ€λ‘ μννλ μν€ν μ² μ€νμΌμ λ§ν©λλ€.
β
2) Stateless (무μνμ±)
RESTλ 무μνμ± μ±κ²©μ κ°μ΅λλ€.
λ€μ λ§ν΄ μμ μ μν μνμ 보λ₯Ό λ°λ‘ μ μ₯νκ³ κ΄λ¦¬νμ§ μμ΅λλ€.
μΈμ μ 보λ μΏ ν€μ 보λ₯Ό λ³λλ‘ μ μ₯νκ³ κ΄λ¦¬νμ§ μκΈ° λλ¬Έμ API μλ²λ λ€μ΄μ€λ μμ²λ§μ λ¨μν μ²λ¦¬νλ©΄ λ©λλ€. λλ¬Έμ μλΉμ€μ μμ λκ° λμμ§κ³ μλ²μμ λΆνμν μ 보λ₯Ό κ΄λ¦¬νμ§ μμμΌλ‘μ¨ κ΅¬νμ΄ λ¨μν΄μ§λλ€.
β
3) Cacheable (μΊμ κ°λ₯)
RESTμ κ°μ₯ ν° νΉμ§ μ€ νλλ HTTPλΌλ κΈ°μ‘΄ μΉνμ€μ κ·Έλλ‘ μ¬μ©νκΈ° λλ¬Έμ, μΉμμ μ¬μ©νλ κΈ°μ‘΄ μΈνλΌλ₯Ό κ·Έλλ‘ νμ©μ΄ κ°λ₯ν©λλ€. λ°λΌμ HTTPκ° κ°μ§ μΊμ± κΈ°λ₯μ΄ μ μ© κ°λ₯ν©λλ€. HTTP νλ‘ν μ½ νμ€μμ μ¬μ©νλ Last-Modifiedνκ·Έλ E-Tagλ₯Ό μ΄μ©νλ©΄ μΊμ± ꡬνμ΄ κ°λ₯ν©λλ€.
β
4) Self-descriptiveness (μ체 νν ꡬ쑰)
RESTμ λ λ€λ₯Έ ν° νΉμ§ μ€ νλλ REST API λ©μμ§λ§ λ³΄κ³ λ μ΄λ₯Ό μ½κ² μ΄ν΄ ν μ μλ μ체 νν κ΅¬μ‘°λ‘ λμ΄ μλ€λ κ²μ λλ€.
β
5) Client - Server ꡬ쑰
REST μλ²λ API μ 곡, ν΄λΌμ΄μΈνΈλ μ¬μ©μ μΈμ¦μ΄λ 컨ν μ€νΈ(μΈμ , λ‘κ·ΈμΈ μ 보)λ±μ μ§μ κ΄λ¦¬νλ κ΅¬μ‘°λ‘ κ°κ°μ μν μ΄ νμ€ν ꡬλΆλκΈ° λλ¬Έμ ν΄λΌμ΄μΈνΈμ μλ²μμ κ°λ°ν΄μΌ ν λ΄μ©μ΄ λͺ νν΄μ§κ³ μλ‘κ° μμ‘΄μ±μ΄ μ€μ΄λ€κ² λ©λλ€.
β
6) κ³μΈ΅ν ꡬ쑰
REST μλ²λ λ€μ€ κ³μΈ΅μΌλ‘ ꡬμ±λ μ μμΌλ©° 보μ, λ‘λ λ°Έλ°μ±, μνΈν κ³μΈ΅μ μΆκ°ν΄ ꡬ쑰μμ μ μ°μ±μ λ μ μκ³ PROXY, κ²μ΄νΈμ¨μ΄ κ°μ λ€νΈμν¬ κΈ°λ°μ μ€κ°λ§€μ²΄λ₯Ό μ¬μ©ν μ μκ² ν©λλ€.
β
REST API λμμΈ κ°μ΄λ
REST API μ€κ³ μ κ°μ₯ μ€μν νλͺ©μ λ€μμ 2κ°μ§λ‘ μμ½ν μ μμ΅λλ€.
β
첫 λ²μ§Έ, URIλ μ 보μ μμμ ννν΄μΌ νλ€.
λ λ²μ§Έ, μμμ λν νμλ HTTP Method(GET, POST, PUT, DELETE)λ‘ νννλ€.
REST API μ€μ¬ κ·μΉ
β
1) URIλ μ 보μ μμμ ννν΄μΌ νλ€. (리μμ€λͺ μ λμ¬λ³΄λ€λ λͺ μ¬λ₯Ό μ¬μ©)
GET /members/delete/1 *ν€λ λΌμΈμ ννν κ²λλ€. |
μμ κ°μ λ°©μμ RESTλ₯Ό μ λλ‘ μ μ©νμ§ μμ URIμ λλ€.
URIλ μμμ νννλλ° μ€μ μ λμ΄μΌ ν©λλ€. deleteμ κ°μ νμμ λν ννμ΄ λ€μ΄κ°μλ μλ©λλ€.
β
2) μμμ λν νμλ HTTP Method(GET, POST, PUT, DELETE λ±)λ‘ νν
μμ μλͺ» λ URIλ₯Ό HTTP Methodλ₯Ό ν΅ν΄ μμ ν΄ λ³΄λ©΄
DELETE /members/1 |
μΌλ‘ μμ ν μ μκ² μ΅λλ€.
β
νμμ 보λ₯Ό κ°μ Έμ¬ λλ GET,
νμ μΆκ° μμ νμλ₯Ό νννκ³ μ ν λλ POST METHODλ₯Ό μ¬μ©νμ¬ ννν©λλ€.
β
νμμ 보λ₯Ό κ°μ Έμ€λ URI
GET /members/show/1 (x) *showλ νμμ
λλ€. λ³΄κ² λ€λ μλλ μκ² μ§λ§ κΆμ₯νμ§ μμ΅λλ€. GET /members/1 (o) |
νμμ μΆκ°ν λ
GET /members/insert/2 (x) *GET λ©μλλ 리μμ€ μμ±μ λ§μ§ μμ΅λλ€. POST /members/2 (o) |
β
[μ°Έκ³ ] HTTP METHOD
POST, GET, PUT, DELETE μ΄ 4κ°μ§μ Methodλ₯Ό κ°μ§κ³ CRUDλ₯Ό ν μ μμ΅λλ€.
METHOD | μν |
POST | POSTλ₯Ό ν΅ν΄ ν΄λΉ URIλ₯Ό μμ²νλ©΄ 리μμ€λ₯Ό μμ±ν©λλ€. |
GET | GETλ₯Ό ν΅ν΄ ν΄λΉ 리μμ€λ₯Ό μ‘°νν©λλ€. 리μμ€λ₯Ό μ‘°ννκ³ ν΄λΉ λνλ¨ΌνΈμ λν μμΈν μ 보λ₯Ό κ°μ Έμ¨λ€. |
PUT | PUTλ₯Ό ν΅ν΄ ν΄λΉ 리μμ€λ₯Ό μμ ν©λλ€. |
DELETE | DELETEλ₯Ό ν΅ν΄ 리μμ€λ₯Ό μμ ν©λλ€. |
λ€μκ³Ό κ°μ μμΌλ‘ URIλ μμμ νννλ λ°μ μ§μ€νκ³ ,
νμμ λν μ μλ HTTP METHODλ₯Ό ν΅ν΄ νλ κ²μ΄ RESTν APIλ₯Ό μ€κ³νλ μ€μ¬ κ·μΉμ λλ€.
β
β
URI μ€κ³ μ μ£Όμν μ
β
1) μ¬λμ ꡬλΆμ(/)λ κ³μΈ΅ κ΄κ³λ₯Ό λνλ΄λ λ° μ¬μ©
http://restapi.example.com/houses/apartments http://restapi.example.com/animals/mammals/whales |
β
2) URI λ§μ§λ§ λ¬Έμλ‘ μ¬λμ(/)λ₯Ό ν¬ν¨νμ§ μλλ€.
URIμ ν¬ν¨λλ λͺ¨λ κΈμλ 리μμ€μ μ μΌν μλ³μλ‘ μ¬μ©λμ΄μΌ νλ©° URIκ° λ€λ₯΄λ€λ κ²μ 리μμ€κ° λ€λ₯΄λ€λ κ²μ΄κ³ , μμΌλ‘ 리μμ€κ° λ€λ₯΄λ©΄ URIλ λ¬λΌμ ΈμΌ ν©λλ€.
REST APIλ λΆλͺ ν URIλ₯Ό λ§λ€μ΄ ν΅μ μ ν΄μΌ νκΈ° λλ¬Έμ νΌλμ μ£Όμ§ μλλ‘ URI κ²½λ‘μ λ§μ§λ§μλ μ¬λμ(/)λ₯Ό μ¬μ©νμ§ μμ΅λλ€.
http://restapi.example.com/houses/apartments/ (X) http://restapi.example.com/houses/apartments (0) |
β
3) νμ΄ν(-)μ URI κ°λ μ±μ λμ΄λλ° μ¬μ©
URIλ₯Ό μ½κ² μ½κ³ ν΄μνκΈ° μν΄, λΆκ°νΌνκ² κΈ΄ URIκ²½λ‘λ₯Ό μ¬μ©νκ² λλ€λ©΄ νμ΄νμ μ¬μ©ν΄ κ°λ μ±μ λμΌ μ μμ΅λλ€.
β
4) λ°μ€(_)μ URIμ μ¬μ©νμ§ μλλ€.
κΈκΌ΄μ λ°λΌ λ€λ₯΄κΈ΄ νμ§λ§ λ°μ€μ 보기 μ΄λ ΅κ±°λ λ°μ€ λλ¬Έμ λ¬Έμκ° κ°λ €μ§κΈ°λ ν©λλ€. μ΄λ° λ¬Έμ λ₯Ό νΌνκΈ° μν΄ λ°μ€ λμ νμ΄ν(-)μ μ¬μ©νλ κ²μ΄ μ’μ΅λλ€. (κ°λ μ±)
β
5) URI κ²½λ‘μλ μλ¬Έμκ° μ ν©νλ€.
URI κ²½λ‘μ λλ¬Έμ μ¬μ©μ νΌνλλ‘ ν΄μΌ ν©λλ€. λμλ¬Έμμ λ°λΌ λ€λ₯Έ 리μμ€λ‘ μΈμνκ² λκΈ° λλ¬Έμ λλ€. RFC 3986(URI λ¬Έλ² νμ)μ URI μ€ν€λ§μ νΈμ€νΈλ₯Ό μ μΈνκ³ λ λμλ¬Έμλ₯Ό ꡬλ³νλλ‘ κ·μ νκΈ° λλ¬Έμ΄μ§μ.
RFC 3986 is the URI (Unified Resource Identifier) Syntax document |
β
6) νμΌ νμ₯μλ URIμ ν¬ν¨μν€μ§ μλλ€.
http://restapi.example.com/members/soccer/345/photo.jpg (X) |
REST APIμμλ λ©μμ§ λ°λ λ΄μ©μ ν¬λ§·μ λνλ΄κΈ° μν νμΌ νμ₯μλ₯Ό URI μμ ν¬ν¨μν€μ§ μμ΅λλ€.
Accept headerλ₯Ό μ¬μ©νλλ‘ ν©μλ€.
GET / members/soccer/345/photo HTTP/1.1 Host: restapi.example.com Accept: image/jpg |
β
리μμ€ κ°μ κ΄κ³λ₯Ό νννλ λ°©λ²
REST 리μμ€ κ°μλ μ°κ΄ κ΄κ³κ° μμ μ μκ³ , μ΄λ° κ²½μ° λ€μκ³Ό κ°μ ννλ°©λ²μΌλ‘ μ¬μ©ν©λλ€.
/리μμ€λͺ
/리μμ€ ID/κ΄κ³κ° μλ λ€λ₯Έ 리μμ€λͺ
ex) GET : /users/{userid}/devices (μΌλ°μ μΌλ‘ μμ ‘has’μ κ΄κ³λ₯Ό ννν λ) |
λ§μ½μ κ΄κ³λͺ μ΄ λ³΅μ‘νλ€λ©΄ μ΄λ₯Ό μλΈ λ¦¬μμ€μ λͺ μμ μΌλ‘ νννλ λ°©λ²μ΄ μμ΅λλ€.
μλ₯Ό λ€μ΄ μ¬μ©μκ° ‘μ’μνλ’ λλ°μ΄μ€ λͺ©λ‘μ ννν΄μΌ ν κ²½μ° λ€μκ³Ό κ°μ ννλ‘ μ¬μ©λ μ μμ΅λλ€.
GET : /users/{userid}/likes/devices (κ΄κ³λͺ μ΄ μ 맀νκ±°λ ꡬ체μ ννμ΄ νμν λ) |
β
μμμ νννλ Colllectionκ³Ό Document
Collectionκ³Ό Documentμ λν΄ μλ©΄ URI μ€κ³κ° ν μΈ΅ λ μ¬μμ§λλ€.
β
DOCUMENTλ λ¨μν λ¬Έμλ‘ μ΄ν΄ν΄λ λκ³ , ν κ°μ²΄λΌκ³ μ΄ν΄νμ λ λ κ² κ°μ΅λλ€.
Collectionμ λ¬Έμλ€μ μ§ν©, κ°μ²΄λ€μ μ§ν©μ΄λΌκ³ μκ°νμλ©΄ μ΄ν΄νμλλ° μ’λ νΈνμ€ κ² κ°μ΅λλ€.
β
컬λ μ κ³Ό λνλ¨ΌνΈλ λͺ¨λ 리μμ€λΌκ³ ννν μ μμΌλ©° URIμ ννλ©λλ€. μλ₯Ό μ΄ν΄λ³΄λλ‘ νκ² μ΅λλ€.
http:// restapi.example.com/sports/soccer |
μ URIλ₯Ό 보μλ©΄ sportsλΌλ 컬λ μ κ³Ό soccerλΌλ λνλ¨ΌνΈλ‘ ννλκ³ μλ€κ³ μκ°νλ©΄ λ©λλ€.
β
μ’ λ μλ₯Ό λ€μ΄λ³΄μλ©΄
http:// restapi.example.com/sports/soccer/players/13 |
sports, players 컬λ μ κ³Ό soccer, 13(13λ²μΈ μ μ)λ₯Ό μλ―Ένλ λνλ¨ΌνΈλ‘ URIκ° μ΄λ£¨μ΄μ§κ² λ©λλ€. μ¬κΈ°μ μ€μν μ μ 컬λ μ μ 볡μλ‘ μ¬μ©νκ³ μλ€λ μ μ λλ€.
μ’ λ μ§κ΄μ μΈ REST APIλ₯Ό μν΄μλ 컬λ μ κ³Ό λνλ¨ΌνΈλ₯Ό μ¬μ©ν λ λ¨μ 볡μλ μ§μΌμ€λ€λ©΄ μ’ λ μ΄ν΄νκΈ° μ¬μ΄ URIλ₯Ό μ€κ³ν μ μμ΅λλ€.
HTTP μλ΅ μν μ½λ
λ§μ§λ§μΌλ‘ μλ΅ μνμ½λλ₯Ό κ°λ¨ν μ΄ν΄λ³΄λλ‘ νκ² μ΅λλ€.
[WEB] π HTTP μν μ½λ μ 리
μν μ½λλ 3μ리 μ«μλ‘ λ§λ€μ΄μ Έ μμΌλ©°, 첫λ²μ§Έ μ리λ 1μμ 5κΉμ§ μ 곡λ©λλ€. 첫λ²μ§Έ μλ¦¬κ° 4μ 5μΈ κ²½μ°λ μ μμ μΈ μν©μ΄ μλκΈ° λλ¬Έμ μ¬μ΄νΈ κ΄λ¦¬μκ° μ¦μ μμμΌ νλ μ 보μ λ
inpa.tistory.com
μ μ€κ³λ REST APIλ URIλ§ μ μ€κ³λ κ²μ΄ μλ κ·Έ 리μμ€μ λν μλ΅μ μ λ΄μ΄μ£Όλ κ²κΉμ§ ν¬ν¨λμ΄μΌ ν©λλ€.
μ νν μλ΅μ μνμ½λλ§μΌλ‘λ λ§μ μ 보λ₯Ό μ λ¬ν μκ° μκΈ° λλ¬Έμ μλ΅μ μνμ½λ κ°μ λͺ νν λλ €μ£Όλ κ²μ μκ°λ³΄λ€ μ€μν μΌμ΄ λ μλ μμ΅λλ€.
β
νΉμ 200μ΄λ 4XXκ΄λ ¨ νΉμ μ½λ μ λλ§ μ¬μ©νκ³ μλ€λ©΄ μ²λ¦¬ μνμ λν μ’ λ λͺ νν μνμ½λ κ°μ μ¬μ©ν μ μκΈ°λ₯Ό κΆμ₯νλ λ°μ λλ€.
β
μνμ½λμ λν΄μλ λͺ κ°μ§λ§ μ 리νλλ‘ νκ² μ΅λλ€.
μνμ½λ | β |
200 | ν΄λΌμ΄μΈνΈμ μμ²μ μ μμ μΌλ‘ μνν¨ |
201 | ν΄λΌμ΄μΈνΈκ° μ΄λ ν 리μμ€ μμ±μ μμ², ν΄λΉ 리μμ€κ° μ±κ³΅μ μΌλ‘ μμ±λ¨(POSTλ₯Ό ν΅ν 리μμ€ μμ± μμ μ) |
μνμ½λ | β |
400 | ν΄λΌμ΄μΈνΈμ μμ²μ΄ λΆμ μ ν κ²½μ° μ¬μ©νλ μλ΅ μ½λ |
401 | ν΄λΌμ΄μΈνΈκ° μΈμ¦λμ§ μμ μνμμ 보νΈλ 리μμ€λ₯Ό μμ²νμ λ μ¬μ©νλ μλ΅ μ½λ |
β | (λ‘κ·ΈμΈ νμ§ μμ μ μ κ° λ‘κ·ΈμΈ νμ λ, μμ² κ°λ₯ν 리μμ€λ₯Ό μμ²νμ λ) |
403 | μ μ μΈμ¦μνμ κ΄κ³ μμ΄ μλ΅νκ³ μΆμ§ μμ 리μμ€λ₯Ό ν΄λΌμ΄μΈνΈκ° μμ²νμ λ μ¬μ©νλ μλ΅ μ½λ |
β | (403 보λ€λ 400μ΄λ 404λ₯Ό μ¬μ©ν κ²μ κΆκ³ . 403 μμ²΄κ° λ¦¬μμ€κ° μ‘΄μ¬νλ€λ λ»μ΄κΈ° λλ¬Έμ) |
405 | ν΄λΌμ΄μΈνΈκ° μμ²ν 리μμ€μμλ μ¬μ© λΆκ°λ₯ν Methodλ₯Ό μ΄μ©νμ κ²½μ° μ¬μ©νλ μλ΅ μ½λ |
μνμ½λ | β |
301 | ν΄λΌμ΄μΈνΈκ° μμ²ν 리μμ€μ λν URIκ° λ³κ²½ λμμ λ μ¬μ©νλ μλ΅ μ½λ |
β | (μλ΅ μ Location headerμ λ³κ²½λ URIλ₯Ό μ μ΄ μ€μΌ ν©λλ€.) |
500 | μλ²μ λ¬Έμ κ° μμ κ²½μ° μ¬μ©νλ μλ΅ μ½λ |
# μ°Έκ³ μλ£
https://meetup.toast.com/posts/92
https://www.youtube.com/watch?v=PmY3dWcCxXI