views:

1305

answers:

5

Ideally, I am looking for something like JAX-RS (using annotations to describe the services I want to call), but allowing to call REST services implemented using other technologies (not JAX-RS). Any suggestion?

+1  A: 

HttpClient mostly.

Gandalf
This works, but I was hoping for something more high level.
Alessandro Vernet
You really should not need anything more high level. As long as you can do the standard verbs, determine the media-type of the response and configure http headers. All of the intelligence on the client should go into encapsulating the media-type formats. What media-types are you planning to use?
Darrel Miller
Darell, I guess the main part that HttpClient doesn't do has to with XML serialization/deserialization of the "parameters". I.e. getting from parameters that look natural in a Java API to an XML document, and vice versa.
Alessandro Vernet
I don't understand. There qre query string parameters which I am assuming HttpClient handles fine. There are parameters that you put in the URL that JAX-RS parses out with a URI template, and then there is the entity body that gets POSTed which contains some form of media-type. What XML parameters are you refering to?If you are trying to create some kind of Java class on the client with a method that looks like it is doing an RPC onto the server then you are kind of defeating the purpose.
Darrel Miller
Darell, let's say you want to update an employee record by calling an existing REST API that expects a PUT of an <emp><first>John</first><last>Smith</last></emp> document on /employees/123 (where 123 is the ID of the employee). Your Java API might look like emp.update("John", "Smith") and in the implementation you need to create the XML document and PUT it to the REST service. Does that make more sense?
Alessandro Vernet
+1  A: 

I suggest you take a look at the WADL project. WADL is to REST what WSDL is to SOAP.

You first need to define the REST interface using WADL. Then you can run the wadl2java tool on it to generate client stubs for the REST calls.

Once you have the WADL for a web service you can implement tools which do other things with it as well, e.g. generate server side stubs, generate documentation, etc.

DSO
Very interesting. I will make sure to have a look at it. Thank you for sharing this.
Alessandro Vernet
This is a guaranteed way to create coupling between the client and server, which is exactly what REST is trying to avoid. Forget WADL, you just don't need it.
Darrel Miller
+1 WADL is the suxor
Gandalf
Darrell, Gandalf, any specific issue with WADL? In my case, the service are already implemented using another technology, so there wouldn't be any coupling introduced. I imagine that whoever wants to call those REST services will write WADL descriptions, based on which a Java API is generate to call the REST services.
Alessandro Vernet
There will always be a coupling between client and server, WADL just makes it explicit. Also, most arguments against WADL assume the clients are javascript running in browser or some other dynamic language, where generating stubs is doesn't provide much value. For compiled languages OTOH, it supports better tooling (code completion, intellisense, etc). However IMO WADL does go too far into questionable territory (e.g. MIME-type descriptions). There is a reason why it isn't mainstream yet. I was simply suggesting you look at it and see if it fits your needs, or at least provide some ideas.
DSO
@DSO, thank you for the great advice. I will indeed look at WADL and just consider it as an option. This has all been very useful.
Alessandro Vernet
+2  A: 

JAX-RS (JSR311) does not define a client API, but most JAX-RS implementations have one, like Jersey, RESTeasy or Apache CXF. The Restlet framework also has client support as well as a seperate HTTP Client extension.

Since these are specialized libraries/frameworks for REST, I'd suggest you look into these.

joschi
+4  A: 

You wrote in a comment that you were "hoping for something more high level" than HttpClient. It sounds like Restlet would be perfect. It provides a high-level API for implementing and using RESTful web applications, with plug-and-play adapters for the lower-level implementations.

For example, to POST a webform to a resource using Restlet 1.1:

Client client = new Client(Protocol.HTTP);

Form form = new Form();
form.add("foo", "bar");
form.add("abc", "123");

Response response = client.post("http://host/path/to/resource", form.getWebRepresentation())

if (response.getStatus().isError()) {
    // deal with the error
    return;
}

if (response.isEntityAvailable()) {
    System.out.println(response.getEntity().getText());
}

If you need to set more options on the request, you can use a Request object:

Form form = new Form();
form.add("foo", "bar");
form.add("abc", "123");

Request request = new Request(Method.POST, "http://host/path/to/resource");

request.setEntity(form.getWebRepresentation());

request.setReferrerRef("http://host/path/to/referrer");

Response response = client.handle(request);

HTH!

Avi Flax
I've just used Restlet Client in a product and find the API to be nice and concise. I have it sitting on top of Apache HTTP Client, and there are other "client connectors" I might have used.
Jim Ferrans
A: 

As Gandalf and Darrel Miller said, HttpClient.

You don't need to be constructing XML from HTTP params. XML should only be your interface between two separate systems. Using HttpClient puts you in Java with the String values at your disposal, goinn back into XML from there is needless.

If you are going back into XML at this point in order to send out to another system, you should be thinking about moving the values from the HTTP params back in to your domain/app logic before communicating with another system. This is necessary to keeps proper seperation of application logic from inter system communications.

Brad