Как применить проекцию к ресурсу метода запроса Spring Data REST?

Я использую Spring Data REST 2.1.4.RELEASE.

я создал

  • объект Booking,
  • его репозиторий REST (расширение CrudRepository) с именем BookingRepository
  • и проекция BookingDetails (с аннотацией @Projection(name="details", types = Booking.class)) для возврата некоторых связанных объектов в разобранном виде, таких как Resource, Activity, Applicant и т. д.

Клиент получает все бронирования с .../rest/bookings, а ответ JSON включает ссылки на связанные объекты. Если он добавляет ?projection=details, то связанные объекты разбиваются и возвращаются. И это здорово.

Теперь я добавляю этот пользовательский метод в репозиторий:

List<Booking> findByApplicant(@Param("applicant") Person applicant);

Когда клиент вызывает его с помощью .../rest/bookings/search/findByApplicant?applicant=5, кажется, нет способа запросить проекцию details. Следующие попытки игнорируются:

  • добавление &projection=details в строку запроса
  • чтобы метод всегда возвращал BookingDetails:

    List<BookingDetails> findByApplicant(@Param("applicant") Person applicant);
    

Подводя итог, можно сказать, что пользовательские методы поиска (findBy*) никогда не возвращают прогноз. Если вы не аннотируете репозиторий с помощью @RepositoryRestResource(excerptProjection = BookingDetails.class), но это приводит к некоторым проблемам, прежде всего, клиент должен всегда использовать одну и ту же проекцию. Как мы можем позволить пользователю использовать проекции также с findBy* методами?


person bluish    schedule 06.02.2015    source источник
comment
URL-адрес типа .../rest/bookings/search/findByApplicant?applicant=5 не очень RESTful. А как насчет .../rest/bookings?applicant=5?   -  person    schedule 06.02.2015
comment
Хотя это совершенно не связано с исходным вопросом плакатов, что беспокоит этот URI? Чтобы быть точным, вы не можете судить о спокойствии URI по определению, поскольку оно зависит исключительно от того, соответствует ли предоставляемый через него ресурс семантике HTTP. Является ли идентификатор ресурса /foo или /conquer/the/world совершенно неважным. Тем не менее, Spring Data REST использует гипермедиа, чтобы позволить клиентам переходить к ресурсам, поэтому структура, если идентификаторы ресурсов даже становятся менее релевантными :).   -  person Oliver Drotbohm    schedule 06.02.2015
comment
URL-адрес пахнет RPC. Конечно, гипермедиа — это хорошо.   -  person    schedule 06.02.2015
comment
URI не пахнут, они непрозрачны. Важны ресурсы и то, как они себя ведут :).   -  person Oliver Drotbohm    schedule 06.02.2015


Ответы (1)


Я проверил, что это работает с Spring Data REST 2.2.1, поэтому, пожалуйста, обновите его. Убедитесь, что ваш клиент действительно отправляет запрошенные параметры так, как вы намеревались. Во время отладки я узнал, что, например. cURL отбрасывает параметры запроса, если вы явно не указали URI. Итак, это:

curl http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details

не отправит какие-либо параметры запроса. Как только вы процитируете URI, он будет.

curl 'http://localhost:8080/orders/search/findByApplicant?applicant=5&projection=details'

Примерно то же самое происходит и со все более популярным HTTPie. С ним требуемый синтаксис:

http :8080/orders/search/findByApplicant applicant==5 projection==details

Если вы не можете заставить его работать таким образом, было бы здорово получить работающий пример проекта для просмотра.

person Oliver Drotbohm    schedule 06.02.2015
comment
большое тебе спасибо! Я наполняю глупость: я тестировал это с помощью Spring Data REST 2.1.4 несколько дней назад и не работал; затем я обновился до 2.2.1 и не проверял (я только проверял новую excerptProjection). Теперь, когда я тестирую .. Я вижу, что это работает! Я не думал, что это можно реализовать именно сейчас, когда мне это нужно :D Теперь я исправляю свой вопрос. Спасибо и извините за потраченное время! - person bluish; 06.02.2015
comment
Не волнуйтесь. Я тоже чувствовал себя глупо, не видя вообще никаких параметров с простым cURL без кавычек. Кроме того, по-прежнему приятно получать эти вопросы, поскольку они становятся каноническим справочником для других, столкнувшихся с той же проблемой :). Рад, что это работает для вас! - person Oliver Drotbohm; 06.02.2015
comment
Привет, столкнулся с похожей ситуацией. Приведенное выше решение работает для пользовательских методов запроса. Но как добавить проекцию для встроенных методов. например, если у меня есть объект Order, /orders даст мне все заказы с примененной проекцией. Но когда я ищу индивидуальный заказ по ссылке self.href, например /orders/58fa7da00498e41f81a9f806, проекция не применяется. Как я могу этого добиться? - person pvpkiran; 24.04.2017