2010-08-18 3 views
6

나는 REST API는 다른 일을 얻을 해당 문서의 기본 문서와 심판을 단지 휴식을 다시 제공 원칙 하우투 다음과 같은 구현이 등 등 예를 들어, A/자동차의 RESTful API 정렬 딜레마

/5 나에게 모델을 제공합니다 : blabla, user_id : 1 그리고 나서 소유자가 필요하면/user/1을 통해 사용자 데이터를 얻습니다.

이렇게하면 DB에 피할 수 있습니다. 모든 것들은 상호 연결되어 있고 데이터는 서로 연결되어 있습니다. 휴식 클라이언트 부분 - 캐시/배율 캐쉬, 눈금 등을 간단하게 유지.

하지만 정렬이 필요할 때 어떻게됩니까?

다음 데이터를 표시하는 프론트 엔드에 대한 일부보기를 가정 해 보겠습니다. 자동차 모델, 사용자 이름 등 ... 예를 들어 사용자 이름별로 정렬하고 싶습니다.

당신은 정말에만 사용자 ID 알고 원인 이름을 기준으로 정렬하려면/자동차/5 말해 ... 나는 사용자/사용자/목록에서 정렬됩니다? 참조

하나의 옵션 sortby = 사용자 이름과 수 없습니다 반환 된 ID 중 실제로 자동차를 참조하는 ID를 상호 연결합니다. 그러나 이것은 우리가 모든 사용자를 얻고 킬러 성능 병목 현상을 보이는 부분만을 사용해야한다는 것을 의미합니다. 어떤 포인터

답변

5

나는이 방법을 취함으로써로, 모든 잘못된 이유로 참여하지 않도록하려는 생각에 대한

감사합니다, 당신은 더 많은 요청을해야 할 것입니다.

대신 표시 할 모든 정보를 다시 가져 오면 (예 : 데이터베이스 조인) 클라이언트는 쿼리를 줄여야하며 일 수 있습니다. lazy)는 모든 자식 객체를로드합니다.

다른 옵션은 하위 개체를 자식 XML 요소로 가져 오는 것입니다 (OpenStreetMap의 RESTful 인터페이스가 작동하는 방식과 비슷한 방식으로). 클라이언트로부터 여전히 단일 히트가 있으며, DB의로드를 최소화하기 위해 쿼리를 최적화 할 수 있어야합니다.

4

서버에있는 모든 조인을 피하고 클라이언트에 남겨 두는 경우이 경우 클라이언트에도 정렬을 남겨 두어야합니다. 이것은 사용자 이름으로 자동차를 정렬하기 위해 결합이 이루어져야하기 때문입니다.

CarsAndOwners 또는 이와 유사한 리소스를 만들어 합류 목록을 반환하면 서버에서 정렬 할 수 있습니다. 내가 예를 들어, 쓰고 싶은 이상적인 편안하고 쿼리를 상상으로 시작 했죠

2

:

/car/list?sortby=username 

그리고 그것을 구현하는 방법을 알아낼.

는 이제 목록 방법은 당신이 말한대로 이름에 노출되지 않도록 차를 개체를 제공하지만, 내가 문제라고 생각하지 않습니다. 모든 정렬은 목록이 준비되기 전에 서버에서 수행되어야합니다.

는이 작업을 수행하기 위해 사용자에 차에 어떤 점에서 객체를 객체에 가입해야하는거야, 그 문제를 교묘히 회피의 방법이 없습니다. 당신이하는 유일한 선택은 당신이 그것을하는 곳입니다.

전통적인 RDBMS로 작업하는 경우 DB 수준에서 수행하는 것이 좋습니다.


애플리케이션 API와 데이터베이스간에 ORM 레이어를 사용하고 있습니까? 당신은 당신이 할 수있는 분류에 편안한 접근을 원하는 경우,

/cars/5 
/users/1 

이제 일반적으로 : 모든

+0

잘 견디고 나머지는 REST 뒤에 있습니다. 현재 ORM을 사용하고 있지만 나머지는 관련이 있다고 생각하지 않습니다. –

+1

DB에 대한 조인을 피하고 REST 응용 프로그램 계층에 모든 개체를 연결 했으므로 ORM을 사용한다는 힌트를 얻었습니다. 이 간단한 아키텍처의 매력을 볼 수는 있지만 현재의 딜레마의 근원 일 것입니다. 응용 프로그램 작동을 위해이 아키텍처를 손상 시키려고합니다. 사전 정렬 된 데이터를 반환하는 DB에 추가 저장된 procs 또는 뷰가 있고, 여전히 이러한 개체에 대한 ORM 매핑을 제공하고 REST 응용 프로그램을 선택하도록합니다. 쿼리에 따라 메소드 간. –

2

먼저, 예를 /car/5는 편안하고 될하기 위해 자원의 복수 버전을해야

/cars?sort=make&order=asc 

예를 들어, 사용자 이름별로 자동차를 분류하고 싶다고 말한 것입니다. 그러나 언급 한 바와 같이 cars 컬렉션은 users에 대해 모를 것입니다. 따라서 자동차 목록을 표시하고 사용자별로 그룹화하려는 경우 어떻게합니까? 이 정보를 검색 할 방법이 필요합니다. 이 일을하는 한 가지 방법은 사용자 통해 루프하고 각 사용자와 관련된 자동차 요청 :

# pseudo code 

users.each do |user| 
    # assuming the user id is 5, 
    # to display the user's cars, 
    # we need to request /users/5/cars 
end 

그래서 우리는 /users/5/cars 같은 URL에 각 개인에 대한 자동차의 목록을 요청할 수 있습니다. 이를 중첩 된 리소스라고합니다. Google은 사용자 5와 관련된 자동차 만 요청합니다.

그러나 API에 대한 요청이 많을 수 있습니다 (사용 사례에 따라 다를 수 있음).

/users/cars?sort=username&order=asc 

이 이름에 의해 주문 사용자와 자동차의 배열을 반환합니다 :

아마 더 나은 또 다른 방법은, 하나 개의 요청에이 작업을 수행하는 것입니다.

그리고 또 다른 접근 방식

가 될 수있다 :

/users?include=[cars]&sort=username&order=asc 

하지만 이전만큼이 방법처럼 해달라고. 나는 이전의 접근법 인 /users/cars을 추천 할 것이다.

사이드 노트 : 부분 목록 만 표시 할 때 users을 요청하는 오버 헤드가 없도록 목록의 페이지가 매겨져 있어야합니다.

/users?page=1&per_page=50 
+1

여러 리소스 이름 지정은 REST의 요구 사항이 아닙니다. 모든 리소스에 대한 가격 정보에 대한 통일 된 의미가 필요합니다. 즉, 모든 노출 된 리소스는 사용자 관점에서 사용 가능한 프로토콜 메서드 (GET, POST , DELETE, etc ...) –

1

데이터베이스는 조인을 신속하게 수행하도록 설계되었으므로 데이터베이스를 클라이언트 또는 서버 응용 프로그램에 맡기는 것이 나에게 적합하지 않습니다.

REST에서 읽은 거의 모든 것이 엔티티/리소스 간의 관계도 리소스 여야한다고 말합니다. 따라서 해당 조인/관계를 나타내는 /mydomain.com/CarsAndUsers 리소스가 있어야합니다.

그런 다음 당신은 다른 같은 해당 자원에 정렬 할 수 있고,이 데이터베이스에 의해 처리됩니다

/mydomain.com/CarsAndUsers?sortby=username

또한에 필터링을 적용 할 수 있습니다 다른 리소스와 마찬가지로 해당 리소스 (및 페이징).

편집 :

이 같은 것을 할 더 좋을 것 코멘트를 같이 지적에 대해

/자동차 포함 = 사용자, sortby = 사용자 이름

감사 에릭? 이거.

+0

API 종단점의 조합 폭발의 비법입니다. 보다 일반적인 RESTful 접근 방식은 매개 변수를 사용하여 인라인 된 객체 (본질적으로 결합 된 표현)를 요청하는 것입니다. 예 :'/ albums? embed = artist'. 삽입 할 수있는 리소스는 하이퍼 미디어 링크 모음에 링크를 포함하여 옵션을 검색 가능하게 만들 수 있습니다. –

+0

감사합니다. Eric, 엔드 포인트의 폭발에 관한 귀하의 요점에 동의하는 반면 질문은 관련 오브젝트에 관한 것이 아니라 관련된 세트의 특성을 기반으로 한 세트를 정렬하는 것에 관한 것입니다. 나는 당신이 제안하고있는 것이 그 특정한 문제를 해결하는지 확신하지 못합니다. 또는 OP가 다음과 같이 할 수 있다고 말하고 있습니까? /cars? embed = user, sortby = username – rmcsharry

+0

그래, 그게 내가 말하는거야. –