REST API 모범 사례 : 매개 변수를 어디에 둘 것인가? [닫은]
REST API는 최소한 두 가지 방법으로 매개 변수를 가질 수 있습니다.
- 의 URL 경로의 일부로서 (예
/api/resource/parametervalue) - 쿼리 인수로 (예
/api/resource?parameter=value)
가장 좋은 방법은 무엇입니까? 1 사용시기와 2 사용시기에 대한 일반적인 지침이 있습니까?
실제 예 : Twitter는 간격을 지정하기 위해 쿼리 매개 변수를 사용합니다. ( http://api.twitter.com/1/statuses/home_timeline.json?since_id=12345&max_id=54321)
이러한 매개 변수를 URL 경로에 배치하는 것이 더 나은 디자인으로 간주됩니까?
모범 사례가 문서화되어 있으면 아직 찾지 못했습니다. 그러나 URL에 매개 변수를 넣을 위치를 결정할 때 사용하는 몇 가지 지침은 다음과 같습니다.
선택적 매개 변수는 쿼리 문자열에 쉽게 넣는 경향이 있습니다.
매개 변수 값이 기존 리소스와 일치하지 않을 때 404 오류를 반환하려면 경로 세그먼트 매개 변수를 사용하는 경향이 있습니다. 예를 들어 /customer/232, 232는 유효한 고객 ID가 아닙니다.
그러나 빈 목록을 반환하려면 매개 변수를 찾을 수 없을 때 쿼리 문자열 매개 변수를 사용하는 것이 좋습니다. 예 :/contacts?name=dave
매개 변수가 URI 공간의 전체 서브 트리에 영향을주는 경우 경로 세그먼트를 사용하십시오. 예를 들어 언어 매개 변수 /en/document/foo.txt대/document/foo.txt?language=en
고유 식별자가 쿼리 매개 변수가 아닌 경로 세그먼트에있는 것을 선호합니다.
URI에 대한 공식 규칙은이 RFC 사양에 나와 있습니다 . URI를 매개 변수화하기위한 규칙을 정의하는 또 다른 유용한 RFC 스펙도 있습니다 .
늦은 답변이지만 공유 된 내용, 즉 요청에 여러 유형의 "매개 변수"가 있다는 점에 대한 통찰력을 추가 할 것입니다.이를 고려해야합니다.
- 로케이터-예를 들어 ID 또는 작업 /보기와 같은 리소스 식별자
- 필터-결과 집합을 검색, 정렬 또는 좁히는 매개 변수입니다.
- 상태-예를 들어 세션 식별, API 키, whatevs.
- 내용-예를 들어 저장 될 데이터.
이제 이러한 매개 변수가 들어갈 수있는 다른 위치를 살펴 보겠습니다.
- 요청 헤더 및 쿠키
- URL 쿼리 문자열 ( "GET"vars)
- URL 경로
- 본문 쿼리 문자열 / 멀티 파트 ( "POST"변수)
일반적으로 상태 정보 유형에 따라 헤더 또는 쿠키에 State를 설정하려고합니다. 우리 모두 이것에 동의 할 수 있다고 생각합니다. 필요한 경우 사용자 정의 http 헤더 (X-My-Header)를 사용하십시오.
마찬가지로, Content는 요청 본문에있는 하나의 장소 만 쿼리 문자열 또는 http multipart 및 / 또는 JSON 컨텐츠로 포함합니다. 이는 서버가 컨텐츠를 보낼 때 서버에서받는 것과 일치합니다. 따라서 당신은 무례하고 다르게 행동해서는 안됩니다.
"id = 5"또는 "action = refresh"또는 "page = 2"와 같은 로케이터는 mysite.com/article/5/page=2각 부분의 의미를 부분적으로 알고있는 위치 (예 : 기사 및 5는 분명히 id가 5) 인 article 유형의 데이터를 가져오고 추가 매개 변수는 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까지). 위치는 항상 해당 특정 인스턴스 (있는 경우)를 찾습니다. 수정 필터링은 수정을 제외하고 로케이터와 동일한 데이터를 반환합니다 (수정이 허용되는 경우).
사람들이 물건을 넣을 곳을 잃어 버린 경우 유레카 순간을 사람들에게 줄 수 있기를 바랍니다.
디자인에 따라 다릅니다. REST over HTTP에는 URI에 대한 규칙이 없습니다 (주로 고유함). 종종 맛과 직관 문제에 관한 것입니다 ...
나는 다음과 같은 접근 방식을 취합니다.
- url path-element : 자원 및 해당 path-element는 디렉토리 탐색 및 하위 자원을 형성합니다 (예 : / items / {id}, / users / items). 확실하지 않은 경우 동료에게 순회한다고 생각하고 "다른 디렉토리"에서 가장 가능성이 높은 경로 요소가 올바른 선택이라고 생각하면
- url 매개 변수 : 실제로 순회가없는 경우 (여러 쿼리 매개 변수가있는 검색 리소스가 그 좋은 예입니다)
IMO 매개 변수는 쿼리 인수보다 좋습니다. url은 리소스를 식별하는 데 사용되는 반면, 추가 된 쿼리 매개 변수는 원하는 리소스 부분, 리소스의 상태 등을 지정합니다.
REST 구현에 따라
1) 경로 변수 는 연락처 또는 노래와 같은 자원에 대한 직접 조치에 사용됩니다.
GET etc / api / resource / {songid} 또는
GET etc / api / resource / {contactid}는 각 데이터를 리턴합니다.
2) Query perms / argument 는 노래의 메타 데이터와 같은 간접 리소스에 사용됩니다. GET / api / resource / {songid}? metadata = genres 특정 노래에 대한 장르 데이터를 반환합니다.
유니버스 리소스 로케이터가 제공하는 "컨텍스트"에 대해 데이터를 "포장"하고 게시합니다. 이는 로케이터를위한 # 1을 의미합니다.
# 2로 한계를 극복하십시오. # 1보다 POST를 선호합니다.
참고 : 제한 사항은
POST in POST 매개 변수 내용의 최대 크기가 있습니까?
GET in GET 요청의 길이에 제한이 있습니까? 그리고 _GET에서 URL 매개 변수의 최대 크기
ps 이러한 제한은 클라이언트 기능 (브라우저) 및 서버 (구성)를 기반으로합니다.
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 템플릿 의 기능 은 매우 제한적입니다 ...
종종 클라이언트 쪽 프로그래머가 쿼리 인수를 선호합니다. 또한 나를 위해 URL 경로를 매개 변수와 분리하고 명확성을 추가하며 더 많은 확장 성을 제공합니다. 또한 URL / URI 건물과 매개 변수 작성기 사이에 별도의 논리를 가질 수 있습니다.
나는 일종의 나무가 있다면 manuel aldana가 다른 옵션에 대해 말한 것을 좋아합니다. 사용자 별 부품이 그처럼 트리밍되는 것을 볼 수 있습니다.
단단하고 빠른 규칙은 없지만, 내가 사용하고 싶은 순수하게 개념적인 관점에서 볼 때 경험할 규칙은 간단히 요약하면 다음과 같습니다. URI 경로 (정의에 따라)는 리소스를 나타내며 쿼리 매개 변수는 기본적으로 해당 리소스의 수정 자입니다. . 지금까지는 도움이되지 않을 것입니다 ... REST API를 사용 GET하면 PUT, 및을 사용하여 단일 리소스를 처리하는 주요 방법이 DELETE있습니다. 따라서 경로에서 무언가를 표현해야하는지 또는 매개 변수로 표현해야하는지 여부는 해당 방법이 해당 표현에 적합한 지 여부로 줄일 수 있습니다. 당신 PUT은 그 길에서 합리적으로 뭔가를 하시겠습니까 ? 물론 PUT어디에서나 무언가를 처리하고 백엔드를 구부려 처리 할 수 있지만PUT불필요하게 상황에 맞는 버전이 아닌 실제 리소스를 나타내는 것. 컬렉션의 경우에도 마찬가지입니다 POST. 특정 컬렉션에 추가하고 싶을 경우 URL이 적합 POST합니다.
일부 경로는 어느 정도 재량 적이며 사용에 의존하는 부모 자원의 자녀에게 어느 정도 양을 가리킬 수 있기 때문에 여전히 회색 부분을 남겨 둡니다. 이것이 이끌어내는 한 가지 어려운 점은 기본 리소스가 없기 때문에 모든 유형의 전이 표현을 쿼리 매개 변수를 사용하여 수행해야한다는 것입니다.
원래 질문 (Twitter 's API)에 제공된 실제 예에 응답하여 매개 변수는 자원 상태 (계층 구조가 아닌)를 필터링하는 전이 쿼리를 나타냅니다. 이 특정 예제에서 이러한 제약 조건으로 표시되는 컬렉션에 추가하는 것은 전적으로 비합리적이며, 쿼리는 객체 그래프 측면에서 의미가있는 경로로 표현할 수 없습니다.
이러한 유형의 리소스 지향적 관점을 채택하면 도메인 모델의 객체 그래프에 쉽게 직접 매핑 할 수 있고 API의 논리가 명확 해지면 모든 것이 매우 깨끗하고 자체 문서화 방식으로 작동하는 지점까지 API를 구동 할 수 있습니다. 일반적으로 적합하지 않은 데이터 모델 (예 : RDBMS)에 매핑 된 기존 URL 라우팅을 사용하는 시스템을 피함으로써 개념을 더 명확하게 만들 수 있습니다. Apache Sling 은 시작하기에 좋은 장소 일 것입니다. Zope 과 같은 시스템에서 객체 순회 디스패치의 개념은 보다 명확한 아날로그를 제공합니다.
여기 내 의견이 있습니다.
쿼리 매개 변수는 요청에 대한 메타 데이터로 사용됩니다. 기존 자원 호출에 대한 필터 또는 수정 자 역할을합니다.
예:
/calendar/2014-08-08/events
해당 날짜의 캘린더 일정을 제공해야합니다.
특정 카테고리에 대한 이벤트를 원하는 경우
/calendar/2014-08-08/events?category=appointments
또는 30 분 이상의 이벤트가 필요한 경우
/calendar/2014-08-08/events?duration=30
리트머스 테스트는 쿼리 매개 변수 없이도 요청을 계속 제공 할 수 있는지 확인하는 것입니다.
나는 일반적으로 쿼리 인수 (예 : / api / resource? parameter = value)로 # 2로 경향이 있습니다.
세 번째 옵션은 실제로 body에 parameter = value를 게시하는 것입니다.
다중 매개 변수 자원에 더 적합하고 나중에 사용하기 위해 더 확장 가능하기 때문입니다.
어떤 것을 선택하든 하나만 선택하고 혼합하지 마십시오. 혼란스러운 API로 이어집니다.
이 주제 중 하나의 "차원"은 생략되었지만 매우 중요합니다. "모범 사례"가 REST 기능으로 구현하거나 기능을 보강하는 플랫폼과 관련이있을 때가 있습니다.
실제 예 :
오늘날 많은 웹 응용 프로그램은 MVC (Model, View, Controller) 아키텍처를 구현합니다. 웹 애플리케이션에 "SEO URL 사용"옵션이있는 경우 특정 표준 경로가 제공된다고 가정합니다.
꽤 유명한 웹 응용 프로그램 인 OpenCart 전자 상거래 상점 만 언급하면됩니다. 관리자가 "SEO URL"을 활성화하면 해당 URL이 다음과 같은 표준 MVC 형식이 될 것으로 예상됩니다.
http://www.domain.tld/special-offers/list-all?limit=25
어디
special-offersURL을 처리 할 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
"경로 형성"인수와 "쿼리 형성"인수가 혼합되어 있습니다.
매개 변수를 제대로 처리하지 못하는 많은 REST API가 있습니다. URI가 개인 식별 정보를 포함하는 경우가 종종 있습니다.
http://software.danielwatrous.com/design-principles-for-rest-apis/
필자의 추론은 매개 변수가 매개 변수가 아니어야하지만 대신 요청 의 HEADER 또는 BODY 로 이동해야 할 때 입니다.
매우 흥미로운 질문입니다.
두 가지를 모두 사용할 수 있지만이 주제에 대한 엄격한 규칙은 없지만 URI 경로 변수를 사용하면 몇 가지 장점이 있습니다.
- 캐시 : 인터넷상의 대부분의 웹 캐시 서비스는 쿼리 매개 변수가 포함되어있을 때 GET 요청을 캐시하지 않습니다. 서버에서 데이터를 변경하기 위해 GET 요청을 사용하는 RPC 시스템이 많기 때문에 (실패해야합니다! Get은 안전한 방법이어야합니다)
그러나 경로 변수를 사용하면이 모든 서비스가 GET 요청을 캐시 할 수 있습니다.
- 계층 : 경로 변수는 계층을 나타낼 수 있습니다 : / City / Street / Place
사용자에게 데이터 구조에 대한 추가 정보를 제공합니다.
그러나 데이터에 계층 관계가 없으면 쉼표 또는 세미콜론을 사용하여 경로 변수를 계속 사용할 수 있습니다.
/ 도시 / 경도, 위도
일반적으로 매개 변수의 순서가 중요 할 때는 쉼표를 사용하고 순서가 중요하지 않은 경우 세미콜론을 사용하십시오.
/ IconGenerator / 빨강; 파랑; 녹색
이러한 이유 외에도 쿼리 문자열 변수를 사용하는 것이 매우 일반적인 경우가 있습니다.
- HTML 양식 변수를 URI에 자동으로 넣으려면 브라우저가 필요할 때
- 알고리즘을 다룰 때. 예를 들어 Google 엔진은 쿼리 문자열을 사용합니다.
http : // www.google.com/search?q=rest
요약하자면,이 방법 중 하나를 사용해야하는 강력한 이유는 없지만 가능하면 URI 변수를 사용하십시오.
참고 URL : https://stackoverflow.com/questions/4024271/rest-api-best-practices-where-to-put-parameters
'development' 카테고리의 다른 글
| 정규식을 사용하여 하위 문자열을 추출하는 방법 (0) | 2020.03.02 |
|---|---|
| 자동 커밋없이 Git 병합 (0) | 2020.03.02 |
| alias 또는 alias_method를 사용해야합니까? (0) | 2020.03.01 |
| 정수 인덱스로 팬더 시리즈 / 데이터 프레임 행 선택 (0) | 2020.03.01 |
| MySQL에서 tinyint, smallint, mediumint, bigint 및 int의 차이점은 무엇입니까? (0) | 2020.03.01 |