Вопросы AMF/JAX-RS (некоторые общие, некоторые специфичные для Enunciate)

Пожалуйста, прости меня, если что-то из этого не так - я новичок в Java. Моя задача - настроить архитектуру клиент / сервер для будущей игры на Facebook. На стороне сервера у меня есть:

  • Джава
  • Кот
  • Resteasy
  • BlazeDS
  • провозглашать

Все держится вместе с мавеном. Я могу аннотировать конечные точки RESTful с помощью @Path(), и они будут выплевывать объекты, сериализованные в AMF, когда я нажму их в браузере. Все идет нормально. Теперь мне нужно использовать эти конечные точки на стороне клиента /Flex. Enunciate сгенерировал файлы AS для типов, которые я аннотировал с помощью @XmlRootElement в Java, и я могу использовать эти типы в своем коде AS3. Проблема в том, что попадание на конечные точки REST в AS3 довольно уродливо. Это выглядит примерно так:

function resourceRetrieved(event:Event):void {
  var stream:URLStream = URLStream( event.target );
  var resource:SomeJavaClass = ( stream.readObject() as SomeJavaClass );
  lblResult.text = resource.message; 
}

var request:URLRequest = new URLRequest("http://localhost:8080/rest/somefunc");
request.method = URLRequestMethod.GET;

var variables:URLVariables = new URLVariables();
variables.message = "This is my test string!";
request.data = variables;

var resourceStream:URLStream = new URLStream();
resourceStream.addEventListener("complete", resourceRetrieved)
resourceStream.load(request);

Гадкий - и я должен написать это от руки, чтобы получить преимущества строгой типизации. Тем не мение! При просмотре исходного кода я заметил, что если вместо @Path используются теги @WebService и @WebMethod, Enunciate генерирует замечательные строго типизированные оболочки AS3 для моих классов обслуживания вместе с соответствующими событиями AS3. Он также генерирует правильный services-config.xml! Затем использование становится примерно таким:

function onSomeFuncEvent(event:SomeJavaServiceEvent):void {
  lblResult.text = event.result;
}

var service:SomeJavaService = new SomeJavaService();
service.addEventListener( SomeJavaServiceEvent.SomeFuncEvent, onSomeFuncEvent );
service.someFunc("This is my test string!");

Как видите, потребителю сгенерированного кода не нужно знать, где находится конечная точка, какие типы возвращаются из событий и т. Д. Я хотел бы пойти по этому пути, потому что я считаю, что его будет проще поддерживать. Это подводит меня к моим вопросам:

  1. Почему замечательные объекты Service и ServiceEvent генерируются только для @WebService и @WebMethod (что, как мне говорит Интернет, это JAX-WS), но не для @Path? Это работа, которая не была сделана, или работа, которая не может быть выполнена, учитывая различия в спецификациях между JAX-RS и JAX-WS? (Я вижу, что as3-endpoint.fmt специально применяется только к @WebService в коде)
  2. Я ошибаюсь, желая использовать REST здесь? Мой технический директор рекомендовал стек Java/Tomcat/RestEasy/BlazeDS, но мне кажется (после возни в течение дня или двух), что BlazeDS/Flex не ладят с REST.
  3. Есть ли стек Java->AMF->Flex, который я должен рассмотреть?

Спасибо за ваше время, и еще раз прошу прощения, если это очевидные проблемы. Мой опыт в разработке игр, а не в веб-разработке.

1 ответ

Решение

Почему замечательные объекты Service и ServiceEvent генерируются только для @WebService и @WebMethod (что, как мне говорит Интернет, это JAX-WS), но не для @Path? Это работа, которая не была сделана, или работа, которая не может быть выполнена, учитывая различия в спецификациях между JAX-RS и JAX-WS? (Я вижу, что as3-endpoint.fmt специально применяется только к @WebService в коде)

Это работа, которую можно сделать, но пока нет. И остается без ответа вопрос о том, должно ли это быть сделано.

Отдых тяжело. Сервисно-ориентированные API (например, SOAP, AMF) гораздо более интуитивно понятны для разработчиков. JAX-RS сделал создание API-интерфейсов REST простым, но за счет предоставления разработчикам больше веревки, с которой можно повеситься. В частности, JAX-RS упрощает создание API на основе HTTP, но только потому, что он использует HTTP, не делает его REST. Для лучшего понимания того, о чем я говорю, я бы предложил эссе Мартина Фаулера о модели зрелости Ричардсона:

http://martinfowler.com/articles/richardsonMaturityModel.html

Так что REST - это намного больше, чем просто выполнение HTTP-запроса и анализ ответа. Кроме того, создание клиентской службы, которая вызывает ресурс JAX-RS (т. Е. @Path), намного больше, чем просто упаковка HTTP-вызовов в удобный класс обслуживания AMF. Кеширование, многоуровневое размещение, HATEOAS и т. Д. И т. Д. - все это вступает в игру и должно быть "скрыто" в клиентской службе, сгенерированной Enunciate.

Я ошибаюсь, желая использовать REST здесь?

Вы не ошибаетесь, но, похоже, вы недооцениваете значение "использовать REST". Итак, ИМО, у вас есть два варианта:

  1. Просто создайте сервисно-ориентированный API, используя JAX-WS.
  2. Узнайте, что такое REST на самом деле и как его применить в своей проблемной области. И не стоит недооценивать сложность в этом. Отдых тяжело.

Мой технический директор рекомендовал стек Java/Tomcat/RestEasy/BlazeDS, но мне кажется (после возни в течение дня или двух), что BlazeDS/Flex не ладят с REST.

Может быть. По крайней мере, одно можно сказать наверняка: дизайнеры BlazeDS/AMF не думали о REST, когда разрабатывали свой стек.

Есть ли стек Java->AMF->Flex, который я должен рассмотреть?

BlazeDS и GraniteDS - единственные два, о которых я могу думать. Они оба хорошие IMO, так что просто выбирайте.

Другие вопросы по тегам