IT-Swarm.Net

검색을위한 RESTful URL 디자인

RESTful URL로 검색을 표시하는 합리적인 방법을 찾고 있습니다.

설치 : 자동차와 차고라는 두 가지 모델이 있는데, 자동차는 차고에있을 수 있습니다. 그래서 내 URL은 다음과 같습니다.

/car/xxxx
  xxx == car id
  returns car with given id

/garage/yyy
  yyy = garage id
  returns garage with given id

자동차는 독자적으로 존재할 수 있으므로 (/ 자동차) 차고에 존재할 수 있습니다. 차고에있는 모든 차량을 표현하는 올바른 방법은 무엇입니까? 같은 것 :

/garage/yyy/cars     ?

차고 yyy 및 zzz에서 자동차의 조합은 어떻습니까?

특정 속성을 가진 자동차 검색을 나타내는 올바른 방법은 무엇입니까? 말 : 4 개의 문으로 모든 청색 세단을 보여주세요.

/car/search?color=blue&type=sedan&doors=4

아니면/cars일까요?

"검색"사용이 부적절한 것 같습니다 - 더 나은 방법/용어는 무엇입니까? 그냥되어야할까요?

/cars/?color=blue&type=sedan&doors=4

검색 매개 변수가 PATHINFO 또는 QUERYSTRING에 속해야합니까?

즉, 교차 모델 REST url 디자인 및 검색에 대한 지침을 찾고 있습니다.

[업데이트] 저스틴의 대답이 마음에 들지만 다중 필드 검색 사례는 다루지 않습니다.

/cars/color:blue/type:sedan/doors:4

또는 그런 것. 어떻게해야합니까?

/cars/color/blue

여러 필드의 경우에?

396
Parand

검색하려면 querystrings을 사용하십시오. 이것은 완벽하게 RESTful이다.

/cars?color=blue&type=sedan&doors=4

일반적인 querystring의 장점은 표준적이고 널리 이해되며 form-get에서 생성 될 수 있다는 것입니다.

410
pbreitenbach

RESTful pretty URL design은 구조 (디렉토리와 유사한 구조, 날짜 : articles/2005/5/13, 객체 및 속성, ..), 슬래시 /는 계층 구조를 나타내며 대신 -id를 사용하십시오.

계층 적 구조

나는 개인적으로 선호합니다 :

/garage-id/cars/car-id
/cars/car-id   #for cars not in garages

사용자가 /car-id 부분을 제거하면 직관적 인 cars 미리보기가 표시됩니다. 사용자는 자신이 나무의 어디에 있는지, 무엇을보고 있는지 정확하게 알고 있습니다. 그는 첫 번째 모습에서 차고와 자동차가 관련되어 있음을 알고 있습니다. /car-id은 (는) /car/id와 달리 함께 속해 있음을 나타냅니다.

수색

검색어는 정상입니다, 선호하는 것만 고려됩니다. 재미있는 부분은 검색에 참여할 때 나타납니다 (아래 참조).

/cars?color=blue;type=sedan   #most prefered by me
/cars;color-blue+doors-4+type-sedan   #looks good when using car-id
/cars?color=blue&doors=4&type=sedan   #I don't recommend using &*

또는 기본적으로 위에서 설명한대로 슬래시가 아닌 모든 것.
공식 : /cars[?;]color[=-:]blue[,;+&], * & 부호는 텍스트에서 처음 인식 할 수 없기 때문에 사용하지 않습니다.

** URI에서 JSON 객체를 전달하는 것이 RESTful이라는 것을 알고 있습니까? **

옵션리스트

/cars?color=black,blue,red;doors=3,5;type=sedan   #most prefered by me
/cars?color:black:blue:red;doors:3:5;type:sedan
/cars?color(black,blue,red);doors(3,5);type(sedan)   #does not look bad at all
/cars?color:(black,blue,red);doors:(3,5);type:sedan   #little difference

가능한 기능?

검색 문자열 부정 (!)
차를 검색하지만 not ​​ black red :
?color=!black,!red
color:(!black,!red)

가입 한 검색
검색 red 또는 blue 또는 black 3 차고의 문 id 1..20 또는 101..103 또는 999 하지만 not ​​ 5 /garage[id=1-20,101-103,999,!5]/cars[color=red,blue,black;doors=3]
그러면 더 복잡한 검색어를 작성할 수 있습니다. ( CSS3 속성 일치 부분 문자열 일치를 찾으십시오 (예 : "bar"user*=bar 포함 사용자 검색).)

결론

어쨌든, 이것은 당신에게 가장 중요한 부분 일 수 있습니다. 결국 원하는대로 할 수 있기 때문에 RESTful URI는 이해하기 쉬운 구조를 나타냅니다. 디렉토리와 같은 /directory/file, /collection/node/item, 날짜 /articles/{year}/{month}/{day} .. 마지막 세그먼트를 생략하면 즉시 얻는 것을 알 수 있습니다.

따라서이 모든 문자는 인코딩되지 않음입니다.

  • 예약되지 않은 : a-zA-Z0-9_.-~
  • 예약 : ;/?:@=&$-_.+!*'(),
  • 안전하지 않음 * : <>"#%{}|\^~[]`

* 안전하지 않은 이유와 왜 인코딩해야합니까 : RFC 1738 2.2 참조

RFC 3986 2.2 참조
이전에 말한 내용에도 불구하고, 여기에는 델리 미터의 일반적인 차이점이 있습니다. 이는 일부 "are" 다른 것들보다 더 중요하다는 의미입니다.

  • 일반 델리 미터 : :/?#[]@
  • 하위 배열 : !$&'()*+,;=

더 많은 독서 :
계층 구조 : 2.3 참조 , 1.2.3 참조
rl 경로 매개 변수 구문
CSS3 특성 일치
IBM : RESTful 웹 서비스-기본 사항
참고 : RFC 1738은 RFC 3986에 의해 업데이트되었습니다.

113
Qwerty

경로에 매개 변수가 있으면 장점이 있지만 IMO에는 일부 중요한 요인이 있습니다.

  • 검색어에 필요한 모든 문자가 URL에 허용되는 것은 아닙니다. 대부분의 구두점 및 유니 코드 문자는 쿼리 문자열 매개 변수로 인코딩 된 URL이어야합니다. 나는 같은 문제로 씨름하고있다. URL에 XPath를 사용하고 싶습니다만, 모든 XPath 구문이 URI 경로와 호환되는 것은 아닙니다. 따라서 간단한 경로의 경우 /cars/doors/driver/lock/combination는 드라이버의 XML 문서에서 'combination'요소를 찾는 데 적합합니다. 하지만 /car/doors[id='driver' and lock/combination='1234']는 그렇게 친근하지 않습니다.

  • 속성 중 하나를 기준으로 자원을 필터링하고 자원을 지정하는 경우에는 차이가 있습니다.

    예를 들어, 이후

    /cars/colors는 모든 자동차의 모든 색상 목록을 반환합니다 (반환 된 자원은 색상 객체의 모음입니다)

    /cars/colors/red,blue,green는 자동차 컬렉션이 아닌 빨강, 파랑 또는 녹색 색상 개체 목록을 반환합니다.

    자동차를 반환하려면 경로가

    /cars?color=red,blue,green 또는 /cars/search?color=red,blue,green

  • 경로의 매개 변수는 이름/값 쌍이 나머지 경로와 격리되지 않기 때문에 읽기가 더 어렵습니다.

한가지 마지막 코멘트. 나는 /garages/yyy/cars (항상 복수형)을 /garage/yyy/cars (원문의 오타가 될 수 있습니다)보다 선호합니다. 단수와 복수 사이의 경로를 변경하지 않기 때문입니다. 's'가 추가 된 단어의 경우 변경 사항이 그렇게 나쁘지는 않지만 /person/yyy/friends/people/yyy로 변경하는 것은 번거로울 수 있습니다.

35
Doug Domeny

Peter의 답변을 확장하려면 Search를 최고의 리소스로 만들 수 있습니다.

POST    /searches          # create a new search
GET     /searches          # list all searches (admin)
GET     /searches/{id}     # show the results of a previously-run search
DELETE  /searches/{id}     # delete a search (admin)

검색 리소스에는 색상, 모델, 가리지 상태 등의 필드가 있으며 XML, JSON 또는 기타 형식으로 지정할 수 있습니다. Car 및 Garage 리소스와 마찬가지로 인증을 기반으로 검색에 대한 액세스를 제한 할 수 있습니다. 동일한 검색을 자주 실행하는 사용자는 프로필에 해당 검색을 저장할 수 있으므로 다시 만들 필요가 없습니다. URL은 대부분 전자 메일을 통해 쉽게 교환 할 수있을만큼 짧을 것입니다. 이러한 저장된 검색은 사용자 정의 RSS 피드의 기초가 될 수 있습니다.

검색을 리소스로 생각할 때 검색을 사용할 수있는 방법은 다양합니다.

아이디어는 이것에서 더 자세히 설명됩니다 Railscast .

30
Rich Apodaca

저스틴의 대답은 아마도 갈 수있는 방법 일 것입니다. 일부 응용 프로그램에서는 이름이 지정된 저장된 검색을 지원하려는 경우와 같이 특정 검색을 리소스로 간주하는 것이 좋습니다.

/search/{searchQuery}

또는

/search/{savedSearchName}
11
Peter Hilton

이것은 REST가 아닙니다. API 내부의 리소스에 URI를 정의 할 수 없습니다. 리소스 탐색은 하이퍼 텍스트 기반이어야합니다. 예쁜 URI와 많은 양의 결합을 원한다면 REST라고 부르지 말라. RESTful 아키텍처의 제약을 직접적으로 위반하기 때문이다.

이것 참조 기사 REST의 발명가.

5
aehlke

검색을 구현하는 데 두 가지 접근 방식을 사용합니다.

1) 가장 간단한 경우, 연관된 요소를 조회하고 탐색하는 경우.

    /cars?q.garage.id.eq=1

즉, 차고 ID가 1 인 쿼리 자동차를 의미합니다.

보다 복잡한 검색을 만들 수도 있습니다.

    /cars?q.garage.street.eq=FirstStreet&q.color.ne=red&offset=300&max=100

FirstStreet의 모든 차고에 빨간색이 아닌 차가 있습니다 (3 페이지, 100 개 요소).

2) 복잡한 쿼리는 생성되어 복구 될 수있는 일반 리소스로 간주됩니다.

    POST /searches  => Create
    GET  /searches/1  => Recover search
    GET  /searches/1?offset=300&max=100  => pagination in search

검색 생성을위한 POST 본문은 다음과 같습니다.

    {  
       "$class":"test.Car",
       "$q":{
          "$eq" : { "color" : "red" },
          "garage" : {
             "$ne" : { "street" : "FirstStreet" }
          }
       }
    }

Grails (기준 DSL)에 기반합니다 : http://grails.org/doc/2.4.3/ref/Domain%20Classes/createCriteria.html

5
user2108278

또한 나는 또한 제안 할 것이다 :

/cars/search/all{?color,model,year}
/cars/search/by-parameters{?color,model,year}
/cars/search/by-vendor{?vendor}

여기서 SearchCars resource의 하위 리소스로 간주됩니다.

1
aux

RESTful은 URL/자동차/검색에서 동사를 사용하지 않는 것이 좋습니다. API를 필터링/검색/페이지 매김하는 올바른 방법은 Query Parameters를 사용하는 것입니다. 그러나 규범을 깨뜨릴 필요가있을 수 있습니다. 예를 들어, 여러 자원을 검색하는 경우/search와 같은 것을 사용해야합니다. q = query

RESTful API를 디자인하는 모범 사례를 이해하려면 http://saipraveenblog.wordpress.com/2014/09/29/rest-api-best-practices/

1
java_geek

저스틴의 반응이 마음에 들지만 검색보다는 필터를보다 정확하게 표현한다고 생각합니다. 캠으로 시작하는 이름의 자동차에 대해 알고 싶습니다.

내가 보는 방식으로 특정 리소스를 다루는 방식으로 그것을 구축 할 수 있습니다.
/cars/cam *

아니면 간단히 필터에 추가 할 수 있습니다.
/자동차/문/4/이름/캠 */색상/빨강, 파랑, 녹색

개인적으로, 나는 후자를 선호하지만, 나는 결코 REST에 대한 전문가가 아니다. (처음 2 주 전만해도 ...)

1
Nate

여기에는 여러 가지 좋은 옵션이 있습니다. 여전히 POST 본문을 사용하는 것을 고려해야합니다.

예를 들어 검색어 문자열이 완벽하지만 더 복잡한 내용이있는 경우 (예 : 임의의 긴 항목 목록이나 부울 조건문을 사용하는 경우 클라이언트가 POST를 통해 전송하는 게시물을 문서로 정의 할 수 있습니다.

이렇게하면 서버 URL 길이 제한을 피할뿐만 아니라 검색에 대한보다 유연한 설명이 가능합니다.

0
estani