Search

REST

REST (Representational State Transfer)

μƒνƒœ ν‘œν˜„ 전솑 μ•„ν‚€ν…μ²˜

present [prΙͺˈzent]

: 보여주닀

represent [ˌreprΙͺˈzent]

: λ‹€μ‹œ 보여주닀, λŒ€μ‹  ν‘œν˜„ν•˜λ‹€
re-(λ‹€μ‹œ) + present(보여주닀) λ‹€μ‹œ 보여주닀, λŒ€ν‘œν•˜λ‹€, λŒ€λ³€ν•˜λ‹€

representational [ ˌreprΙͺzenˈteΙͺΚƒnl ]

: ν‘œν˜„ν•˜λŠ”, λ³΄μ—¬μ£ΌλŠ”

REST

μƒνƒœ ν‘œν˜„ 전솑 μ•„ν‚€ν…μ²˜

μžμ›μ˜ μƒνƒœλ₯Ό ν‘œν˜„ν•˜μ—¬ μ „λ‹¬ν•˜λŠ” μ•„ν‚€ν…μ²˜
URI 둜 μžμ›μ„ λŒ€μ‹ ν•˜μ—¬ ν‘œν˜„ν•˜κ³ , μ„œλ²„κ°€ ν•΄μ•Ό ν•  ν–‰μœ„(μ„œλ²„μ˜ μƒνƒœ)λ₯Ό HTTP λ©”μ†Œλ“œλ‘œ ν‘œν˜„ν•˜λŠ” 것을 μ›μΉ™μœΌλ‘œ ν•˜λŠ” μ•„ν‚€ν…μ²˜
β€’
λ„€νŠΈμ›Œν¬ μ•„ν‚€ν…μ²˜ μ€‘μ˜ ν•˜λ‚˜μž…λ‹ˆλ‹€.
β€’
ν”„λ‘ νŠΈμ—”λ“œ 및 λ°±μ—”λ“œμ˜ 독립성과 ν™•μž₯μ„± ν–₯μƒμ‹œν‚΅λ‹ˆλ‹€.

Overview

β€’
REST μžμ„Ένžˆ μ•Œμ•„λ³΄κΈ°
β€’
RESTful
β€’
RESTful API
β€’
CRUD
β€’
RESTful CRUD
β€’
REST μ•„ν‚€ν…μ²˜λ₯Ό μ‚¬μš©ν•˜λŠ” 이유
β€’
Server Side Rendering (SSR)
β€’
Client Side Rendering (CSR)
β€’
Non-RESTful VS RESTful
β€’
REST μ•„ν‚€ν…μ²˜μ˜ 6가지 원칙

REST μžμ„Ένžˆ μ•Œμ•„λ³΄κΈ°

2000 λ…„ 둜이 ν•„λ”© (Roy Fielding) 의 박사 λ…Όλ¬Έμ—μ„œ μ†Œκ°œλœ κ°œλ…μ΄λ‹€.
REST μ•„ν‚€ν…μ²˜λ₯Ό μ œμ‹œν•œ 핡심 인물 쀑 ν•œ λͺ…μœΌλ‘œ, HTTP ν”„λ‘œν† μ½œκ³Ό μ›”λ“œ μ™€μ΄λ“œ μ›Ή (WWW)의 핡심 ν‘œμ€€ν™”μ— κΈ°μ—¬ν–ˆμŠ΅λ‹ˆλ‹€. 필딩은 그의 λ°•μ‚¬ν•™μœ„ λ…Όλ¬Έμ—μ„œ REST(Representational State Transfer) μ•„ν‚€ν…μ²˜λ₯Ό μ†Œκ°œν•˜μ—¬, λΆ„μ‚° ν•˜μ΄νΌλ―Έλ””μ–΄ μ‹œμŠ€ν…œμ„ μœ„ν•œ 섀계 원칙을 μ œμ•ˆν–ˆμŠ΅λ‹ˆλ‹€. 이후 λ§Žμ€ μ›Ή μ„œλΉ„μŠ€μ™€ APIκ°€ REST μ•„ν‚€ν…μ²˜ μŠ€νƒ€μΌμ„ μ μš©ν•˜μ—¬ κ΅¬μΆ•λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
RESTλŠ” Representational State Transfer의 μ•½μžλ‘œ, μ›Ή κ°œλ°œμ—μ„œ λ„€νŠΈμ›Œν¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ„€κ³„ν•˜λŠ” 데 자주 μ‚¬μš©λ˜λŠ” μ•„ν‚€ν…μ²˜ μŠ€νƒ€μΌμž…λ‹ˆλ‹€. REST의 원칙을 μ€€μˆ˜ν•˜λŠ” RESTful APIλŠ” λ‹€λ₯Έ μ‹œμŠ€ν…œ 간에 HTTPλ₯Ό 톡해 ν†΅μ‹ ν•˜κ³  데이터λ₯Ό κ΅ν™˜ν•  수 있게 ν•΄μ€λ‹ˆλ‹€.
RESTλŠ” κ°„λ‹¨ν•˜κ³  μœ μ—°ν•œ μ•„ν‚€ν…μ²˜λ‘œ, μžμ›μ„ URI(Uniform Resource Identifier)둜 ν‘œν˜„ν•˜κ³ , HTTP λ©”μ†Œλ“œ(GET, POST, PUT, DELETE λ“±)λ₯Ό μ‚¬μš©ν•˜μ—¬ ν•΄λ‹Ή μžμ›μ— λŒ€ν•œ μ•‘μ…˜μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€. λ˜ν•œ, RESTful APIλŠ” μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜μ§€ μ•Šκ³ , μš”μ²­μ— ν•„μš”ν•œ λͺ¨λ“  정보λ₯Ό μš”μ²­ μžμ²΄μ— ν¬ν•¨μ‹œν‚΅λ‹ˆλ‹€.
μ΄λŸ¬ν•œ RESTful API의 μž₯점은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:
β€’
κ°„κ²°μ„±: 직관적이고 κ°„κ²°ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.
β€’
ν™•μž₯μ„±: μ‹œμŠ€ν…œμ„ λŠμŠ¨ν•˜κ²Œ κ²°ν•©ν•˜μ—¬ ν™•μž₯이 μš©μ΄ν•©λ‹ˆλ‹€.
β€’
κ°€μ‹œμ„±: μžμ›μ— λŒ€ν•œ ν‘œμ€€ν™”λœ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•˜λ―€λ‘œ, κ°œλ°œμžλ“€μ΄ APIλ₯Ό μ΄ν•΄ν•˜κ³  μ‚¬μš©ν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€.
λ”°λΌμ„œ, RESTful APIλŠ” ν˜„λŒ€μ μΈ μ›Ή κ°œλ°œμ—μ„œ 맀우 μ€‘μš”ν•œ 역할을 λ‹΄λ‹Ήν•˜κ³  있으며, λ§Žμ€ μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜κ³Ό μ„œλΉ„μŠ€κ°€ RESTλ₯Ό 기반으둜 κ΅¬μΆ•λ˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

RESTful

: REST μ•„ν‚€ν…μ²˜λ₯Ό λ”°λ₯΄λŠ” μ‹œμŠ€ν…œ λ˜λŠ” μ„œλΉ„μŠ€λ₯Ό κ°€λ¦¬ν‚€λŠ” μš©μ–΄μž…λ‹ˆλ‹€

RESTful API

REST μ•„ν‚€ν…μ²˜ 원칙을 λ”°λ₯΄λŠ” API둜, RESTful μ„œλΉ„μŠ€λ₯Ό μœ„ν•œ μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€. 이 APIλŠ” μ›Ή μ„œλΉ„μŠ€λ₯Ό κ΅¬μΆ•ν•˜κ±°λ‚˜ ν†΅ν•©ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
주둜 HTTPλ₯Ό 기반으둜 ν•˜λ©°, μžμ›μ„ URL둜 ν‘œν˜„ν•˜κ³  HTTP λ©”μ†Œλ“œ(GET, POST, PUT, DELETE λ“±)λ₯Ό μ‚¬μš©ν•˜μ—¬ μžμ›μ„ κ΄€λ¦¬ν•˜λ©°, JSON λ˜λŠ” XMLκ³Ό 같은 데이터 ν˜•μ‹μ„ 톡해 데이터λ₯Ό κ΅ν™˜ν•©λ‹ˆλ‹€.
RESTful APIλŠ” κ°„λ‹¨ν•˜κ³  직관적이며, μ„œλ²„μ™€ ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄μ˜ 톡신을 효율적으둜 μˆ˜ν–‰ν•˜λŠ” 데 도움이 λ©λ‹ˆλ‹€.

CRUD

CRUDλŠ” λ°μ΄ν„°μ˜ 기본적인 μž‘μ—…μ„ λ‚˜νƒ€λ‚΄λŠ” μ•½μ–΄λ‘œ, Create(생성), Read(읽기), Update(μˆ˜μ •), Delete(μ‚­μ œ)의 λ„€ 가지 κΈ°λ³Έ μž‘μ—…μ„ λ§ν•©λ‹ˆλ‹€. 이 λ„€ 가지 μž‘μ—…μ€ 주둜 λ°μ΄ν„°λ² μ΄μŠ€μ™€ κ΄€λ ¨λœ μž‘μ—…μ—μ„œ μ‚¬μš©λ©λ‹ˆλ‹€:

RESTful CRUD

CRUD μž‘μ—…
μš”μ²­ λ©”μ†Œλ“œ
μ„€λͺ…
Create
POST
μƒˆλ‘œμš΄ 데이터 λ ˆμ½”λ“œλ₯Ό 생성
Read
GET
데이터λ₯Ό μ½κ±°λ‚˜ 쑰회
Update
PUT/PATCH
데이터 λ ˆμ½”λ“œλ₯Ό μˆ˜μ • λ˜λŠ” κ°±μ‹ 
Delete
DELETE
데이터λ₯Ό μ‚­μ œ
RESTful APIλŠ” μ΄λŸ¬ν•œ HTTP λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ„œλ²„μ˜ μžμ›μ„ κ΄€λ¦¬ν•˜λŠ” 데 ν™œμš©λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, POST μš”μ²­μ„ 톡해 μƒˆλ‘œμš΄ 데이터λ₯Ό μƒμ„±ν•˜κ³ , GET μš”μ²­μ„ 톡해 데이터λ₯Ό μ½κ±°λ‚˜ μ‘°νšŒν•˜λ©°, PUT λ˜λŠ” PATCH μš”μ²­μ„ 톡해 데이터λ₯Ό μˆ˜μ •ν•˜κ³ , DELETE μš”μ²­μ„ 톡해 데이터λ₯Ό μ‚­μ œν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ HTTP λ©”μ†Œλ“œλ₯Ό μ΄μš©ν•˜μ—¬ 각각의 CRUD μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 것이 RESTful API의 μ£Όμš” νŠΉμ§• 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€.

REST μ•„ν‚€ν…μ²˜λ₯Ό μ‚¬μš©ν•˜λŠ” 이유

RESTful APIλŠ” 일반적으둜 HTTP ν”„λ‘œν† μ½œμ„ λ”°λ₯΄κ³ , μš”μ²­κ³Ό 응닡을 ν‘œμ€€ν™”λœ λ°©μ‹μœΌλ‘œ μ²˜λ¦¬ν•¨μœΌλ‘œμ¨, λ‹€μ–‘ν•œ μ–Έμ–΄λ‚˜ ν”Œλž«νΌ 간에 μƒν˜Έμš΄μš©μ„±μ„ 보μž₯ν•©λ‹ˆλ‹€. μ΄λŠ” ν”„λ‘ νŠΈμ—”λ“œμ™€ λ°±μ—”λ“œλ₯Ό λΆ„λ¦¬ν•˜κ³ , 각 μ˜μ—­μ„ λ…λ¦½μ μœΌλ‘œ κ°œλ°œν•  λ•Œ 맀우 μœ μš©ν•©λ‹ˆλ‹€. λ”°λΌμ„œ ν”„λ‘ νŠΈμ—”λ“œμ™€ λ°±μ—”λ“œλ₯Ό λ…λ¦½μ μœΌλ‘œ κ°œλ°œν•˜λŠ” 경우 RESTful APIλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 일반적으둜 ꢌμž₯λ©λ‹ˆλ‹€.
REST λŠ” λ„€νŠΈμ›Œν¬ μ•„ν‚€ν…μ²˜μ˜ μΌμ’…μž…λ‹ˆλ‹€.

μ£Όμš” λ„€νŠΈμ›Œν¬ μ•„ν‚€ν…μ²˜ μ’…λ₯˜

1.
κ³„μΈ΅ν™”λœ μ•„ν‚€ν…μ²˜(Layered Architecture) : λ„€νŠΈμ›Œν¬ μ‹œμŠ€ν…œμ΄ μ—¬λŸ¬ κ³„μΈ΅μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ 있으며, 각 계측은 νŠΉμ •ν•œ μ—­ν• κ³Ό μ±…μž„μ„ κ°–μŠ΅λ‹ˆλ‹€. OSI 7계측 λͺ¨λΈμ΄ μ΄λŸ¬ν•œ 계측화 μ•„ν‚€ν…μ²˜μ˜ ν•œ μ˜ˆμž…λ‹ˆλ‹€.
2.
RESTful μ•„ν‚€ν…μ²˜(Representational State Transfer) : RESTλŠ” ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ κ°„μ˜ 톡신을 μœ„ν•œ μ›Ή μ•„ν‚€ν…μ²˜μ˜ ν•œ ν˜•νƒœλ‘œ, λ¦¬μ†ŒμŠ€λ₯Ό URL을 톡해 μ‹λ³„ν•˜κ³  HTTP λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•˜λŠ” μ•„ν‚€ν…μ²˜ μ›μΉ™μž…λ‹ˆλ‹€.
3.
λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ μ•„ν‚€ν…μ²˜(Microservices Architecture) : 이 μ•„ν‚€ν…μ²˜λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ—¬λŸ¬ μž‘μ€ μ„œλΉ„μŠ€λ‘œ λΆ„ν• ν•˜μ—¬ 각 μ„œλΉ„μŠ€κ°€ λ…λ¦½μ μœΌλ‘œ κ΅¬μ„±λ˜κ³  μ‹€ν–‰λ˜λ„λ‘ ν•˜λŠ” ꡬ쑰λ₯Ό λ§ν•©λ‹ˆλ‹€.

Server Side Rendering (SSR)

μ„œλ²„ μΈ‘ λ Œλ”λ§(Server-Side Rendering, SSR)은 μ‚¬μš©μžκ°€ μ›ΉνŽ˜μ΄μ§€μ— μ ‘μ†ν–ˆμ„ λ•Œ, μ„œλ²„μ—μ„œ ν•΄λ‹Ή νŽ˜μ΄μ§€λ₯Ό μ™„μ „νžˆ λ Œλ”λ§ν•˜κ³  μ™„μ„±λœ HTML λ¬Έμ„œλ‘œ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μ œκ³΅ν•˜λŠ” κΈ°μˆ μž…λ‹ˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈμ—μ„œλŠ” μ„œλ²„λ‘œλΆ€ν„° μ „λ‹¬λœ μ™„μ„±λœ HTML을 λ°›μ•„ 화면에 ν‘œμ‹œν•˜λŠ” λ°©μ‹μž…λ‹ˆλ‹€.

Client Side Rendering (CSR)

ν΄λΌμ΄μ–ΈνŠΈ μΈ‘ λ Œλ”λ§ (Client-Side Rendering λ˜λŠ” CSR)은 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‚¬μš©μžμ˜ λΈŒλΌμš°μ €μ—μ„œ JavaScriptλ₯Ό μ‚¬μš©ν•˜μ—¬ μ™„μ „νžˆ λ Œλ”λ§ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. 이 방식은 μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 정적 νŒŒμΌμ„ λ‘œλ“œν•˜κ³  μ‚¬μš©μž μƒν˜Έ μž‘μš©μ— 따라 APIμ—μ„œ 데이터λ₯Ό 가져와 DOM을 μ‘°μž‘ν•˜μ—¬ λ‚΄μš©μ„ λ™μ μœΌλ‘œ ν‘œμ‹œν•©λ‹ˆλ‹€.
CSR(Client-Side Rendering)μ—μ„œλŠ” 주둜 JSON λ˜λŠ” XMLκ³Ό 같은 데이터λ₯Ό λ°›μ•„ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ λ Œλ”λ§ν•˜κ³ , React, Vue, Angular λ“±μ˜ ν”„λ ˆμž„μ›Œν¬ λ˜λŠ” 라이브러리λ₯Ό μ‚¬μš©ν•˜μ—¬ ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λ Œλ”λ§μ„ λ‹΄λ‹Ήν•©λ‹ˆλ‹€. νŽ˜μ΄μ§€ λ‘œλ”© ν›„, ν”„λ‘ νŠΈμ—”λ“œ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ μ„œλ²„μ—μ„œ 받은 데이터λ₯Ό λ™μ μœΌλ‘œ λ Œλ”λ§ν•˜μ—¬ μ‚¬μš©μžμ—κ²Œ λ³΄μ—¬μ€λ‹ˆλ‹€. 이 과정은 ν΄λΌμ΄μ–ΈνŠΈ μΈ‘μ—μ„œ μ΄λ£¨μ–΄μ§€λ―€λ‘œ λΈŒλΌμš°μ €μ—μ„œ λΉ λ₯΄κ²Œ 화면을 ν‘œμ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Non-RESTful μ‹œμŠ€ν…œ

Non-RESTful μ‹œμŠ€ν…œμ€ REST μ•„ν‚€ν…μ²˜μ˜ 원칙을 λ”°λ₯΄μ§€ μ•ŠλŠ” μ‹œμŠ€ν…œμ„ μ˜λ―Έν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ μ‹œμŠ€ν…œμ€ REST의 κΈ°λ³Έ 원칙 쀑 일뢀 λ˜λŠ” μ „ν˜€ μ μš©λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.
λΉ„RESTful μ‹œμŠ€ν…œμ—μ„œλŠ” μžμ›μ„ URI둜 ν‘œν˜„ν•˜λŠ” 것이 뢈λͺ…ν™•ν•˜κ±°λ‚˜ 일관성이 없을 수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, HTTP λ©”μ„œλ“œλ₯Ό μ˜¬λ°”λ₯΄κ²Œ μ‚¬μš©ν•˜μ§€ μ•Šκ±°λ‚˜, Hypermediaλ₯Ό ν™œμš©ν•˜μ§€ μ•ŠλŠ” λ“± REST μ•„ν‚€ν…μ²˜μ—μ„œ κ·œμ •ν•œ 원칙을 λ”°λ₯΄μ§€ μ•ŠλŠ” νŠΉμ„±μ„ 보일 수 μžˆμŠ΅λ‹ˆλ‹€.

RESTful μ‹œμŠ€ν…œ

RESTful μ‹œμŠ€ν…œμ€ REST의 κΈ°λ³Έ 원칙인 μžμ› 식별, μžκΈ°μ„œμˆ ν˜• λ©”μ‹œμ§€, HATEOAS(ν•˜μ΄νΌλ―Έλ””μ–΄ μ œμ–΄ μƒνƒœ) 등을 μ μš©ν•˜λŠ” μ‹œμŠ€ν…œμ„ κ°€λ¦¬ν‚΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ μ‹œμŠ€ν…œμ€ μΌκ΄€λœ URI, HTTP λ©”μ†Œλ“œμ˜ μ‚¬μš©, Hypermedia의 적극적인 ν™œμš©κ³Ό 같은 REST μ•„ν‚€ν…μ²˜μ˜ 원칙을 λ”°λ₯΄λ©°, 이λ₯Ό 톡해 ν™•μž₯μ„±κ³Ό μœ μ§€λ³΄μˆ˜μ„±μ΄ ν–₯μƒλ©λ‹ˆλ‹€.

Non-RESTful VS RESTful

REST μ•„ν‚€ν…μ²˜μ˜ 6가지 원칙

1.
μΈν„°νŽ˜μ΄μŠ€ 일관성 (Uniform Interface)
2.
λ¬΄μƒνƒœ (Stateless)
3.
캐싱 κ°€λŠ₯ (Cacheable)
4.
계측화 (Layered System)
5.
Code on Demand
6.
ν΄λΌμ΄μ–ΈνŠΈ/μ„œλ²„ ꡬ쑰 (Client/Server Architecture)

μΈν„°νŽ˜μ΄μŠ€ 일관성 (Uniform Interface)

일관적인 μΈν„°νŽ˜μ΄μŠ€λ‘œ λΆ„λ¦¬λ˜μ–΄μ•Ό ν•œλ‹€.
REST μΈν„°νŽ˜μ΄μŠ€λŠ” 일관성을 κ°€μ Έμ•Ό ν•©λ‹ˆλ‹€. μ΄λŠ” λ¦¬μ†ŒμŠ€μ— μ ‘κ·Όν•˜λŠ” 방법이 μΌκ΄€λ˜μ–΄μ•Ό 함을 μ˜λ―Έν•©λ‹ˆλ‹€. λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ μ •λ³΄λŠ” λ¦¬μ†ŒμŠ€ μ‹λ³„μžμ™€ ν•¨κ»˜ μš”μ²­λ˜λ©°, μ„œλ²„λŠ” λ¦¬μ†ŒμŠ€ μƒνƒœλ₯Ό ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μ „λ‹¬ν•©λ‹ˆλ‹€.

λ¬΄μƒνƒœ (Stateless)

각 μš”μ²­ κ°„ ν΄λΌμ΄μ–ΈνŠΈμ˜ μ½˜ν…μŠ€νŠΈκ°€ μ„œλ²„μ— μ €μž₯λ˜μ–΄μ„œλŠ” μ•ˆ λœλ‹€
μš”μ²­ κ°„ μƒνƒœ 정보λ₯Ό μœ μ§€ν•˜μ§€ μ•ŠλŠ” μ›μΉ™μž…λ‹ˆλ‹€. 각 μš”μ²­μ€ κ·Έ μš”μ²­ μžμ²΄μ— ν•„μš”ν•œ λͺ¨λ“  정보λ₯Ό 포함해야 ν•˜λ©°, μ„œλ²„λŠ” 각 μš”μ²­μ„ λ³„κ°œμ˜ μš”μ²­μœΌλ‘œ μ·¨κΈ‰ν•΄μ•Ό ν•©λ‹ˆλ‹€.

캐싱 κ°€λŠ₯ (Cacheable)

WWWμ—μ„œμ™€ 같이 ν΄λΌμ΄μ–ΈνŠΈλŠ” 응닡을 캐싱할 수 μžˆμ–΄μ•Ό ν•œλ‹€.
ν΄λΌμ΄μ–ΈνŠΈλŠ” 응닡을 캐싱할 수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. μ„œλ²„λŠ” 응닡에 μΊμ‹œ μ œμ–΄ 헀더λ₯Ό μΆ”κ°€ν•˜μ—¬ 캐싱 λ™μž‘μ„ μ‘°μ ˆν•  수 μžˆμŠ΅λ‹ˆλ‹€.

캐싱

캐싱은 자주 μ‚¬μš©λ˜λŠ” 데이터λ₯Ό 미리 μ €μž₯해두고 ν•„μš”ν•  λ•Œλ§ˆλ‹€ λΉ λ₯΄κ²Œ μ‚¬μš©ν•˜λ„λ‘ ν•˜λŠ” κΈ°μˆ μž…λ‹ˆλ‹€.

계측화 (Layered System)

ν΄λΌμ΄μ–ΈνŠΈλŠ” λŒ€μƒ μ„œλ²„μ— 직접 μ—°κ²°λ˜μ—ˆλŠ”μ§€, μ—°κ²°λ˜μ—ˆλŠ”μ§€λ₯Ό μ•Œ 수 μ—†λ‹€.
RESTλŠ” κ³„μΈ΅ν™”λœ ꡬ쑰λ₯Ό κ°€μ§‘λ‹ˆλ‹€. μ„œλ²„λŠ” λ‹€μ–‘ν•œ κ³„μΈ΅μœΌλ‘œ λ‚˜λ‰˜μ–΄ 있으며, ν΄λΌμ΄μ–ΈνŠΈλŠ” μ„œλ²„μ™€ 직접 ν†΅μ‹ ν•˜μ§€λ§Œ, μ‹€μ œ μ„œλ²„κ°€ μ²˜λ¦¬λ˜λŠ” μœ„μΉ˜λ₯Ό μ•Œ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

Code on Demand

μ„œλ²„κ°€ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ‹€ν–‰μ‹œν‚¬ 수 μžˆλŠ” λ‘œμ§μ„ μ „μ†‘ν•˜μ—¬ κΈ°λŠ₯을 ν™•μž₯μ‹œν‚¬ 수 μžˆλ‹€.
"Code on Demand"λŠ” λ¦¬μ†ŒμŠ€κ°€ μ„œλ²„μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈλ‘œ λ³΄λ‚΄μ§€λŠ” λ™μ•ˆμ— ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ μ‹€ν–‰ κ°€λŠ₯ν•œ μ½”λ“œλ₯Ό μ „μ†‘ν•˜μ—¬, ν΄λΌμ΄μ–ΈνŠΈκ°€ μ‹€ν–‰ν•  수 μžˆλŠ” κΈ°λŠ₯을 ν™•μž₯ν•˜λŠ” 원칙을 κ°€λ¦¬ν‚΅λ‹ˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈλŠ” 이 μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆμ–΄μ•Ό ν•˜λ©°, 일반적으둜 JavaScriptκ°€ κ°€μž₯ 일반적인 μ‚¬μš© μ‚¬λ‘€μž…λ‹ˆλ‹€.

ν΄λΌμ΄μ–ΈνŠΈ/μ„œλ²„ ꡬ쑰 (Client/Server Architecture)

ν΄λΌμ΄μ–ΈνŠΈ-μ„œλ²„μ˜ 각 νŒŒνŠΈκ°€ λ…λ¦½μ μœΌλ‘œ κ°œμ„ λ  수 μžˆλ„λ‘ ν•΄μ€€λ‹€.
RESTλŠ” ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„κ°€ λΆ„λ¦¬λ˜μ–΄μ•Ό ν•œλ‹€λŠ” μ›μΉ™μž…λ‹ˆλ‹€. μ„œλ²„λŠ” 데이터 μ €μž₯, 관리, λ°±μ—”λ“œ λ‘œμ§μ„ μ²˜λ¦¬ν•˜κ³ , ν΄λΌμ΄μ–ΈνŠΈλŠ” μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•˜κ³  μ‚¬μš©μž μš”μ²­μ„ μ„œλ²„λ‘œ μ „μ†‘ν•©λ‹ˆλ‹€.

REST μ•„ν‚€ν…μ²˜μ˜ URL λͺ…λͺ… κ·œμΉ™

λͺ…사 μ‚¬μš©

: URL은 λ¦¬μ†ŒμŠ€λ₯Ό λ‚˜νƒ€λ‚΄λ©°, λ¦¬μ†ŒμŠ€μ— λŒ€ν•œ λ™μž‘μ€ HTTP λ©”μ„œλ“œλ₯Ό 톡해 μˆ˜ν–‰λ˜λ―€λ‘œ, λͺ…사λ₯Ό μ‚¬μš©ν•˜μ—¬ λ¦¬μ†ŒμŠ€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

λ³΅μˆ˜ν˜• μ‚¬μš©

: λ¦¬μ†ŒμŠ€λ₯Ό λ‚˜νƒ€λ‚Ό λ•Œ λ³΅μˆ˜ν˜•μ„ μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, /users, /posts와 같이 λ¦¬μ†ŒμŠ€ λ³΅μˆ˜ν˜•μ„ μ‚¬μš©ν•©λ‹ˆλ‹€.

ν•˜μœ„ λ¦¬μ†ŒμŠ€λ₯Ό μœ„ν•œ 쀑첩 URL μ‚¬μš©

: 관계가 μžˆλŠ” λ¦¬μ†ŒμŠ€μ˜ 경우, 쀑첩 URL ꡬ쑰 (/super/sub) λ₯Ό μ‚¬μš©ν•˜μ—¬ 관계λ₯Ό λͺ…ν™•νžˆ ν•©λ‹ˆλ‹€.

ν•˜μ΄ν”ˆ(-) λŒ€μ‹  μ–Έλ”μŠ€μ½”μ–΄(_) μ‚¬μš©

: 가독성을 높이고 식별을 μ‰½κ²Œ ν•˜κΈ° μœ„ν•΄ 언더 μŠ€μ½”μ–΄(_)λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. (단, λ¦¬μ†ŒμŠ€ μ΄λ¦„μ˜ λ„μ–΄μ“°κΈ°λŠ” ν•˜μ΄ν”ˆ(-) μ‚¬μš©)

λ‹¨μˆœν•˜κ³  직관적인 URL

: URL은 λ¦¬μ†ŒμŠ€λ₯Ό μ‹λ³„ν•˜λŠ” 데 μ‚¬μš©λ˜λ©°, 이것은 직관적이고 λͺ…ν™•ν•΄μ•Ό ν•©λ‹ˆλ‹€. ν•˜λ‚˜μ˜ λ¦¬μ†ŒμŠ€μ— ν•˜λ‚˜μ˜ URL 을 λŒ€μ‘ν•˜λŠ” 것이 μ’‹μœΌλ©° 파일 ν™•μž₯자 (.html, .jsp λ“±)λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μŠ€ν”„λ§λΆ€νŠΈλ‘œ RESTful API κ΅¬ν˜„ν•˜κΈ°

1.
@RestController 클래슀 μ •μ˜
2.
GET, POST, PUT, DELETE 컨트둀러 λ©”μ†Œλ“œ μ •μ˜

@RestController 클래슀 μ •μ˜

/** * 🟒 RestFul * κ²Œμ‹œνŒ 컨트둀러 * - κ²Œμ‹œκΈ€ λͺ©λ‘ - [GET] - /boards * - κ²Œμ‹œκΈ€ 쑰회 - [GET] - /boards/10 * - κ²Œμ‹œκΈ€ 등둝 처리 - [POST] - /boards * - κ²Œμ‹œκΈ€ μˆ˜μ • 처리 - [PUT] - /boards * - κ²Œμ‹œκΈ€ μ‚­μ œ 처리 - [DELETE] - /boards/10 */ @Slf4j @RestController @RequestMapping("/boards") public class RestBoardController { }
Java
볡사

GET, POST, PUT, DELETE 컨트둀러 λ©”μ†Œλ“œ μ •μ˜

β€’
κ²Œμ‹œκΈ€ λͺ©λ‘ - [GET] - /boards
β€’
κ²Œμ‹œκΈ€ 쑰회 - [GET] - /boards/10
β€’
κ²Œμ‹œκΈ€ 등둝 처리 - [POST] - /boards
β€’
κ²Œμ‹œκΈ€ μˆ˜μ • 처리 - [PUT] - /boards
β€’
κ²Œμ‹œκΈ€ μ‚­μ œ 처리 - [DELETE] - /boards/10

κ²Œμ‹œκΈ€ λͺ©λ‘ - [GET] - /boards

/** * κ²Œμ‹œκΈ€ λͺ©λ‘ * [GET] * /boards * response : boardList * @return */ @GetMapping() public ResponseEntity<?> findAll() { log.info("[GET] - /board"); try { List<Board> boardList = boardService.list(); return new ResponseEntity<>(boardList, HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } }
Java
볡사

κ²Œμ‹œκΈ€ 쑰회 - [GET] - /boards/10

/** * κ²Œμ‹œκΈ€ 쑰회 * [GET] * /boards/{no} * request : id * response : board * @param id - κ²Œμ‹œκΈ€ 번호 * @return */ @GetMapping("/{no}") public ResponseEntity<?> find(@PathVariable("no") Integer no) { log.info("[GET] - /board/" + no); try { Board board = boardService.select(no); return new ResponseEntity<>(board, HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } }
Java
볡사

κ²Œμ‹œκΈ€ 등둝 처리 - [POST] - /board

/** * κ²Œμ‹œκΈ€ 등둝 * [POST] * /boards * request : boards * response : β­•, ❌ * @param board * @return */ @PostMapping() public ResponseEntity<?> create(@RequestBody Board board) { log.info("[POST] - /boards"); try { int result = boardService.insert(board); if( result == 0 ) return ResponseEntity.badRequest().build(); return new ResponseEntity<>("CREATED", HttpStatus.CREATED); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } }
Java
볡사

κ²Œμ‹œκΈ€ μˆ˜μ • 처리 - [PUT] - /boards

/** * κ²Œμ‹œκΈ€ μˆ˜μ • * [PUT] * /boards * request : boards * response : β­•, ❌ * @param board * @return */ @PutMapping() public ResponseEntity<?> update(@RequestBody Board board) { log.info("[PUT] - /board"); try { int result = boardService.update(board); if( result == 0 ) return ResponseEntity.badRequest().build(); return new ResponseEntity<>("UPDATED", HttpStatus.OK); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } }
Java
볡사

κ²Œμ‹œκΈ€ μ‚­μ œ 처리 - [DELETE] - /boards/10

/** * κ²Œμ‹œκΈ€ μ‚­μ œ * [DELETE] * /boards/{no} * request : no * response : β­•, ❌ * @param id * @return */ @DeleteMapping("/{no}") public ResponseEntity<?> delete(@PathVariable("no") Integer no) { log.info("[DELETE] - /boards/" + no); try { int result = boardService.delete(no); if( result == 0 ) return ResponseEntity.badRequest().build(); return ResponseEntity.ok().build(); } catch (Exception e) { return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } }
Java
볡사

Github (μ†ŒμŠ€μ½”λ“œ)