[api] REST API 모범 사례 : 매개 변수 값 목록을 입력으로 승인하는 방법 [닫기]

새로운 REST API를 시작하고 입력 매개 변수의 형식을 지정하는 방법에 대한 우수 사례에 대한 커뮤니티 입력을 원했습니다.

현재 API는 매우 JSON 중심적입니다 (JSON 만 반환). 우리가 XML을 반환해야하는지 여부에 대한 논쟁은 별도의 문제입니다.

API 출력이 JSON 중심이므로 입력이 약간 JSON 중심적 인 경로를 따라 가고 있으며 일반적으로 이상하지만 다소 이상 할 수 있다고 생각했습니다.

예를 들어, 현재 여러 제품을 한꺼번에 가져올 수있는 몇 가지 제품 세부 정보를 얻으려면 다음을 수행하십시오.

http://our.api.com/Product?id=["101404","7267261"]

이것을 다음과 같이 단순화해야합니까?

http://our.api.com/Product?id=101404,7267261

아니면 JSON 입력이 편리합니까? 고통이 더 있습니까?

우리는 두 가지 스타일을 모두 수용하고 싶을 수도 있지만 유연성으로 인해 실제로 혼란과 유지 보수 (유지 관리, 문서 등)가 더 많이 발생합니까?

더 복잡한 경우는 더 복잡한 입력을 제공하려는 경우입니다. 예를 들어 검색시 여러 필터를 허용하려는 경우 :

http://our.api.com/Search?term=pumas&filters={"productType":["Clothing","Bags"],"color":["Black","Red"]}

필터 유형 (예 : productType 및 color)을 요청 이름으로 다음과 같이 입력하지 않아도됩니다.

http://our.api.com/Search?term=pumas&productType=["Clothing","Bags"]&color=["Black","Red"]

모든 필터 입력을 그룹화하고 싶었 기 때문입니다.

결국, 이것이 정말로 중요합니까? JSON 유형이 너무 많아 입력 유형이 그다지 중요하지 않을 수 있습니다.

API에 대한 AJAX 호출을 수행하는 JavaScript 클라이언트는 JSON 입력을 더 쉽게 사용할 수 있다는 점을 알고 있습니다.



답변

한 걸음 물러서

무엇보다도 REST는 URI를 범용 고유 ID로 설명합니다. 너무 많은 사람들이 URI의 구조와 어떤 URI가 다른 URI보다 “휴식 적”인지에 따라 잡히고 있습니다. 이 주장은 누군가 “Bob”을 명명하는 것이 “Joe”를 명명하는 것보다 낫다고 말하는 것만 큼 성가신 일입니다. 두 사람 모두 “사람을 식별하는”직무를 수행합니다. URI는 보편적으로 고유 한 이름에 지나지 않습니다 .

따라서 REST의 눈 ?id=["101404","7267261"]에는 더 편안한 지 ?id=101404,7267261또는 \Product\101404,7267261다소 쓸데 없는지 에 대한 논쟁 이 있습니다 .

이제 URI를 구성하는 방법이 여러 번 RESTful 서비스의 다른 문제에 대한 좋은 지표가 될 수 있다고 말했습니다. URI에는 일반적으로 몇 가지 붉은 깃발이 있습니다.

제안

  1. 동일한 리소스 및 Content-Location

    우리는 두 가지 스타일을 모두 수용하고 싶을 수도 있지만 유연성으로 인해 실제로 혼란과 유지 보수 (유지 관리, 문서 등)가 더 많이 발생합니까?

    URI는 리소스를 식별합니다. 각 자원에는 하나의 표준 URI 가 있어야 합니다. 이 두 URI를 동일한 리소스를 가리 가질 수 없습니다 것을 의미하지 않는다 하지만 그 일에 대해 갈 수있는 잘 정의 된 방법이 있습니다. JSON 및 목록 기반 형식 (또는 다른 형식)을 모두 사용하기로 결정한 경우 이러한 형식 중 어떤 것이 기본 정식 URI 인지 결정해야합니다 . 동일한 “자원”을 가리키는 다른 URI에 대한 모든 응답에는 Content-Location헤더 가 포함되어야합니다 .

    유추라는 이름을 고수하면서 여러 URI를 갖는 것은 사람들의 별명을 갖는 것과 같습니다. 그것은 완벽하게 수용 가능하고 종종 매우 편리하지만, 닉네임을 사용하는 경우 여전히 그 사람의 이름을 알고 싶어 할 것입니다. 이런 식으로 누군가 “Nichloas Telsa”라는 이름으로 누군가를 언급 할 때, 나는 그들이 “Nick”이라고 언급 한 사람에 대해 이야기하고 있다는 것을 알고 있습니다.

  2. URI에서 “검색”

    더 복잡한 경우는 더 복잡한 입력을 제공하려는 경우입니다. 예를 들어 검색시 여러 필터를 허용하려는 경우 …

    내 경험의 일반적인 규칙은 URI에 동사가 포함되어 있으면 무언가 꺼져 있다는 표시 일 수 있습니다. URI의 자원을 식별, 그러나 그들은 표시 안 무엇을 우리가 자원하고 있어요. 이것이 바로 “일관된 인터페이스”라는 HTTP 또는 편안한 용어입니다.

    URI에서 동사를 사용하는 것은 비유라는 이름의 유사점을 극복하기 위해 누군가와 상호 작용할 때 누군가의 이름을 변경하는 것과 같습니다. Bob과 상호 작용하는 경우 Bob에게 Hi라고 말하고 싶을 때 Bob의 이름이 “BobHi”가되지 않습니다. 마찬가지로 제품을 “검색”하려는 경우 URI 구조가 “/ Product / …”에서 “/ Search / …”로 변경되지 않아야합니다.

초기 질문에 답변

  1. ["101404","7267261"]vs 관련 101404,7267261: 여기에 제 제안은 단순성을 위해 JSON 구문을 피하는 것입니다 (즉, 사용자가 실제로 필요하지 않은 경우 URL 인코딩을 수행하지 않아도 됨). API를 좀 더 유용하게 사용할 수 있습니다. 더 나은 방법은 다른 사람들이 권장 한 application/x-www-form-urlencoded것처럼 최종 사용자에게 가장 친숙 할 수 있는 표준 형식을 사용하는 것입니다 (예 🙂 ?id[]=101404&id[]=7267261. “pretty”가 아닐 수도 있지만 Pretty URI가 필요한 URI를 의미하지는 않습니다. 그러나 궁극적으로 REST에 대해 말할 때 내 초기 요점을 되풀이하는 것은 중요하지 않습니다. 그것에 너무 많이 머 무르지 마십시오.

  2. 복잡한 검색 URI 예제는 제품 예제와 거의 같은 방식으로 해결할 수 있습니다. application/x-www-form-urlencoded이미 많은 사람들에게 익숙한 표준이므로 형식을 다시 사용하는 것이 좋습니다 . 또한 두 가지를 병합하는 것이 좋습니다.

URI …

/Search?term=pumas&filters={"productType":["Clothing","Bags"],"color":["Black","Red"]}

URI 인코딩 후 URI …

/Search?term=pumas&filters=%7B%22productType%22%3A%5B%22Clothing%22%2C%22Bags%22%5D%2C%22color%22%3A%5B%22Black%22%2C%22Red%22%5D%7D

로 변환 할 수 있습니다 …

/Product?term=pumas&productType[]=Clothing&productType[]=Bags&color[]=Black&color[]=Red

URL 인코딩 요구 사항을 피하고 상황을 좀 더 표준으로 보이게하는 것 외에도 이제 API를 약간 균질화합니다. 사용자는 제품 또는 제품 목록을 검색하려는 경우 (모두 RESTful 용어로 단일 “자원”으로 간주 됨) /Product/...URI에 관심이 있다는 것을 알고 있습니다 .


답변

URL 매개 변수로 값 목록을 전달하는 표준 방법은 값을 반복하는 것입니다.

http://our.api.com/Product?id=101404&id=7267261

대부분의 서버 코드는이 값을 값 목록으로 해석하지만 대부분 단일 값 단순화가 있으므로 찾아야 할 수도 있습니다.

구분 된 값도 괜찮습니다.

JSON을 서버로 보내야하는 경우 URL에서 다른 형식으로 보는 것을 좋아하지 않습니다. 특히, URL에는 크기 제한이 있습니다 (실제로는 이론이 아닌 경우).

내가 복잡한 쿼리를 RESTfully하게 수행하는 방법은 두 단계로 이루어집니다.

  1. POST 쿼리 요구 사항, ID 수신 (필수적으로 검색 기준 자원 작성)
  2. GET 위의 ID를 참조하여 검색
  3. 필요에 따라 필요에 따라 쿼리 요구 사항을 삭제하지만 해당 요구 사항을 재사용 할 수 있습니다.

답변

먼저:

두 가지 방법으로 할 수 있다고 생각합니다

http://our.api.com/Product/<id> : 하나의 레코드 만 원하면

http://our.api.com/Product : 모든 기록을 원한다면

http://our.api.com/Product/<id1>,<id2> : James가 제안한 것처럼 Product 태그 뒤에 매개 변수가 매개 변수이기 때문에 옵션이 될 수 있습니다.

또는 내가 가장 좋아하는 것은 다음과 같습니다.

당신은 사용 할 수 있습니다 응용 프로그램 상태의 엔진으로 하이퍼 미디어를 편안 WS의 (HATEOAS) 속성과 통화 할 http://our.api.com/Product에 해당 URL을 반환해야 http://our.api.com/Product/<id>하고,이 후 그들에게 전화를.

둘째

URL 호출에서 쿼리를 수행해야 할 때. HATEOAS를 다시 사용하는 것이 좋습니다.

1) 전화 받기 http://our.api.com/term/pumas/productType/clothing/color/black

2) 전화 받기 http://our.api.com/term/pumas/productType/clothing,bags/color/black,red

3) (HATEOAS 사용)` http://our.api.com/term/pumas/productType/에 전화를 거십시오 .-> 가능한 모든 의복 URL을 받으십시오-> 원하는 것 (의류 및 가방)을 부르십시오- > 가능한 컬러 URL 수신-> 원하는 컬러 URL 호출


답변

RFC 6570 을 확인하십시오 . 이 URI 템플리트 스펙은 URL에 매개 변수를 포함하는 방법에 대한 많은 예를 보여줍니다.


답변

첫 번째 경우 :

일반적인 제품 조회는 다음과 같습니다

http://our.api.com/product/1

그래서 최선의 방법은 당신이 이것을 할 것이라고 생각합니다.

http://our.api.com/Product/101404,7267261

두 번째 경우

querystring 매개 변수를 사용하여 검색하십시오. 를 사용하는 대신 AND 및 OR로 용어를 결합하고 싶습니다 [].

추신 : 이것은 주관적 일 수 있으므로 편안하다고 느끼는 것을하십시오.

URL에 데이터를 넣는 이유는 링크를 사이트에 붙여 넣거나 사용자간에 공유 할 수 있기 때문입니다. 이것이 문제가되지 않으면 반드시 JSON / POST를 대신 사용하십시오.

편집 : 반영 시이 접근법은 복합 키가있는 엔티티에 적합하지만 여러 엔티티에 대한 쿼리에는 적합하지 않다고 생각합니다.


답변

nategood의 답변이 완성되어 귀하의 요구를 기쁘게하는 것처럼 보였습니다. 그래도 여러 (1 이상) 리소스를 식별하는 방법에 대한 의견을 추가하고 싶습니다.

http://our.api.com/Product/101404,7267261

그렇게함으로써 당신은 :

고객을 복잡하게
이 응답을 배열로 해석하도록 강제 를 복잡하게하십시오. 다음 요청을하면 나에게 직관적입니다.http://our.api.com/Product/101404

중복 API 생성
하나의 API로 모든 제품을 가져오고 위의 하나를 여러 개 가져 오기 위해 를 . UX를 ​​위해 사용자에게 두 페이지 이상의 세부 정보를 표시해서는 안되므로 ID를 두 개 이상 사용하는 것은 쓸모없고 순수한 제품 필터링에 사용됩니다.

문제가되지는 않지만 단일 엔터티를 반환하여 (응답에 하나 이상이 포함되어 있는지 확인하여) 서버 측에서 직접 처리하거나 클라이언트가 관리하도록해야합니다.

Amazing 에서 책을 주문하고 싶습니다 . 나는 그것이 어떤 책인지 정확하게 알고 있으며 공포 책을 탐색 할 때 목록에서 볼 수 있습니다.

  1. 10 000 놀라운 라인, 0 놀라운 테스트
  2. 놀라운 몬스터의 귀환
  3. 놀라운 코드를 복제하자
  4. 끝의 놀라운 시작

두 번째 책을 선택하면 목록의 책 부분을 자세히 설명하는 페이지로 리디렉션됩니다.

--------------------------------------------
Book #1
--------------------------------------------
    Title: The return of the amazing monster
    Summary:
    Pages:
    Publisher:
--------------------------------------------

아니면 해당 책의 전체 세부 정보 만 제공하는 페이지에서?

---------------------------------
The return of the amazing monster
---------------------------------
Summary:
Pages:
Publisher:
---------------------------------

내 의견

이 리소스의 세부 정보를 얻을 때 unicity가 보장되면 경로 변수에 ID를 사용하는 것이 좋습니다. 예를 들어 아래 API는 특정 리소스에 대한 세부 정보를 얻는 여러 가지 방법을 제안합니다 (제품에 고유 ID가 있고 해당 제품의 사양에 고유 한 이름이 있고 위에서 아래로 탐색 할 수 있다고 가정).

/products/{id}
/products/{id}/specs/{name}

둘 이상의 리소스가 필요한 순간에 더 큰 컬렉션에서 필터링하는 것이 좋습니다. 같은 예를 들면 :

/products?ids=

물론 이것은 부과되지 않았기 때문에 제 의견입니다.


답변