REST API 모범 사례 : 매개 변수를 어디에 둘 것인가? [닫은]


348

REST API는 최소한 두 가지 방법으로 매개 변수를 가질 수 있습니다.

  1. 의 URL 경로의 일부로서 (예 /api/resource/parametervalue )
  2. 쿼리 인수로 (예 /api/resource?parameter=value )

가장 좋은 방법은 무엇입니까? 1 사용시기와 2 사용시기에 대한 일반적인 지침이 있습니까?

실제 예 : Twitter는 간격을 지정하기 위해 쿼리 매개 변수를 사용합니다. ( http://api.twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321)

이러한 매개 변수를 URL 경로에 배치하는 것이 더 나은 디자인으로 간주됩니까?

답변:


254

모범 사례가 문서화되어 있으면 아직 찾지 못했습니다. 그러나 URL에 매개 변수를 넣을 위치를 결정할 때 사용하는 몇 가지 지침은 다음과 같습니다.

선택적 매개 변수는 쿼리 문자열에 쉽게 넣는 경향이 있습니다.

매개 변수 값이 기존 리소스와 일치하지 않을 때 404 오류를 반환하려면 경로 세그먼트 매개 변수를 사용하는 경향이 있습니다. 예를 들어 /customer/232, 232는 유효한 고객 ID가 아닙니다.

그러나 빈 목록을 반환하려면 매개 변수를 찾을 수 없을 때 쿼리 문자열 매개 변수를 사용하는 것이 좋습니다. 예 :/contacts?name=dave

매개 변수가 URI 공간의 전체 서브 트리에 영향을주는 경우 경로 세그먼트를 사용하십시오. 예를 들어 언어 매개 변수 /en/document/foo.txt/document/foo.txt?language=en

고유 식별자가 쿼리 매개 변수가 아닌 경로 세그먼트에있는 것을 선호합니다.

URI에 대한 공식 규칙은이 RFC 사양에 나와 있습니다 . URI를 매개 변수화하기위한 규칙을 정의하는 또 다른 매우 유용한 RFC 스펙도 있습니다 .


5
공식 규칙 URI와 임시 sepc는 정말 유용하고 흥미로 웠습니다! :-)
KajMagnus 10

1
404 오류 테스트는 쿼리 매개 변수, 헤더 또는 요청 본문에 속하는 경로에 정보를 넣지 않도록 도와줍니다. 지적 해 주셔서 감사합니다!
Kevin Condon

152

늦은 답변이지만 공유 된 내용, 즉 요청에 여러 유형의 "매개 변수"가 있다는 점에 대한 통찰력을 추가 할 것입니다.이를 고려해야합니다.

  1. 로케이터-예를 들어 ID 또는 작업 /보기와 같은 리소스 식별자
  2. 필터-결과 집합을 검색, 정렬 또는 좁히는 매개 변수입니다.
  3. 상태-예를 들어 세션 식별, API 키, whatevs.
  4. 내용-예를 들어 저장 될 데이터.

이제 이러한 매개 변수가 들어갈 수있는 다른 위치를 살펴 보겠습니다.

  1. 요청 헤더 및 쿠키
  2. URL 쿼리 문자열 ( "GET"vars)
  3. URL 경로
  4. 본문 쿼리 문자열 / 멀티 파트 ( "POST"변수)

일반적으로 상태 정보 유형에 따라 헤더 또는 쿠키에 상태를 설정하려고합니다. 우리 모두 이것에 동의 할 수 있다고 생각합니다. 필요한 경우 사용자 정의 http 헤더 (X-My-Header)를 사용하십시오.

마찬가지로 Content는 요청 본문에 하나의 장소 만 있으며 쿼리 문자열 또는 http multipart 및 / 또는 JSON 컨텐츠로 요청 본문에 있습니다. 이는 서버가 컨텐츠를 보낼 때 서버로부터받는 것과 일치합니다. 따라서 당신은 무례하고 다르게 행동해서는 안됩니다.

"id = 5"또는 "action = refresh"또는 "page = 2"와 같은 로케이터는 mysite.com/article/5/page=2각 부분의 의미를 부분적으로 알고있는 곳 (예 : 기사 및 5는 분명히 id가 5) 인 기사 유형의 데이터를 가져오고 추가 매개 변수는 URI의 일부로 지정됩니다. 형식은 page=2이거나 page/2URI의 특정 지점 이후에 "폴더"가 키-값 쌍이라는 것을 알고있는 경우 일 수 있습니다.

필터는 항상 올바른 데이터를 찾는 데 필요한 부분이므로 로케이터가 단독으로 리턴하는 항목의 서브 세트 또는 수정 사항 만 리턴하기 때문에 항상 쿼리 문자열로 이동합니다. mysite.com/article/?query=Obama(서브 세트) 의 검색은 필터이므로 /article/5?order=backwards(수정)도 마찬가지입니다 . 그것이 무엇이라고 불리는 것이 아니라 그것이 무엇인지 생각하십시오!

"view"가 출력 형식을 결정 mysite.com/article/5?view=pdf하면 원하는 리소스를 원점으로 옮기지 않고 찾은 리소스의 수정을 반환하므로 필터 ( )입니다. 대신 기사의 특정 부분을 확인하면 ( mysite.com/article/5/view=summary) 로케이터입니다.

리소스 집합을 좁히는 것은 필터링입니다. 리소스 내에서 특정 항목을 찾는 중입니다 ... duh. 서브 세트 필터링은 많은 수의 결과를 리턴 할 수 있습니다 (0까지). 위치는 항상 해당 특정 인스턴스 (있는 경우)를 찾습니다. 수정 필터링은 수정을 제외하고 로케이터와 동일한 데이터를 반환합니다 (수정이 허용되는 경우).

사람들이 물건을 넣을 곳을 잃어 버린 경우 유레카 순간을 사람들에게 줄 수 있기를 바랍니다.


2
id필터가 아닌가? 그것은 자원의 일부를 반환
조나단.

13
@홍옥. 특정 리소스, 즉 기사 번호 5를 반환하지 않습니다. 필터는 항상 리소스 모음에서 검색 범위를 좁히는 방법입니다. 특정 리소스 만 원한다면이를 얻을 수있는 지정된 방법이 있어야합니다. 필터링은 여러 리소스를 반환 할 수 있음을 의미합니다. ID는 필터가 아니며 명확한 단일 리소스입니다. RANGE ID가있는 경우 범위에 ID가 하나만 포함되어 있어도 필터가됩니다. 필터에 리소스 유형도 포함 된 경우 아티클뿐만 아니라 ID 5의 모든 리소스가 반환됩니다.
Tor Valamo

1
@Jonathan .: DarrelMiller가 언급했듯이, 알 수없는 ID의 경우 object / id에 대한 요청이 404를 반환 할 것으로 예상하지만 object? id = id가 반환되고 목록을 비울 것으로 예상합니다. 또한 모든 유형의 필터링 / 하위 설정이 목록을 반환해야한다고 생각합니다.
njzk2

1
페이지는 리소스 (페이지 모음)의 필터 일 수 있지만 동시에 해당 모음 내의 특정 자원이므로 페이지는 어렵습니다. 필자는 항상 필터가 아닌 로케이터로 기사 페이지를 요청합니다. 그러나 페이지는 사용자 목록과 같이 무언가 목록의 필터 일 수 있습니다. 그러나이 페이지는 본질적으로 "항목에서 시작하여 항목 (page-1)*perpage표시 "라고하는 구분 기호 perpage입니다. 필터로 사용하는 것은 정확하지만 다른 이유가 있습니다. "페이지"라고 부르는 것은 기술적으로 잘못되었습니다. 더 의미 올바른 또는 "startAt" "에서"를 호출하는 것입니다
토르 Valamo

1
(계속) "페이지"의 의미 적 의미는 변경되지 않는 특정 리소스라는 것입니다. 실제 인쇄에서 나옵니다. 우리가 책이나 인쇄물을 한 번도 본 적이 없다면 "페이지"는 실제로 단어가 아닐 것입니다. 동적 항목 목록이있는 경우 "페이지"로 분할 된 경우 숫자, 알파벳 또는 항목 별 특정 시작 지점과 "페이지 당 수"필터를 제공해야합니다. 목록에서 무언가를 참조하려면 구체적인 내용을 원합니다. 또한 5 페이지로 이동하여 내부 perpage를 20 대신 50으로 변경
했다는

21

디자인에 따라 다릅니다. REST over HTTP에는 URI에 대한 규칙이 없습니다 (주로 고유 한 것임). 종종 맛과 직관 문제에 관한 것입니다 ...

나는 다음과 같은 접근 방식을 취합니다.

  • url path-element : 자원 및 해당 path-element는 디렉토리 탐색 및 하위 자원을 형성합니다 (예 : / items / {id}, / users / items). 확실하지 않은 경우 동료에게 순회한다고 생각하고 "다른 디렉토리"에서 가장 가능성이 높은 경로 요소가 올바른 선택이라고 생각하면
  • url 매개 변수 : 실제로 순회가없는 경우 (여러 쿼리 매개 변수가있는 검색 리소스가 그 좋은 예입니다)

1
실제로 URI가 어떻게 보이는지에 대한 명확한 규칙이 있으며 RESTful URI에 적용하는 방법에 대한 모호성은 거의 없습니다.
DanMan

18

IMO 매개 변수는 쿼리 인수보다 낫습니다. url은 리소스를 식별하는 데 사용되는 반면, 추가 된 쿼리 매개 변수는 원하는 리소스 부분, 리소스의 상태 등을 지정합니다.


7
실제로 경로와 쿼리는 자원을 식별하기 위해 조합되어 사용됩니다. 이것은 RFC 3986에서 명확 해졌다 http://labs.apache.org/webarch/uri/rfc/rfc3986.html#query
Darrel Miller

@DarrelMiller 나는 이것이 오래된 게시물이라는 것을 알고 있지만 쿼리 매개 변수가 리소스를 식별하는 데 사용된다는 사실에 대해 더 알고 싶습니다. 제공하신 링크가 이제 종료되었습니다. RFC3986을 살펴 봤지만이 사실을 어떻게 추론했는지 알 수 없습니다. 또한 정의에 따라 식별자 매개 변수는 선택 사항이 아니므로 식별을 위해 쿼리 매개 변수를 사용하는 것이 적절하지 않은 것으로 보입니다.
Mickael Marrache


2
@DarrelMiller 감사합니다! 내 질문은 일반적으로 중간 HTTP 구성 요소가 쿼리 문자열을 포함하는 요청의 응답을 캐시하지 않는다는 사실에서 비롯됩니다. 따라서 쿼리 매개 변수는 일부 기준에 따라 리소스를 검색하고 리소스를 고유하게 식별하지 않는 것이 더 적합한 것으로 보입니다.
Mickael Marrache

17

REST 구현에 따라

1) 경로 변수 는 연락처 또는 노래와 같은 자원에 대한 직접 조치에 사용됩니다. 예 :
GET 등 / api / resource / {songid} 또는
GET 등 / api / resource / {contactid}

2) Query perms / argument 는 노래의 메타 데이터와 같은 간접 리소스에 사용됩니다.


5
실제로 REST 표준 은 없습니다 . 당 위키 백과 : 달리 SOAP 기반의 웹 서비스, RESTful 웹 API에 대한 "공식적인"표준이 없다 [14]. 이는 프로토콜 인 SOAP와 달리 REST가 아키텍처 스타일이기 때문입니다. REST는 표준은 아니지만 웹과 같은 RESTful 구현은 HTTP, URI, XML 등과 같은 표준을 사용할 수 있습니다.
DavidRR

나는 2 접근법을 좋아하지 않는다. 오히려 / api / genres? songid = 123 또는 / api / songs / {song-id} / genres를 선호합니다
Bart Calixto

1
@Bart, Satish는 기본적으로 선호도라고 언급 한 경로의 변수를 참조했습니다. 그러나 장르가 실제로 메타 데이터이고 노래 엔터티 / 리소스의 필드가 아닌 경우 더 많은 감성을 볼 수 있습니다. 그것에 쿼리 문자열을 사용하는 ..
Brett Caswell

@BrettCaswell은 그것을 얻었다! 지적 해 주셔서 감사합니다. 정말 감사합니다!
Bart Calixto

16

유니버스 리소스 로케이터가 제공하는 "컨텍스트"에 대해 데이터를 "포장"하고 게시합니다. 이는 로케이터를위한 # 1을 의미합니다.

# 2로 한계를 극복하십시오. # 1보다 POST를 선호합니다.

참고 : 제한 사항은

POST in POST 매개 변수 내용의 최대 크기가 있습니까?

GET in GET 요청의 길이에 제한이 있습니까? 그리고 _GET에서 URL 매개 변수의 최대 크기

ps 이러한 제한은 클라이언트 기능 (브라우저) 및 서버 (구성)를 기반으로합니다.


추가 기능 : 재치있는 노선 따라서 ALTER 코드 필요없이 진화 된 기능을 제공합니다 (헤더를 통해 구별) 버전을 가질 수 소비하는 당신이로 작성하는 것이 나머지-전체 (API) 코드 restify -> 버전 화 된 경로에 대한보기
DGM

5

URI 표준 에 따르면 경로는 계층 매개 변수에 대한 것이고 쿼리는 비 계층 매개 변수에 대한 것입니다. Ofc. 그것은 당신에게 계층적인 것이 매우 주관적 일 수 있습니다.

여러 URI가 동일한 리소스에 할당 된 상황에서는 식별에 필요한 매개 변수를 경로에, 표현을 작성하는 데 필요한 매개 변수를 쿼리에 넣는 것을 좋아합니다. (이 방법으로 라우팅하기가 더 쉽습니다.)

예를 들면 다음과 같습니다.

  • /users/123/users/123?fields="name, age"
  • /users/users?name="John"&age=30

지도 축소를 위해 다음 접근법을 사용하고 싶습니다.

  • /users?name="John"&age=30
  • /users/name:John/age:30

따라서 URI를 구성하는 방법은 실제로 귀하와 서버 측 라우터에 달려 있습니다.

참고 :이 매개 변수는 쿼리 매개 변수입니다. 실제로 당신이하고있는 일은 간단한 쿼리 언어를 정의하는 것입니다. 복잡한 쿼리 (과 같은 연산자, 또는보다 큰 연산자 등을 포함)에 따라 기존 쿼리 언어를 사용하는 것이 좋습니다. URI 템플릿 의 기능 은 매우 제한적입니다 ...


4

종종 클라이언트 쪽 프로그래머가 쿼리 인수를 선호합니다. 또한 나를 위해 URL 경로를 매개 변수와 분리하고 명확성을 추가하며 더 많은 확장 성을 제공합니다. 또한 URL / URI 건물과 매개 변수 작성기 사이에 별도의 논리를 가질 수 있습니다.

나는 일종의 나무가 있다면 manuel aldana가 다른 옵션에 대해 말한 것을 좋아합니다. 사용자 별 부품이 그처럼 트리밍되는 것을 볼 수 있습니다.


4

단단하고 빠른 규칙은 없지만, 내가 사용하고 싶은 순수하게 개념적인 관점에서 볼 때 경험하는 규칙은 간단히 다음과 같이 요약 할 수 있습니다. . 지금까지는 도움이되지 않을 것입니다 ... REST API를 사용 GET하면 PUT, 및을 사용하여 단일 리소스를 처리하는 주요 방법이 DELETE있습니다. 따라서 경로에서 무언가를 표현해야하는지 또는 매개 변수로 표현해야하는지 여부는 해당 방법이 해당 표현에 적합한 지 여부로 줄일 수 있습니다. PUT그 길에서 합리적으로 무언가를 원하십니까 ? 당신은 물론PUT 어디에서나 무언가를 처리하고 백엔드를 구부려 처리 할 수 ​​있지만PUT불필요하게 상황에 맞는 버전이 아닌 실제 리소스를 나타내는 것. 컬렉션의 경우도 마찬가지입니다 POST. 특정 컬렉션에 추가하고 싶을 경우 URL이 적합 POST합니다.

일부 경로는 어느 정도 재량 적이며 사용에 의존하는 부모 자원의 자녀에게 어느 정도 양을 가리킬 수 있기 때문에 여전히 회색 부분을 남겨 둡니다. 이것이 이끌어내는 한 가지 어려운 점은 기본 리소스가 없기 때문에 모든 유형의 전이 표현을 쿼리 매개 변수를 사용하여 수행해야한다는 것입니다.

원래 질문 (Twitter 's API)에 제공된 실제 예에 응답하여 매개 변수는 계층 구조가 아닌 자원 상태를 필터링하는 전이 쿼리를 나타냅니다. 이 특정 예제에서 이러한 제약 조건으로 표시되는 컬렉션에 추가하는 것은 전적으로 비합리적이며, 쿼리는 객체 그래프의 관점에서 의미가있는 경로로 표현할 수 없습니다.

이러한 유형의 리소스 지향적 관점을 채택하면 도메인 모델의 객체 그래프에 쉽게 직접 매핑 할 수 있으며 API의 논리가 명확 해지면 모든 것이 매우 깨끗하고 자체 문서화 방식으로 작동하는 지점까지 API를 구동 할 수 있습니다. 일반적으로 적합하지 않은 데이터 모델 (예 : RDBMS)에 매핑 된 기존 URL 라우팅을 사용하는 시스템을 피함으로써 개념을보다 명확하게 할 수 있습니다. Apache Sling 은 시작하기에 좋은 장소 일 것입니다. Zope 과 같은 시스템에서 객체 순회 디스패치의 개념은 보다 명확한 아날로그를 제공합니다.


4

여기 내 의견이 있습니다.

쿼리 매개 변수는 요청에 대한 메타 데이터로 사용됩니다. 기존 자원 호출에 대한 필터 또는 수정 자 역할을합니다.

예:

/calendar/2014-08-08/events

해당 날짜의 캘린더 일정을 제공해야합니다.

특정 카테고리에 대한 이벤트를 원하는 경우

/calendar/2014-08-08/events?category=appointments

또는 30 분 이상의 이벤트가 필요한 경우

/calendar/2014-08-08/events?duration=30

리트머스 테스트는 쿼리 매개 변수 없이도 요청을 계속 제공 할 수 있는지 확인하는 것입니다.


2

나는 일반적으로 쿼리 인수 (예 : / api / resource? parameter = value)로 # 2로 경향이 있습니다.

세 번째 옵션은 실제로 body에 parameter = value를 게시하는 것입니다.

다중 매개 변수 자원에 대해 더 잘 작동하고 나중에 사용하기 위해 더 확장 가능하기 때문입니다.

어떤 것을 선택하든 하나만 골라 혼합하고 일치시키지 마십시오. 혼란스러운 API로 이어집니다.


2

이 주제 중 하나의 "차원"은 생략되었지만 매우 중요합니다. "모범 사례"가 REST 기능으로 구현하거나 기능을 보강하는 플랫폼과 관련이있을 때가 있습니다.

실제 예 :

오늘날 많은 웹 애플리케이션은 MVC (Model, View, Controller) 아키텍처를 구현합니다. 웹 응용 프로그램에 "SEO URL 사용"옵션이있는 경우 특정 표준 경로가 제공된다고 가정합니다.

꽤 유명한 웹 응용 프로그램 인 OpenCart 전자 상거래 상점을 언급하면됩니다. 관리자가 "SEO URL"을 활성화하면 해당 URL이 다음과 같은 표준 MVC 형식이 될 것으로 예상됩니다.

http://www.domain.tld/special-offers/list-all?limit=25

어디

  • special-offers URL을 처리 할 MVC 컨트롤러입니다 (특별 행사 페이지 표시).

  • list-all호출 할 제어기의 조치 또는 기능 이름입니다. (*)

  • limit = 25는 페이지 당 25 개의 항목이 표시됨을 나타내는 옵션입니다.

(*) list-all는 명확성을 위해 사용한 가상 함수 이름입니다. 실제로 OpenCart 및 대부분의 MVC 프레임 워크에는 index사용자가 기본 작업을 수행하려고 할 때 호출 되는 기본 암시 적 (및 일반적으로 URL에서 생략 됨) 기능이 있습니다. 따라서 실제 URL은 다음과 같습니다.

http://www.domain.tld/special-offers?limit=25

위와 비슷한 상당히 표준적인 응용 프로그램 또는 프레임 워크 구조를 사용하면 최적화 된 웹 서버를 얻게되며 URL을 다시 작성합니다 (실제 "비 SEO"URL은 다음과 같습니다). http://www.domain.tld/index.php?route=special-offers/list-all&limit=25 ).

따라서 개발자는 시스템 관리자가 아닌 한 기존 인프라를 다루고 "모범 사례"를 조정해야합니다. Apache / NGinx 다시 쓰기 구성을 조정하는 방법 (후자는 불쾌 할 수 있음)을 정확하게 알고 있어야합니다. 의 위에.

따라서 REST API는 참조 웹 애플리케이션의 표준에 따라 일관성과 편의성 / 속도 (따라서 예산 절약) 측면에서 훨씬 더 나은 경우가 많습니다.

위의 실제 예제로 돌아가려면 일관된 REST API는 다음과 같은 URL을 사용합니다.

http://www.domain.tld/api/special-offers-list?from=15&limit=25

또는 (SEO가 아닌 URL)

http://www.domain.tld/index.php?route=api/special-offers-list?from=15&limit=25

"경로 형성"인수와 "쿼리 형성"인수가 혼합되어 있습니다.



0

매우 흥미로운 질문입니다.

두 가지를 모두 사용할 수 있지만이 주제에 대한 엄격한 규칙은 없지만 URI 경로 변수를 사용하면 몇 가지 장점이 있습니다.

  • 캐시 : 인터넷상의 대부분의 웹 캐시 서비스는 쿼리 매개 변수가 포함 된 경우 GET 요청을 캐시하지 않습니다. 서버에서 데이터를 변경하기 위해 GET 요청을 사용하는 RPC 시스템이 많기 때문에 (실패해야합니다! Get은 안전한 방법이어야합니다)

그러나 경로 변수를 사용하면이 모든 서비스가 GET 요청을 캐시 할 수 있습니다.

  • 계층 : 경로 변수는 계층을 나타낼 수 있습니다 : / City / Street / Place

사용자에게 데이터 구조에 대한 추가 정보를 제공합니다.

그러나 데이터에 계층 관계가 없으면 쉼표 또는 세미콜론을 사용하여 경로 변수를 계속 사용할 수 있습니다.

/ 도시 / 경도, 위도

일반적으로 매개 변수의 순서가 중요 할 때는 쉼표를 사용하고 순서가 중요하지 않은 경우 세미콜론을 사용하십시오.

/ IconGenerator / 빨강; 파랑; 녹색

이러한 이유 외에도 쿼리 문자열 변수를 사용하는 것이 매우 일반적인 경우가 있습니다.

  • HTML 양식 변수를 URI에 자동으로 넣으려면 브라우저가 필요할 때
  • 알고리즘을 다룰 때. 예를 들어 Google 엔진은 쿼리 문자열을 사용합니다.

http : // www.google.com/search?q=rest

요약하자면,이 방법 중 하나를 사용해야하는 강력한 이유는 없지만 가능하면 URI 변수를 사용하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.