[rest] 검색을위한 RESTful URL 디자인

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

설정 : 차가 차고에있을 수있는 두 가지 모델 인 Cars and Garages가 있습니다. 그래서 내 URL은 다음과 같습니다.

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

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

자동차는 자체적으로 존재할 수 있으므로 (/ car) 차고에 존재할 수 있습니다. 주어진 차고에있는 모든 차를 대표하는 올바른 방법은 무엇입니까? 다음과 같은 것 :

/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

여러 현장 사건에?



답변

검색하려면 querystrings를 사용하십시오. 이것은 완벽하게 편안합니다.

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

일반 쿼리 문자열의 장점은 표준이며 널리 이해되며 form-get에서 생성 될 수 있다는 것입니다.


답변

편안하고 꽤 URL 설계 구조에 따라 자원을 표시에 관한 것입니다 (디렉토리 같은 구조, 날짜 : 기사 / 5분의 2,005 / 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

가능한 기능?

검색 문자열 부정 (!)
모든 차량을 검색하지만 검은 색빨간색은 검색하지 않습니다 .
?color=!black,!red
color:(!black,!red)

가입 검색
검색 빨간색 또는 파란색 또는 검은 색 으로 자동차 3 차고 아이디에 문을 1..20 또는 101..103 또는 999하지 5
/garage[id=1-20,101-103,999,!5]/cars[color=red,blue,black;doors=3]
그런 다음 더 복잡한 검색 쿼리를 구성 할 수 있습니다. ( 하위 문자열 일치 에 대한 아이디어는 CSS3 속성 일치 를 보십시오 . 예를 들어 “bar”를 포함하는 사용자 검색 user*=bar)

결론

그냥 마음에 계속, 결국처럼 그러나 당신이 그것을 할 수 있기 때문에 어쨌든, 이것은 당신을위한 가장 중요한 부분이 될 수있는 편안하고 URI 쉽게 예를 들어, 디렉토리와 같은 이해할 수있는 구조를 나타내며 /directory/file, /collection/node/item날짜가 /articles/{year}/{month}/{day}.. 그리고 당신은 생략하는 경우를 마지막 세그먼트 중 하나라도 즉시 얻을 수 있습니다.

따라서이 모든 문자는 인코딩되지 않은 상태허용됩니다 .

  • 예약되지 않음 : a-zA-Z0-9_.-~
    일반적으로 인코딩 및 인코딩이 모두 허용되며 두 가지 용도가 동일합니다.
  • 특수 문자: $-_.+!*'(),
  • reserved : ;/?:@=&
    그들이 나타내는 목적으로 인코딩되지 않은 상태로 사용될 수 있으며, 그렇지 않으면 인코딩되어야합니다.
  • 안전하지 않은 : 안전하지 않은 <>"#%{}|\^~[]`
    이유와 암호화해야하는 이유 : RFC 1738 2.2 참조

    더 많은 문자 클래스 는 RFC 1738 # page-20참조하십시오 .

RFC 3986 2.2 참조
내가 이전에 말한에도 불구하고, 여기에 몇 가지가 있다는 것을 의미, 분리 문자의 일반적인 구분이다 “입니다” 다른 사람보다 더 중요합니다.

  • 일반 삼각근 : :/?#[]@
  • 서브 델리 미터 : !$&'()*+,;=

더 읽기 :
계층 구조 : 2.3를 참조 , 1.2.3 참조
URL 경로 매개 변수 구문
CSS3 속성 일치
IBM을 : RESTful 웹 서비스 – 기본 사항
참고 : RFC 1738, RFC 3986에 의해 업데이트 된


답변

경로에 매개 변수를 사용하면 몇 가지 장점이 있지만 IMO에는 몇 가지 중요한 요소가 있습니다.

  • 검색 쿼리에 필요한 모든 문자가 URL에 허용되는 것은 아닙니다. 대부분의 문장 부호 및 유니 코드 문자는 쿼리 문자열 매개 변수로 URL 인코딩되어야합니다. 나는 같은 문제로 씨름하고 있습니다. URL에서 XPath를 사용하고 싶지만 모든 XPath 구문이 URI 경로와 호환되는 것은 아닙니다. 따라서 간단한 경로 의 경우 운전자 도어 XML 문서에서 /cars/doors/driver/lock/combinationcombination‘요소 를 찾는 것이 적절합니다 . 그러나 /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것은 번거로운 것 같습니다.


답변

Peter의 답변을 넓히려면 검색을 일류 자원으로 만들 수 있습니다.

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 and Garage 리소스와 마찬가지로 인증을 기반으로 검색에 대한 액세스를 제한 할 수 있습니다. 동일한 검색을 자주 실행하는 사용자는 자신의 프로필에 저장하여 다시 만들 필요가 없습니다. URL은 많은 경우 이메일을 통해 쉽게 거래 할 수있을 정도로 짧습니다. 이러한 저장된 검색은 사용자 정의 RSS 피드 등의 기초가 될 수 있습니다.

검색을 리소스로 생각할 때 검색을 사용할 가능성이 많이 있습니다.

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


답변

Justin의 대답은 아마도 갈 길이지만 일부 응용 프로그램에서는 명명 된 저장된 검색을 지원하려는 경우와 같이 특정 검색을 자체 리소스로 간주하는 것이 좋습니다.

/search/{searchQuery}

또는

/search/{savedSearchName}


답변

검색을 구현하기 위해 두 가지 접근 방식을 사용합니다.

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


답변

REST가 아닙니다. API 내부의 리소스에 대한 URI를 정의 할 수 없습니다. 자원 탐색은 하이퍼 텍스트 중심이어야합니다. 예쁜 URI와 많은 양의 커플 링을 원한다면 RESTful 아키텍처의 제약 조건을 직접 위반하기 때문에 REST라고 부르지 마십시오.

REST 발명가 가이 기사 를 참조하십시오 .