본문 바로가기
Engineering/SW Design

[REST 설계] URI 식별자 설계

by 쿨쥰 2022. 5. 21.

URI 식별자는 어떤 패턴으로 설계 해야 할까?


이전 글 : REST API 소개

[Backend Engineering/REST API Design] - [REST 설계] REST API 소개

 

[REST 설계] REST API 소개

REST API 란 뭘까? REST API 소개  REST API 는 웹확장성이 고려된 웹 구조적 아키텍쳐 스타일에서 2000년대 초반 Representational State Transfer 의 약자로서 소개 되었다. 이는 아파치 HTTP 서버 프로젝트를..

skidrow6122.tistory.com

 

URI (Uniform Resource Identifier)

REST API 는 리소스를 나타 낼 때 URI 를 사용한다. 팀 버너스리는 그가 정의한 웹 아키텍쳐의 원칙에서 URI 의 불투명 성에 대해 다음과 같이 설명 하였다.

  • 식별자로 할 수 있는 유일한 일은 대상을 나타내는 것이다. 역참조를 할 때가 아니라면 다른 정보를 얻기 위해서 URI의 내용을 들여다 보지 말아야 한다.

클라이언트는 웹 연결 방식에 있어 URI를 불투명한 식별자로 취급해야한다.

따라서 REST API 설계자는 URI를 만들 때부터 REST API 리소스 모델을 클라이언트에 전달 할 수 있어야 한다.

 

URI의 형태 관련 규칙

규칙1) 슬래시 구분자는 계층 관계를 나타낸다.

슬래시는 path 내에서 리소스간 계층 관계를 나타내며 예시는 아래와 같다.

 

규칙2) URI 마지막 문자로 슬래시를 포함하지 않는다.

URI 경로 마지막에 있는 슬래시는 아무 의미가 없지만, 혼동을 줄 수 있으므로 REST API 마지막 글자에 슬래시가 오면 안되고, 클라이언트에 제공하는 링크에도 그런 API를 제공해서는 안된다.

 

규칙3) 하이픈 (-) 은 URI 가독성을 높이는데 사용한다.

URI 를 쉽게 읽고 해석하기 위해 긴 경로에 하이픈을 사용하여 가독성을 높일 수 있다. 특수문자나 공백이 들어갈경우 regex 를 통해 - 으로 대체 하는 로직을 풀어내는 것도 같은 맥락이다.

 

규칙4) 밑줄(_) 은 URI 에 사용하지 않는다.

그냥 사용하지 말자.

 

규칙5) URI 경로에는 소문자를 사용한다.

RFC 3986 표준에 따라 아래 두개의 URI는 다른 URI로 인식하며, 애초에 혼동을 방지 하기 위하여 대소문자를 섞어 쓰지 않도록 한다.

 

규칙6) 파일 확장자는 URI에 포함시키지 않는다.

웹에서 dot 은 URI에서 파일이름과 확장자를 구분하는 데 사용한다. 하지만 REST API에서는 메시지 바디 내용의 포맷을 나타내기 위한 파일 확장자를 URI안에 포함하지 않아도 된다.

대신 이 확장자는 미디어 타입에 의존하는데 Content-Type헤더를 통해 전달 되며, 메시지 바디의 내용을 어떻게 처리할 지 결정 한다.

 

리소스 모델링

URI 경로는 REST API의 리소스 모델을 다루는데, 경로 구문의 각 계층은 리소스 모델 계층에서 유일한 리소스임을 의미한다.

예를들어, http://api.example.com/entry/01/whatever 과 같은 URI 디자인이 있다면,

다음과 같은 자체 리소스 주소를 가진 URI가 있다는 것을 뜻한다.

 

용도 별 URI 경로 디자인

규칙7) 도큐먼트 이름으로는 단수 명사를 사용한다.

도큐먼트 리소스를 나타내는 URI는 단수 명사나 명사구를 포함하는 경로 부분으로 이름 짓는다. 예를 들어 한 명의 선수 도큐먼트를 나타내는 URI는 단수 형태가 되는 셈이다.

 

규칙8) 컬렉션 이름으로는 복수 명사를 사용한다.

컬렉션을 식별하는 URI는 복수 명사나 복수 명사구를 나타내는 명사로 이름 짓는다. 예를 들어 팀 내 선수 도큐먼트 들을 포함하는 컬렉션 URI 예시는 아래와 같다.

 

규칙9) 스토어 이름으로는 복수 명사를 사용한다.

스토어는 클라이언트에서 관리하는 리소스 저장소다. 스토어 리소스는 API클라이언트가 리소스를 넣거나 빼는 것, 지우는 것에 관여하고 스토어 스스로 새로운 리소스를 생성하지 못하기 때문에 새로운 URI를 만들지는 못한다. 예를 들면 즐겨찾는 선수 정보라고 한다면 favorites 가 스토어를 나타내는 좋은 예시이다.

 

규칙10) 컨트롤러 이름으로는 동사나 동사구를 사용한다.

컨트롤러 리소스는 절차적 개념을 모델화 한 것으로 실행 가능한 함수와 같아서 파라미터와 리턴 값이 있다. 따라서 프로그램에서 사용하는 함수 처, 컨트롤러 리소스를 나타내는 URI는 동작을 포함하는 이름으로 지어야 한다.

 

규칙11) 경로 중 변하는 부분은 유일한 값으로 대체 한다.

경로 부분 중 변수처럼 변환하여 유일한 식별자 값으로 자동으로 채워지기도 한다. 예를들어 변수를 세 개 (leagueId, teamId, playerId)운용한다면 다음과 같은 URI 템플릿이 구성 될 것이다.

이런 템플릿 형 URI에서는 REST API 자체나 클라이언트가 URI 템플릿에 있는 변수를 실제 값으로 대체 한다. 이때 각 변수에 들어가는 실제 값들이 유니크한 식별자를 가져야 함을 의미 한다. e.g. 시퀀스 넘버, UUID 등

 

규칙12) CRUD 기능을 나타내는 것은 URI에 사용하지 않는다.

HTTP 리퀘스트 메서드기능을 통해 CRUD를 표현하고 URI path 자체에 기능을 명시 하지 않는다. 따라서 아래의 예시 URI난 좋은 디자인이라 할 수 있다.

  • DELETE /users/1234

반면에 흔히 사용하는 아래의 패턴은 사용해서 안되는 디자인이다.

  • DELETE /deleteUser/1234

 

URI Query 디자인

URI 구성 요소인 쿼리는 유일한 리소스를 식별하는데 도움을 준다. 흔히 볼 수 있는 쿼리 스트링으로서의 예시는 아래와 같다.

/send-sms 까지는 sms 문자를 보내고자 하는 액션을 수행하는 컨트롤러 리소스 URI 이다.

?text=homerun 은 homerun 이라는 sms 문자를 보내는 컨트롤러 리소스 URI 이다.

URI 쿼리 구성요소는 파라미터들로 되어있, 이 파라미터는 경로의 구성 요소에 의해 계층적으로 식별된 리소스의 변형이나 파생으로 해석 될 수 있다.

 

규칙13) URI 쿼리 부분으로 컬렉션이나 스토어를 필터링 할 수 있다.

URI 쿼리는 컬렉션이나 스토어의 검색 기준으로 사용하기에 적합하다.

  • GET /players
  • GET /players?role=pitcher

첫번째 URI에 대한 응답 메시지는 players 컬렉션에 있는 모든 선수들의 리스트이다.

두번째 URI에 대한 응답 메시지는 players 컬렉션에 있는 선수 중 role 의 값이 pitcher 즉 투수들만 리턴한다.

 

규칙14) URI 쿼리는 컬렉션이나 스토어의 결과를 페이지로 구분하여 나타내는데 사용해야 한다.

REST API 클라이언트는 쿼리 구성요소를 사용하여 컬렉션이나 스토어의 결과를 pageSize, pageStartIndex 같은 파라키터 값으로 페이지화 한다.pageSize 는 응답에 반환되는 element 의 최대값을 나타내는 데 사용 된다. 그리고 pageStartIndex 파라미터는 응답에 반환되는 첫번째 element의 index를 나타낸다.

  • GET /users?pageSize=25&pageStartIndex=50

이것은 50페이지로부터 최대 75페이지 까지만 받는 의미를 가지고 있다.

만약 URI 쿼리로 클라이언트의 페이지나 필터링의 요구사항에 대응 할 수 없다면, URI 쿼리 파트 대신 리퀘스트의 바디 부분에 좀더 복잡한 파라미터를 실어서 받는 특별한 컨트롤러가 고려 될 수 있다.

  • POST /users/search

 


REST API 설계시 가장 먼저 드는 고민인 리소스 를 식별하기 위한 URI에 대한 설계 패턴을 알아 보았다.

다음 글에서는 HTTP 요청 메서드를 활용한 인터랙션 설계에 대해 다뤄 본다.

'Engineering > SW Design' 카테고리의 다른 글

디자인 패턴 개요  (1) 2023.05.19
[REST 설계] 패턴 예제  (0) 2023.05.07
[REST 설계] 헤더 / 바디 디자인  (0) 2023.05.01
[REST 설계] HTTP 메소드와 응답코드  (0) 2023.04.25
[REST 설계] REST API 소개  (0) 2022.05.20

댓글