Domanda

Please forgive me if any of this is wrong -I'm completely new to Java. My task is to set up the client/server architecture for an upcoming Facebook game. On the server-side, I have:

  • Java
  • Tomcat
  • RestEasy
  • BlazeDS
  • Enunciate

All held together with Maven. I can annotate RESTful endpoints with @Path() and they will spit out objects serialized in AMF when I hit them in the browser. So far so good. Now I need to consume these endpoints on the client/Flex-side. Enunciate has generated AS files for the types I have annotated with @XmlRootElement in Java, and I can use these types in my AS3 code. The problem is that hitting REST endpoints in AS3 is pretty ugly. It looks something like this:

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);

Ugly -and I have to write this by hand in order to get the benefits of strong typing. However! I noticed when digging through the source code that if the @WebService and @WebMethod tags are used instead of @Path, wonderful strongly-typed AS3 wrappers for my service classes are generated by Enunciate, along with corresponding AS3 events. It also generates the correct services-config.xml! The usage then becomes something like this:

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!");

As you can see, the consumer of the generated code does not need to know where the endpoint is, what types are returned from the events, etc. I would like to go this route because I believe it will be easier to maintain. That brings me to my questions:

  1. Why are the wonderful Service and ServiceEvent objects only generated for @WebService and @WebMethod (which the Internet tells me is JAX-WS) but not @Path? Is it work that hasn't been done, or work that can not be done given the spec differences between JAX-RS and JAX-WS? (I see that the as3-endpoint.fmt is specifically only applied to @WebService in the code)
  2. Am I wrong in wanting to use REST here? The Java/Tomcat/RestEasy/BlazeDS stack was recommended by my CTO but it seems to me (after fiddling for a day or two) that BlazeDS/Flex don't get along that well with REST.
  3. Is there a Java->AMF->Flex stack I should be considering?

Thank you for your time, and again I am sorry if these are obvious issues. My background is in game development, not web development.

È stato utile?

Soluzione

Why are the wonderful Service and ServiceEvent objects only generated for @WebService and @WebMethod (which the Internet tells me is JAX-WS) but not @Path? Is it work that hasn't been done, or work that can not be done given the spec differences between JAX-RS and JAX-WS? (I see that the as3-endpoint.fmt is specifically only applied to @WebService in the code)

It's work that could be done, but hasn't yet. And there's an unanswered question of whether it should be done.

REST is hard. Service-oriented APIs (e.g. SOAP, AMF) are much more intuitive to developers. JAX-RS has made creating REST APIs easy to do, but at the cost of giving developers more rope to hang themselves with. More specifically, JAX-RS makes it easy to create HTTP-based APIs, but just because it's using HTTP doesn't make it REST. For a better understanding of what I'm talking about I'd suggest Martin Fowler's essay on the Richardson Maturity Model:

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

So there's a lot more to REST than just making an HTTP request and parsing the response. By extension, there is a lot more to creating a client-side service that calls a JAX-RS resource (i.e. @Path) than just wrapping HTTP calls in a convenient AMF service class. Cacheing, layering, HATEOAS, etc., etc., all come into play and would have to be "hidden" in a client-side service generated by Enunciate.

Am I wrong in wanting to use REST here?

You're not wrong but it appears that you might be underestimating what it means to "use REST". So IMO, you've got two options:

  1. Just create a service-oriented API using JAX-WS.
  2. Go learn what REST really is and how to really apply it to your problem space. And don't underestimate the complexity in this. REST is hard.

The Java/Tomcat/RestEasy/BlazeDS stack was recommended by my CTO but it seems to me (after fiddling for a day or two) that BlazeDS/Flex don't get along that well with REST.

Perhaps. At least one thing is for sure: the designers of BlazeDS/AMF weren't thinking REST when they designed their stack.

Is there a Java->AMF->Flex stack I should be considering?

BlazeDS and GraniteDS are the only two I can think of. They're both good IMO, so just take your pick.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top