๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒฟ Spring

[Spring boot/RESTful] REST API ๋ฒ„์ „ ๊ด€๋ฆฌ

by nitronium102 2022. 2. 18.

๋ฒ„์ „ ๊ด€๋ฆฌ

๋‹จ์ˆœํ•˜๊ฒŒ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ฃผ๋Š” ํ•ญ๋ชฉ์„ ์ œ์–ดํ•˜๋Š” ์šฉ๋„๊ฐ€ ์•„๋‹ˆ๋ผ
REST API์˜ ์„ค๊ณ„๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์กฐ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋„ ๋ฒ„์ „์„ ๋ณ€๊ฒฝํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ์–ด๋– ํ•œ API ๋ฒ„์ „์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€ ๋ช…์‹œํ•ด์•ผ ํ•œ๋‹ค.


์ข…๋ฅ˜

1) URI Versioning : Twitter

2) Request Parameter Versioning : Amazon

3) (Custom) Headers Versioning(MIME) : Microsoft

4) Media type Versioning(content negotiation, accept header) : Github

 

  • ์ผ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๊ฐ€๋Šฅ : URI, Request Parameter
  • ์ผ๋ฐ˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ๋ถˆ๊ฐ€ : (Custom) Headers Versioning, Media type Versioning

 

์œ ์˜ ์‚ฌํ•ญ

  • URI Pollution : ๋„ˆ๋ฌด ์ง€์ €๋ถ„ํ•˜๊ฑฐ๋‚˜ ๊ณผ๋„ํ•˜๊ฒŒ ์ •๋ณด๋ฅผ ํ‘œ๊ธฐํ•˜๋Š” ๊ฒƒ์€ ์ง€์–‘
  • Misuse of HTTP headers : ์ž˜๋ชป๋œ ํ—ค๋”๊ฐ’ ์ฃผ์˜
  • Caching : ์ ์ ˆํžˆ ์บ์‹œ ์‚ญ์ œํ•ด์„œ ์ œ๋Œ€๋กœ ๋œ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ
  • Can we execute the request on browser?
  • API Documentation

 

REST API ๋ฒ„์ „ ๊ด€๋ฆฌ

Richardson Maturity Model

 

Richardson Maturity Model

The model of dividing the REST compliant services to identify their maturity level - is called Richardson Maturity Model.

restfulapi.net

๊ธฐ๋ณธ ์„ค์ •

// ๋ฐ˜ํ™˜๋ฐ›์€ User๋ฅผ UserV2๋กœ ๋ณ€ํ™˜
UserV2 userV2 = new UserV2();

// ๋‘ ์ธ์Šคํ„ด์Šค ๊ฐ„์— ๊ณตํ†ต๋œ ํ•„๋“œ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ํ•ด๋‹น ๊ฐ’์„ copyํ•จ
BeanUtils.copyProperties(user, userV2); // id, name, joinDate, password, ssn
userV2.setGrade("VIP");

 

URL์„ ์ด์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

url์— ๋ฒ„์ „์„ ํ‘œ์‹œํ•จ์œผ๋กœ์จ ๋ฒ„์ „์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฒ„์ „ ๊ด€๋ฆฌ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์†Œ์Šค ์ฝ”๋“œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ œ๊ณตํ•˜๋ ค๋Š” ์„œ๋น„์Šค์˜ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด์„œ๋„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

@GetMapping("/v1/users/{id}") 
public MappingJacksonValue retrieveUserV1(@PathVariable int id) { ... }

 

Request Parameter๋ฅผ ์ด์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

params = " " ์‚ฌ์šฉ

// ๋ฐ์ดํ„ฐ ๋’ค์— ๋ฒ„์ „์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ์ถ”๊ฐ€์ ์œผ๋กœ ์ „๋‹ฌ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— URI ๋’ค์— "/"๊ฐ€ ๋ถ™๋Š”๋‹ค
@GetMapping(value = "/users/{id}/", params = "version=1")

http://localhost:8088/admin/users/1/?version=1 ๋ฐฉ์‹์œผ๋กœ ํ˜ธ์ถœ

 

Header๋ฅผ ์ด์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

@GetMapping(value = "/users/{id}", headers = "X-API-VERSION=2")

MIME ํƒ€์ž…์„ ์ด์šฉํ•œ ๋ฒ„์ „ ๊ด€๋ฆฌ

MIME ํƒ€์ž… → Multi-Purpose Internet Mail Extension(ํŒŒ์ผ ๋ณ€ํ™˜)

์ด๋ฉ”์ผ๊ณผ ํ•จ๊ป˜ ์ „์†ก๋˜๋Š” ๋ฉ”์ผ๋ฅผ ํ…์ŠคํŠธ ๋ฌธ์ž๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ด๋ฉ”์ผ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•

// ์ œ๊ณตํ•˜๊ณ ์ž ํ•˜๋Š” MIME ํƒ€์ž… ์ง€์ •
// ๊ธฐ์กด์— ์—†๋˜ ์ƒˆ๋กœ์šด ๊ฐ’ -> application
// ๋ฒ„์ „ ์ด๋ฆ„ : appv1
// ์ „๋‹ฌ ์‹œํ‚ค์กฐ์ž ํ•˜๋Š” ํƒ€์ž… : json
@GetMapping(value = "/users/{id}", produces = "application/vnd.company.appv1+json")

๋Œ“๊ธ€