2013-12-10 5 views
2

내 응용 프로그램에서 REST 리소스로 노출하는 개체가 있다고 가정합니다. 이 객체에는 많은 필드가 있으며 관련 컬렉션을 비롯한 많은 다른 객체가 포함되어 있습니다. 이런 식으로 뭔가,하지만 훨씬 더 큰 생각 :REST 리소스의 동적 표시

Customer 
    List<Order> orders 
    List<Address> shippingAddresses; 
    // other fields for name, etc. 

Order 
    List<Product> products 
    // fields for total, tax, shipping, etc. 

Product 
    // fields for name, UPC, description, etc. 

내 고객 중 일부는 각 주문의 모든 제품에 대한 모든 세부 사항을 원할 것입니다 /customer/{id}

나의 API의 고객을 노출합니다. 내가 HATEOAS를 따를 경우 제품 세부 정보를 얻기위한 링크를 제공 할 수 있습니다. 고객을위한 주문 내에서 제품을 채우는 서비스로의 n + 1 호출로 이어질 것입니다. 다른 한편으로는, 나는 항상 그것을 채우는 경우에 많은 클라이언트가 필요하지 않은 많은 정보를받으며 필요없는 데이터베이스 조회를 수행합니다.

클라이언트의 필요에 따라 내 리소스를 고객이 대신 표현하도록 허용하려면 어떻게해야합니까?

몇 가지 옵션이 있습니다.

  1. 사용되는 것을 미리 지정하려면 Jackson의 JsonView 주석을 사용하십시오. 호출자는 자신에게 적절한보기를 요청합니다. 즉 /customer/{id}?view=withProducts입니다. 이것은 내가 컴파일 타임에 모든 사용 가능한 뷰를 지정하도록 요구할 것이고 모든 융통성이있는 것은 아니다.

  2. 발신자가 요청에 입력 할 특정 필드 (예 : /customer/{id}?fields=orders,firstName,lastName)를 요청하도록 허용합니다. 이 필드 매개 변수를 구문 분석 할 수 및 아마도 리플렉션을 사용하여 물건을 채우는 데 사용할 수있는 일부 처리기가 필요합니다. 나에게 지저분한 소리가 난다. 하위 리소스에 대해 무엇을합니까? fields=orders.products.upc을 수거하고 컬렉션에 참여할 수 있습니까? 내가 REST 또는 무엇인가 위에 최대 절전 모드를 쓰려고하는 것처럼 들린다.

  3. HATEOAS를 따르고 클라이언트가 필요한 것을 채우기 위해 100 만 건의 HTTP 호출을하도록 요구합니다. 대부분의 경우 항목을 채우고 싶지 않지만 주문 세부 정보 또는 이와 유사한 내용을 표시하려고하는 사람에게는 비용이 많이 들기 때문에 큰 효과가 있습니다.

  4. 은 ...

  5. 다른 각 뷰에 대해 별도의 자원이 있습니까?

답변

1

나는 이런 식으로 뭔가 할 것 : /고객/{ID를}/주문/= 엔티티 당신의 옵션 1의보다 구체적인 변화의 일종이다

있습니다.

당신 것 또한이 다음 옵션을

  1. 특정하기 위해 특정 고객으로부터 제품의 목록이없는 : /고객/{ID}/주문/{ID}
  2. 그냥 주문 제품이없는 고객 : /고객/{ID}/주문/

나는, 단수 자원을 회피하는 경향이 becau 대부분의 시간 또는 결국 누군가 항상 사물의 목록을 원한다.

+0

내 경험에 따르면, 다음 id가없는'/ customer'는리스트를 줄 것이고,'/ customer/{id}'는 한 고객에게 어떻게 줄 것인가하는 것이지만, 그것은 단지 문체적인 것입니다. 흥미로운 부분 인'include = entities' 물건입니다. 즉, 기본적으로 옵션이 두 개 밖에 없다는 것을 의미합니다. 하나는 완전히 통합되어 있고 하나는 필드 만 포함하고 있습니다. 관련된 컬렉션 중 일부가 값 비싼 작업을 필요로하는 경우 특히 충분히 유연하지 않다고 생각합니다. – digitaljoel

+0

어떤 엔티티를 포함할지 여부를 말하기보다는 포함시킬 엔티티를 말하면됩니다./customers/{id}/orders /? products = yes & productdetails = yes 및/customers/{id}/orders/{id}는 해당 id로 베어 본 주문을 제공합니다. –

+0

예, 기본적으로 제 2 번입니다. 이 일에 마법의 탄환이없는 것 같습니다. – digitaljoel

1

옵션 2 (클라이언트가 필드를 지정 함)는 필터링 방식이며 GETable 리소스보다 쿼리 인터페이스와 유사합니다. 서비스가 채워지는 POST 요청에서 부분 템플릿을 수락하면 필터가 더 표현력이 풍부해질 수 있습니다. 그러나 그것은 복잡합니다.

복잡한 엔티티에 대한 2 가지 간단한 표현 만 있으면 충분합니다. 도메인의 사례 중 99.9 %를 처리해야합니다. 이 점을 감안할 때, 사물의 "보기"마다 URI를 하나 더 만들어라.

0.1 %를 처리하려면 (예 : Products 컬렉션을 완전히 채워야하는 경우) 필터링 할 수있는 중첩 엔티티에 쿼리 인터페이스를 제공하십시오. 위의 단순화 된 표현의 일부로 이러한 콜렉션을 검색하는 하이퍼 미디어 링크를 제공 할 수도 있습니다.

+0

기본적으로 각보기마다 다른 처리기입니다. JsonView를 사용하여 직렬화를 수행 할 수 있으며, 연관된 컬렉션을 가져오고 다른 컬렉션은 가져 오지 않습니다. – digitaljoel

+0

이렇게하는 것이 좋습니다. 이 엔터티는 실제로 프레젠테이션 계층에 대한 정보를 편리하게 조합하기 때문에 실제로는 PUTable이 아니라는 것을 알고 있어야합니다. 고객은 실제로 주문과 관련하여 알지 못하는 별도의 리소스이기 때문에 여기서는 많은 유연성이 있습니다.이 리소스에 대해 다른 이름을 사용할 수도 있습니다. –

관련 문제