В JAX RS различия между возвращаемым откликом и бином или коллекцией бобов (DTO)
Я работаю над созданием API REST. Мой вопрос, при использовании Джерси, в чем различия между построением моих служб и возвратом объекта Response или возвратом бина или коллекции. Меня интересуют только успешные звонки, я выкидываю соответствующие исключения для ошибок и исключительных ситуаций.
Вот пример:
@Produces(MediaType.APPLICATION_JSON)
public Response search(FooBean foo){
List<FooBean> results = bar.search(foo);
return Response.ok(results).build();
}
против
@Produces(MediaType.APPLICATION_JSON)
public List<FooBean> search(FooBean foo){
List<FooBean> results = bar.search(foo);
return results;
}
Я видел оба использованных примера, и я предпочел бы второй сценарий, чтобы было проще распознать метод обслуживания. Я изучил ответы на оба эти метода, и они кажутся идентичными.
Мысли?
3 ответа
Различия объяснены в спецификации JAX-RS:
3.3.3 Тип возврата
Методы ресурса МОГУТ возвращать void, Response, GenericEntity или другой тип Java, эти возвращаемые типы сопоставляются с телом объекта ответа следующим образом:
недействительным
В результате получается пустое тело объекта с кодом статуса 204.
отклик
В результате получается тело объекта, сопоставленное из свойства объекта Ответа с кодом состояния, указанным свойством статуса Ответа. Нулевое возвращаемое значение приводит к 204 коду статуса. Если свойство статуса Ответа не установлено: код состояния 200 используется для свойства, отличного от NULL, и код состояния 204, если свойство объекта имеет значение NULL.
GenericEntity
В результате получается тело сущности, сопоставленное из свойства Entity GenericEntity. Если возвращаемое значение не является нулевым, используется код состояния 200, нулевое возвращаемое значение дает код состояния 204.
Другой
В результате получается тело сущности, сопоставленное с классом возвращаемого экземпляра. Если возвращаемое значение не является нулевым, используется код состояния 200, нулевое возвращаемое значение дает код состояния 204.Методы, которым необходимо предоставить дополнительные метаданные с ответом, должны возвращать экземпляр Response, класс ResponseBuilder предоставляет удобный способ создания экземпляра Response с использованием шаблона построителя.
"Обычные" бобы отображаются так же, как Response
есть, за исключением того, что Response
позволяет устанавливать дополнительные метаданные (заголовки ответа, специализированный статус, специализированный тип контента и т. д.). Что касается того, какой из них использовать, это полностью зависит от вас тоже - Response
дает вам больше гибкости, но обычные бины более "самодокументируются".
Там нет никакой разницы, если вы хотите всегда возвращать ответ 200 - OK
, перехват и манипулирование всеми исключениями, которые могут произойти до или после того, как ваш метод вернет результат, с перехватами или WebApplicationException
, Итак, оба эти метода приведут к одним и тем же ответам.
Единственное отличие заключается в определенных сценариях, таких как возврат нулевых объектов или создание объекта, как в следующем примере:
@POST
@Consumes("application/json")
public Response post(String content) {
URI createdUri = ...
Object createdContent = create(content);
return Response.created(createdUri).entity(createdContent).build();
}
В этом случае возврат будет 201 - CREATED
(С помощью URI для доступа к созданному объекту)
Итак, следующий метод:
@POST
@Consumes("application/json")
public Object post(String content) {
URI createdUri = ...
Object createdContent = create(content);
return createdContent;
}
... вернет ответ 200 - OK
Если вас не волнует, какой статус ответа получит ваш клиент, вы можете без проблем использовать любую декларацию.
Источник: Джерси.
Мое личное мнение: если ответ содержит DTO (Bean/Collection of bean), то служба rest всегда должна возвращать DTO, но не объект Response.
Мотивация: рано или поздно, вам будет предложено упростить использование услуг отдыха для клиентов, предоставляя api отдыха для клиентов. Обычно вы должны извлечь для него остальные интерфейсы и внедрить их с вашими сервисами отдыха. Эти остальные интерфейсы используются клиентами вашего отдыха клиента.
И с точки зрения клиента, существует огромная разница между обработкой DTO и простым Response. В случае использования Response ваш клиент вынужден:
- Проверьте код ответа явно, чтобы обработать успешный ответ
- Обрабатывать ошибки, проверяя коды явно
- Преобразуйте тело своего ответа в DTO самостоятельно.
Это означает, что обработка Response очень похожа на возврат кодов ошибок в методах, что считается очень плохой практикой. Для обработки ошибок в одном месте используются исключения (я не говорю о способах обработки ошибок FP, что является лучшим).
Итак, что вы можете сделать:
- Если запрос успешно обработан, преобразуйте данные вашего сервиса отдыха в DTO/Bean и верните их.
- Если проверка не удалась или что-то пошло не так, создайте исключение в службе отдыха. Возможно, преобразователь исключений по умолчанию не подходит для вас, поэтому вам придется реализовать собственный сопоставитель исключений.
Так что если подумать заранее, вам следует вернуть DTO.
Один вариант использования, когда должен быть возвращен простой ответ - например, при экспорте файла. Кажется, JAX RS не позволяет вернуть объект InputStream. Не уверен, это нужно проверить.
Другой вариант использования был указан @Perception, но это скорее исключение, чем правило:
Методы, которым необходимо предоставить дополнительные метаданные с ответом, должны возвращать экземпляр Response, класс ResponseBuilder предоставляет удобный способ создания экземпляра Response с использованием шаблона построителя.
Примечание: это общий вопрос для JAX RS, не зависит от точной реализации, такой как Resteasy или Jersey