티스토리 뷰

URI 설계 시 고려 사항 

REST 서비스 프로젝트를 여러번 수행했지만 여전히 많은 시행 착오를 하고 있고 많은 도전을 받고 있습니다. 
왜 이렇게해야 하는지, 왜 이런 구조인지 ... 
URI에 넣을 내용인지 파라미터로 전달할 것인지 등등  
하지 말라고 그렇게 말해도 굳이 URI에 DELETE, UPDATE, GET등을 넣는 개발자도 많습니다. 

화면과 비즈니스 로직을 분리하고 BACK-END를 개발할 때 REST 서비스는 참 좋은 가이드가 됩니다. 
이 포스팅은 URI 설계에 대한 정답이라기 보다 그동안 시행 착오를 겪으면서 쌓은 경험으로 보시면 됩니다. 

1. 누가 설계 할 것인가? 

URI만으로 어떤 서비스인지 이해할 수 있어야 하며 설계의 일관성이 유지되는 것이 중요합니다. 또 RESTFUL SERVICE가 배포 되고 외부에서 이용하기 시작하면 고치기가 쉽지 않기 때문에 URI 설계는 업무 도메인에 대한 풍부한 이해가 있는 사람이 설계하는게 좋습니다. 

2. URI의 구성 

공통 구성(기본) + 리소스 구성

공통에 포함될 내용과 리소스는 어떻게 구성할 것인가?
URI 설계와 관련해서 간단한 예시를 통해 설명하도록 하겠습니다. 

2-1. 공통 구성

URI 설계시 공통적인 부분으로 버전, 구분, 권한에 대한 고려를 해 놓지 않으면 개발 완료 후 새로운 요청 사항이 추가 되었을 때 전체를 주소 체계를 수정해야 할 수도 있습니다.  

/[version]/[구분자]/[serviceID]


version : 외부에서 사용시 이전 버전과 새로운 버전을 동시에 서비스해야 할 수 있다. 

구분자 : 내부, 외부, vendor, category, division, section 등을 구분 할 수 있는 구분자 필요. 인터셉터, 필터 등에서 활용할 여지가 있기 때문에 확장성을 생각한다면 고려해서 설계해야 한다. 

serviceID : 권한, 통제 등에 사용

2-2. 리소스 구성

기본 규칙
  • 소문자 사용. 
  • 하이픈(-, hyphen) 사용 : space 대신 하이픈 사용, 일관성을 위해 under score 사용 안 함.
  • 확장자 사용 안함. 
  • URI 경로를 통해 리소스의 계층 관계를 표현한다. 
  • URI 마지막 문자로 "/"를 포함하지 않는다. 
  • CRUD 기능을 나타내는 것은 URI에 사용하지 않는다.
프로젝트 규칙
  • Collection 유형
    - 전체 조회 : 리소스-all
    - 페이징된 리소스 :  복수명사 
  • Document 유형
    - 단수명사, 명사 조합  
(회사나 프로젝트에서 이러한 룰을 정해서 전체 일관성을 유지하면 됩니다) 

/리소스(Collection) 
/리소스(Collection)/고유ID(Document) 
/리소스(Collection)/고유ID(Document) /하위리소스(Collection)
/리소스(Collection)/고유ID(Document) /하위리소스(Collection)/하위리소스고유ID(Document) 
리소스 : orders, customers, products, categories, stores, brands 등등
 
모두가 이해할 수 있고 지킬 수 있는 규칙을 만드는 것이 중요.

3. URI 설계 시 고려사항

3-1. URI에 속할 것인가? 파라미터로 전달할 것인가? 

URI는 Collection과 Document를 조회할 수 있는 ID를 가지며 이외 조건은 파라미터로 전달합니다. 

(해당 리소스의 필터 조건/옵션, 페이지 사이즈, 정렬)


3-2. 관점에 따른 설계

REST 설계는 관점과 요구 사항, 구조, 업무 도메인 특성에 따라 설계가 되어 지기 때문에 해석하기에 따라 여러 행태로 만들어 질 수 있습니다. 예를 들어 쇼핑몰에서 `고객`를 중심으로 한다면 `고객`은 쿠폰도 가지고 있고 장바구니, 주문 정보 등을 가지고 있습니다. 주문 정보에는 배송지, 결제정보, 주문한 상품 등이 있습니다. 상품에는 상품정보, Q&A, 사용기 등이 있습니다. 이런 경우 URI가 꼬리에 꼬리를 무는 형태로 설계하기 보다 상호 종속 여부 등을 고려해서 분리해야 할 필요가 있습니다. 


/고객/고객ID/주문/주문ID/상품/상품ID/구매후기/구매후기ID (X) 


위와 같은 경우에는 고객과 주문, 상품으로 나뉘어져야 합니다. 

/customers/1234/orders 

- 고객 주문 조회, 주문 ID는 customer에 종속되지 않습니다.

/orders/20190212000001

- 주문 상세 조회

/products/12345/reviews/90001 (

- 사용기는 상품에 종속이 되어 있기 때문에 하나로 묶여야 합니다. 

- 만약 사용기 만으로 서비스를 한다면 그에 따른 URI를 생성합니다. 


어떤 관점이냐에 따라 설계는 다양한 형태를 가질 수 있습니다. 


4. URI 설계 예시

게시판을 예시로 URI 설계 구성을 보겠습니다.   


게시판 구성 

  • 카테고리  
  • 제목  
  • 상태
  • 첨부파일들
  • 이미지들
  • 댓글들


URI Http Method Contents
/forum-all GET 전체 댓글
/forums GET 전체글 목록(페이징)
  POST 글 등록(첨부파일, 이미지 포함)
/forums/{forumId} GET  게시판 상세 조회 

PUT 게시판 수정(첨부파일, 이미지 포함) 

DELETE 게시판 삭제(첨부파일, 이미지 포함) 
/forums/{forumId}/comment-all GET 전체 댓글
/forums/{forumId}/comments GET 전체댓글 목록(페이징)
  POST 댓글 등록
/forums/{forumId}/comments/{commentId} GET  댓글 상세 조회 

PUT 댓글 수정

DELETE 댓글 삭제
/forums/{forumId}/file-all GET 전체 첨부파일
/forums/{forumId}/files GET 전체 첨부파일 목록(페이징)
  POST 첨부파일 등록
/forums/{forumId}/files/{fileId} GET  첨부파일 조회

PUT 첨부파일 수정

DELETE 첨부파일 삭제
/forums/{forumId}/image-all GET 전체 이미지
/forums/{forumId}/images GET 전체 이미지 목록(페이징)
  POST 이미지 등록
/forums/{forumId}/images/{imageId} GET  이미지 조회

PUT 이미지 수정

DELETE 이미지 삭제

제목, 내용, 상태, 정렬 순서, 페이징 사이즈, 페이지 번호 등은 파라미터로 처리합니다. 


카테고리 관점

업무가 카테고리에 따라 서비스 되어 져야 하는 경우 카테고리를 중심으로 설계될 수도 있습니다. 
URI Http Method Contents
/category-all GET 전체 카테고리
/categories GET 전체 카테고리 목록(페이징)
  POST 카테고리 등록
/categories/{categoryId} GET 카테고리 상세 조회
/categories/{cateId}/forums GET 카테고리의 모든 게시글들
/categories/{cateId}/products GET 카테고리의 모든 상품들

5. 마무리 

위 내용은 프로젝트 시작할 때 팀원들과 공유하는 내용입니다.
복잡하게 또 많은 설명을 하기 보다 간단한 예시를 통해 공유하는 것이 이해하기 쉬웠습니다. 

기본적인 설계 규칙을 공유하고 그외 별도로 예외에 대한 정의를 하는 것이 좋습니다. 
위에 예제는 모두 ID가 하나인데 어떤 경우 ID가 다섯개가 넘는 경우도 있고 CRUD 이외 행위에 대한 처리도 필요할 수 있습니다. 
공통을 관리하는 사람 또는 URI 설계하는 사람이 이런 부분 조정을 하거나 표준을 정할 필요가 있습니다. 


댓글
댓글쓰기 폼