처음 해보는 Spring Framework 미션. 나는 요구 사항을 모두 만족시키고 리뷰 요청을 보냈다. 그리고 아래와 같은 리뷰를 받았다.

피드백

스프링 미션을 진행하면서 URI에대한 고민을 잠깐 했지만, 현재 고민해야 될 내용이 아니라고 생각하고 넘어갔다. 하지만 내 생각은 틀렸다. 이번 기회를 통해 REST API에 대해 좀 공부해보고 그 내용을 정리해본다.

REST란

월드 와이드 웹과 같은 신뢰성이 있고 확장성이 있는 분산 시스템을 구축하기위한 아키텍쳐 디자인 제약의 모음이다. 여기서 ‘신뢰성’은 ‘어떤 컴포넌트에 장애가 발생하더라도 분산 시스템이 서비스를 제공할 수 있는 능력’정도로 이해했다. 그리고 ‘확장성’은 ‘작업을 처리할 수 있는 양이 지속적으로 발전될 수 있는 능력’이라고 이해했다. REST를 사용하면 클라이언트와 서버를 분리할 수 있기때문에, 확장성이 높고, 유연하게 사용할 수 있다. 여기서 REST의 제약들을 준수한 시스템을 RESTful하다고 일컫는다. 여기서 REST는 표준이 아니라 하나의 아키텍처 스타일이라는 것에 유의해야된다.

REST의 6가지 제약 조건

  • 클라이언트-서버 구조: 사용자 인터페이스 문제와 데이터 저장 문제를 분리한다. 이를 통해 여러 플랫폼에서 사용자 인터페이스를 이식할 수 있도록 개선한다. 또한 서버 컴포넌트들을 단순화 시킬 수있다.
  • 무상태(Stateless): 클라이언트에서 서버로 보내는 요청에 이해에 필요한 모든 정보를 포함해야된다. 서버는 클라이언트의 상태를 저장하면 안되며, 세션 상태는 전적으로 클라이언트에서 유지해야된다. 서버가 상태를 관리할 필요가 없기 때문에 구현이 더 단순화된다.
  • 캐시: 서버의 응답 내에 있는 데이터를 캐싱할 수 있다. 응답을 캐싱하게되면 클라이언트의 동등한 요청에 데이터를 재사용할 수 있게된다. 이 캐시를 통해 일부 통신을 일부 제거할 수 있게되어 성능을 향상시킬 수 있다.
  • 인터페이스 일관성: 클라이언트에 의존하지 않고, 표준화 된 인터페이스를 갖도록한다.
  • 계층화(Layered System): 클라이언트나 서버에 미들웨어 컴포넌트를 추가할 수 있도록 해야된다. 하지만 Client-Server 사이에서는 그 컴포넌트가 추가되었는지, 다른 서비스와 추가로 통신하는지에는 관심이 없다.
  • Code-On-Demand: 선택적인 제약 조건이다. 서버로부터 받은 프로그램을 클라이언트에서 실행할 수 있어야된다.

REST의 구현

REST를 구현하는 대표적인 사례가 HTTP를 활용한 방법이다. 웹 환경 통신의 대부분이 HTTP를 사용하기 때문에 REST는 무조건 HTTP로 구현된다고 생각한다. 사실 REST는 WAP, WebRTC, MQTT 등의 다른 프로토콜로도 구현이 가능하다. 아래는 HTTP를 이용하여 REST를 구현할 때 적용되는 규칙들이다.

HTTP 메서드를 사용하여 요청의 의미를 가지게 하기

HTTP 메서드에서 주로 사용하는 것은 아래 5가지가 있다. 이 메서드롤 리소스에 대응하는 작업의 의미를 가지게한다.

HTTP 메서드 CURD 전체 컬렉션(e.g. /customers) 특정 항목(e.g. /customers/{id})
POST Creat 201(Created): ‘Location’ 헤더에 생성된 항목의 ID를 포함하여 링크를 남긴다 (e.g /customers/{id}) 404(Not Found), 만약 이미 존재한다면 409(Conflict)
GET Read 200(OK): customers의 리스트. 목록이 크다면 pagination, sort, filter을 사용할 수 있다 200(OK), 만약 ID가 없거나 유효하지 않은 경우 404(Not Found)
PUT Update/Replace 컬렉션의 모든 리소스를 교체하려는 것이 아니면 405(Method Not Allowed) 200(OK), 만약 ID가 없거나 유효하지 않은 경우 404(Not Found)
PATCH Update/Modify 컬렉션 자체를 수정하려는 것이 아니면 405(Method Not Allowed) 200(OK) 또는 204(No Content), 만약 ID가 없거나 유효하지 않은 경우 404(Not Found)
DELETE Delete 컬렉션 전체를 삭제하려는 경우가 아니라면 405(Method Not Allowed) 200(OK) 또는 204(No Content), 만약 ID가 없거나 유효하지 않은 경우 404(Not Found)
  • PUT과 PATCH의 차이

    처음 Update를 위한 메서드가 2개라 혼란스러울 수 있다. 이를 이해하기 위해서는 멱등성이라는 개념을 알아야된다. 멱등성은 동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니는지를 나타내는 성질이다. 대표적으로 GET, PUT, DELETE가 멱등성을 가지고, POST, PATCH는 멱등성을 가지지 않는다. PUT의 경우에는 요청의 body 내용을 그대로 리소스를 교체하게 되지만, PATCH는 사이드 이펙트가 있는 업데이트다.

적절한 리소스 이름 제공하기

적절한 리소스 이름은 API의 이해도를 높일 수 있다. 리소스는 URI 이름을 통해 계층적으로 표시되므로 클라이언트에게 친숙하고 이해하기 쉬운 형태여야된다. 여기서 리소스란 무엇일까? REST가 처음 소개된 로이 필딩의 논문 “Architectural Styles and the Design of Network-based Software Architectures“에 따르면 정보의 추상화다. 문서, 이미지, 임의의 서비스, DB 테이블의 한 행 등 하이퍼 텍스트의 참조 대상이 될 수 있는 모든 정보를 추상화한 것에 해당한다. 아래는 URI 경로(리소스 이름) 디자인에 대한 몇 가지 규칙이다.

  • 쿼리 문자열 대신 URI에 식별자를 사용해라.
    • 좋음 예: /users/12345
    • 나쁜 예: /api?type=users&id=23
  • URL의 계층적 특성을 활용해서 구조를 나타낸다.
  • 데이터 관점이 아니라 소비자 관점의 디자인을 해야된다.
  • 리소스의 이름은 명사 여야한다. 요청의 행동에 대한 부분은 HTTP 메서드로 표현한다.
  • 컬렉션을 나타낼 때는 복수 형으로 나타내야된다.
    • 좋은 예: /customers/33245/orders/8769/lineitems/1
    • 나쁜 예: /customer/33245/order/8769/lineitem/1
  • URL에 컬렉션의 표현을 포함하지 않는다(예: customer-list)
  • URL 세그먼트에 소문자를 사용하고 하이픈(‘-‘)으로 단어를 구분한다. 일부 서버에서는 대소 문자를 무시하기 때문이다.
  • 의미가 있는 세그먼트만 남겨서 URL을 최대한 짧게 남긴다.

참고 자료

https://developer.mozilla.org/ko/docs/Glossary/REST

https://d2.naver.com/helloworld/206816

https://sanghaklee.tistory.com/61

http://haah.kr/2017/05/24/rest-the-dissertation-summary/

https://www.chakray.com/advantages-of-rest-api/

댓글남기기