Аннотации JAX-RS: лучше использовать интерфейсы или классы?
Я нахожусь на ранней стадии реализации REST и недавно узнал, что мы можем добавлять аннотации JAX-RS к нашим интерфейсам Java-сервисов, а не к реализациям классов.
Мне кажется, что это может привести к чистому файлу класса, но также может привести к тому, что разработчики будут постоянно путаться между файлами.
Каковы преимущества и недостатки каждого подхода?
Ответы
Ответ 1
Вы должны поместить его в интерфейс. Скорее, моя практика требует, чтобы я поместил ее в интерфейс, потому что мои клиентские и серверные стороны используют одно и то же определение jax-rs.
Я склонен использовать jax-rs для REST-RPC.
Причина REST заключается в том, чтобы позволить URL-адрес URL-адреса веб-сервиса быть работоспособным и "доступным для клиента" с помощью любой структуры программирования.
Использование jax-rs ограничивает использование java на стороне сервера.
Использование jax-rs для REST-RPC ограничивает использование java на стороне сервера и клиента.
Что такое REST-RPC?
В не слишком запутанном отношении объяснения RPC - это способ вызова функции/метода на клиенте, который при передаче по каналу обслуживается сервером, так что на стороне сервера существует одна и та же функция/метод.
RestEasy позволяет вам использовать определение jax-rs на стороне клиента для вызова той же функции, обслуживаемой на стороне сервера.
RestyGWT тоже с некоторой модификацией интерфейса для указания метода обратного вызова позволит вам (в некоторой степени) использовать определение jax-rs как на стороне клиента, так и на стороне сервера. Вам просто нужно написать script, чтобы переместить возвращаемый тип в аргумент типа метода обратного вызова.
Вы можете сомневаться, почему ограничиваете себя выполнением java с обеих сторон? Разве это не победит одну из целей в жизни REST? Я думаю, что Jax-rs REST-RPC - удобный путь для внедрения и тестирования службы jax-rs. Если вы хотите реализовать службу jax-rs, вы, вероятно, сделаете это изначально в Java с обеих сторон. И тогда, когда ваша служба выйдет из-под земли, вы можете начать писать PHP или python-клиенты.
Написание ваших jax-rs в файлах интерфейса позволит вам опубликовать ваш интерфейс для операций на стороне клиента. Это особенно справедливо для REST-RPC. Тем не менее, вы можете выполнить прокрутку над вашим определением jax-rs, чтобы опубликовать свой API веб-службы для не-java-программистов.
У меня есть некоторые продолжающиеся расхождения на эту тему...
http://h2g2java.blessedgeek.com/2011/11/gwt-with-jax-rs-aka-rpcrest-part-0.html.
Ответ 2
Я думаю, что я должен почтительно не соглашаться с Blessed Geek здесь. То, что упоминается, является очень конкретным прецедентом, который требует использования аннотаций на интерфейсе.
В моем собственном опыте я столкнулся с ситуациями, когда структура либо по дизайну, либо по ошибке не отвечает должным образом на размещение аннотаций на интерфейсе. Например, Apache CXF неправильно обрабатывает запросы @PUT с помощью @PathParams, определенных в пути, когда вы помещаете аннотации в интерфейс. Не спрашивай меня, почему. CXF не одинок в этом; Spring Безопасность имеет аналогичные ограничения при размещении аннотаций на интерфейсах. Таким образом, это контрапункт к упомянутому выше.
В тех случаях, когда вы можете свободно выбирать, где разместить аннотации, , я настоятельно призываю вас рассмотреть, что имеет смысл с точки зрения намерения, дизайна и простоты разработки.
Как философский аргумент, некоторые люди говорят, что размещение аннотаций на интерфейсах - это еще одна форма контрактного программирования - вы говорите, что реализации будут соблюдать определенные правила.
Другая сторона этой монеты (в зависимости от вашего определения интерфейсов) заключается в том, что интерфейсы не должны заботиться о том, какие шаги их разработчики предпринимают для достижения цели, определенной в контракте метода. Например, зачем размещать аннотацию @Transactional на интерфейсе, если у вас могут быть две реализации, одна из которых не знает, что такое "транзакция"?
На практике линии размываются. В случае определения остаточной конечной точки вы можете предпочесть размещение соответствующих аннотаций на интерфейсе. Я думаю, что это имеет смысл в большинстве случаев; вы, вероятно, не будете иметь несколько реализаций, где одна и та же сигнатура метода отвечает на различные HTTP-глаголы. Однако вы можете придумать ситуацию, когда разные реализации предпочитают потреблять и производить разные типы медиа.
Итак, большая идея здесь - "это зависит". Но, надеюсь, это пища для размышлений для тех, кто может наткнуться на этот вопрос.
Ответ 3
У меня был аналогичный вопрос при использовании JAX-RS с JAX-B. Я надеялся использовать аннотации JAX-B на интерфейсах, а не на классах. Это не работает, как я и ожидал, причина объясняется немаршальщиком. Чтобы решить свои проблемы, я закончил использование классов. Здесь описано, почему и что я нашел.