I was reading many articles to find the best Rest Client for java application, I found finally using Jersey with Apache HTTP client 4.5 is great but in a lot of articles I found that now Retrofit is the best (I didn't mention
Volley because in my case I don't need that the API supports caching.
Does Retrofit is better for a java client application. or is it just better for android? and why I didn't find this comparison before .. they cannot be compared?
Can I have a comparison between their performance, connection pooling, on which layer do they work, compression of the requests and responses, Timeout, de-serialization?
HTTP3 does not support connection pooling, is that why retrofit is used usually for android ?? so It will not be practical for a normal java application where it will cause connection leak.
My target is to find the best Rest API client with a high performance, and support high number of connections.
Thank you in advance
You're mixing different things together. To clear things up up-front:
Retrofit is a client library to interact with REST APIs. As such it offers the same abstraction level as Jersey, RESTeasy or Spring's RestTemplate. They all allow to interact with REST APIs using a type-safe API without having to deal with low level aspects like serialization, request building and response handling.
Each of those libraries uses a HTTP client underneath to actually talk to an HTTP server. Examples are Apache HTTP client that you mentioned, OkHttp or the plain-old HttpUrlConnection shipping with the JDK.
You can usually mix and match the different REST client libraries and HTTP clients except for Retrofit because Retrofit has a hard dependency on OkHttp since version 2 (with Retrofit 1.x you can use Apache HTTP Client, HttpUrlConnection or OkHttp).
Back to the actual question: What to pick when.
Android: It's easy here because JAX-RS, the API/technology behind Jersey and RESTeasy isn't supported on Android. Hence Retrofit is more or less your only option except maybe Volley if you don't want to talk HTTP directly. Spring isn't available either and Spring Android is abandoned.
JRE/JDK: Here you have the full choice of options.
Retrofit might be nice if you want a quick and easy solution to implement a third-party API for which no SDK is available or JAX-RS interfaces.
Spring's RestTemplate is a good choice if you're using Spring and there are no JAX-RS interfaces or you don't want to buy into JAX-RS, i.e. also using it on the server-side.
JAX-RS (Jersey, RESTeasy, …) is a good choice if you want to share interface definitions between client and servers or if you're all-in on JavaEE anyway.
Regarding performance: The main drivers here is the time spent on doing HTTP and (de)serialization. Because (de)serialization is performed by specialized libraries like Jackson or protobuf and all use the same (or you could at least make them to) there shouldn't be any meaningful difference.
It took a while to find, however I have found the perfect REST client library that makes our development declarative and easy. We can use this as the standard when developing new REST implementations or APIs.
It is called Feign, developed by the Netflix team and made to work with Spring Cloud Netflix. More details here on the project’s site.
Some features include:
- Integration with Jackson, Gson and other Encoders/Decoders
- Using OkHttp for network communication, a proven HTTP library
- Binding with SLF4J for logging features
- Interface-based implementation, minimal development. Below is a sample client:
#FeignClient("stores")
public interface StoreClient
{
#RequestMapping(method = RequestMethod.GET, value = "/stores")
List<Store> getStores();
#RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
Store update(#PathVariable("storeId") Long storeId, Store store);
}
And after #aha 's answer as quoted below:
JRE/JDK: Here you have the full choice of options.
Retrofit might be nice if you want a quick and easy solution to
implement a third-party API for which no SDK is available or JAX-RS
interfaces.
Spring's RestTemplate is a good choice if you're using
Spring and there are no JAX-RS interfaces or you don't want to buy
into JAX-RS, i.e. also using it on the server-side.
JAX-RS (Jersey,
RESTeasy, …) is a good choice if you want to share interface
definitions between client and servers or if you're all-in on JavaEE
anyway.
Feign works like retrofit and JAX-RS together: easy solution and can share interface definitions between client and servers and can use JAX-RS interfaces
Related
After some benchmarking I've found that AsyncHttpClient (https://github.com/AsyncHttpClient/async-http-client) seems to be the most stable and scalable async http client out there as it's based on NIO and seems to scale very well during load. I compared it against OkHttp and Apache Async and it seems to perform really well when simulating a backend with latency.
Unfortunately I have not yet found any way to expose it as a Spring AsyncRestTemplate, making a migration in our existing codebase a pain.
Does anyone know of any good bridge to RestTemplate's using the library, or if otherwise, how to create an issue in the Spring project to include it among the other Async http client factories?
You can't use RestTemplate for async requests, that's what the AsyncRestTemplate is for. You'll need to implement your own AsyncClientHttpRequestFactory. I briefly looked into the link you provided in your post, and it looked like you could wrap a AsyncRestClient and return BoundRequestBuilder from AsyncClientHttpRequestFactory.createAsyncRequest. Then onwards, you basically need to delegate the calls from Spring-specific interfaces to AsyncRestClient-specific classes. It shouldn't be too hard.
That said, Spring 5 Web comes with a WebClient that does async and more. I suggest seriously considering it before building your own async library, albeit on top of another one.
Here is an official java doc of spring RestTemplate.
Note: by default the RestTemplate relies on standard JDK facilities to
establish HTTP connections. You can switch to use a different HTTP
library such as Apache HttpComponents, Netty, and OkHttp through the
HttpAccessor.setRequestFactory(org.springframework.http.client.ClientHttpRequestFactory)
property.
EDIT:
OK here you go with spoon feeded answer:
AsyncRestTemplate template = new AsyncRestTemplate(
new HttpComponentsAsyncClientHttpRequestFactory());
HttpComponentsAsyncClientHttpRequestFactory is part of spring since 4.0
I am trying to use the JAX-RS 2.0 client in CSF 3.x, but am having some difficulty finding a way to programatically add interceptors to the client. I'n particular I'm trying to add the regular gzip and logging interceptors, something that worked well on the server side, to the client side as well.
I would prefer to use the JAX-RS standard client, rather than the CXF-specific WebClient or Proxy methods. I'm not opposed to some CXF-specific code in configuring the client, or using a different API than can then be converted to a JAX-RS standard Client/WebTarget, but to tie the entire client to CXF is undesirable to me.
I can accomplish what I intend to do by implementing my own Client(Request|Response)Filters, but it would be preferable to reused the well-tested logic that CXF already contains for this purpose.
This all seems rather simple to do if I was using Jersey, but does anyone have any idea on how to do this in CXF?
First of all, I'm not trying to start a flame-war here. I know Jersey sufficiently well, but have hardly used httpclient.
What are the key differences between jersey-client and Apache's httpclient? In what areas is one better than the other? Is there a good comparison chart somewhere? Which one performs better with larger files (say 2048 MB)?
Many thanks for your comments!
These two things probably should not be compared directly. Jersey is a REST-client, featuring full JAX-RS implementation, neat fluent API and a powerfull filter stack. Apache Http Client is a HTTP-client, perfect in managing low-level details like timeouts, complex proxy routes and connection polling. They act on a different levels of your protocol stack.
When you're using Jersey there is always some kind of HTTP client backend involved. Given no backend explicitly, Jersey will use HttpUrlConnection as a default backend.
Jersey with HttpUrlConnection backend example:
Client client = Client.create();
WebResource webResource = client.resource("http://localhost:8080/path");
ClientResponse response = webResource.accept("application/json")
.get(ClientResponse.class);
Jersey with Apache Http Client backend example:
HttpClient apacheClient = HttpClientBuilder.create().build();
Client client = new Client(new ApacheHttpClient4Handler(apacheClient,
new BasicCookieStore(),
true));
WebResource webResource = client.resource("http://localhost:8080/path");
ClientResponse response = webResource.accept("application/json")
.get(ClientResponse.class);
Please note usage of Handler in the last example. This is a key integration abstraction for Jersey to incorporate and utilize various backends. First example uses URLConnectionClientHandler deep under the hood.
Speaking about performance and features it makes little sense to compare Apache Http Client with Jersey. One may want to compare different Jersey backends here, as Jersey itself is merely a wrapping API. I'd like to highlight some key differencies between HttpUrlConnection and Apache Http Client based on my own experience:
HttpUrlConnection
No external dependencies are necessary. This may be quite valuable on embedded or mobile platforms.
Extremely well documented everywhere
Has poorly designed API. HttpUrlConnection-based implementation is difficult to maintain and extend.
Many features are configured through JVM properties, some of which may be non-reconfigurable during runtime.
In some cases hopeless at handling timeouts. You may end up setting 10 different JVM properties for different timeouts and still get your connections hanging forever in some circumstances.
Since Gingerbread is a recommended http client API for Android.
Apache Http Client
For 3.X versions it's performance was somewhat similar to HttpUrlConnection. Version 4.1 contains lots of performance enchancements and performs way better than it's counterpart
Quite good at managing connection and data read timeouts
It's design follows Open/Closed Principle, so you can customize almost any part of HTTP processing with your own implementation. Examples: redirect strategies, retry strategies, custom cookie storages, interceptors for requests/responses, etc.
Provides rich proxy support with customizable route builders for complex multy-proxy paths
Has out of the box per-route connection pool. This may give a good performance benefit if SSL/TLS is used, especialy having hardware PKCS#11 tokens involved. HttpUrlConnection also has an internal pooling, but you have no tools to customize what or when to pool, no monitoring facilities to check the pool state.
Features detailed logging
Keep in mind, that it also possible to use other backends (e.g. for non-blocking clients) with Jersey if you have an appropriate com.sun.jersey.api.client.ClientHandler implementation.
I researched a lot about it, but I wasn't able to reach a conclusion about this matter.
I'm creating a new front-end in GWT, using GWT-Platform and GIN, for an existing application. But I can't figure out which is the best way to interact with the existing REST API.
What I found up to now is that I can use RequestBuilder to do the calls, and that also exists the RestyGWT framework for REST communications. But I don't know how to integrate any of them with GIN Injector. And I have doubts on how to translate the JSON return from the service to the JTO available in the client code translated by GWT.
The last one specially due to a legacy code that translate the Beans from the server to a kind of generic Json format.
So what I want to know is do anybody have experience integrating legacy backend to a new GWT front-end with REST. How they integrate both? How they solve, if experienced, the Beans integration?
I agree with Ümit, If you are worried about the "communication" between backend and frontend don´t get stress:
Something like:
public String serializeToJson(YoutEntity report) {
AutoBean<YoutEntity > bean = AutoBeanUtils.getAutoBean(report);
return AutoBeanCodex.encode(bean).getPayload();
}
public YoutEntity deserializeCompanyFromJson(String json) {
AutoBean<YoutEntity > bean =
AutoBeanCodex.decode(factoryYourEntity, YoutEntity .class, json);
return bean.as();
}
is perfectly possible using Autobeans!
And using GWT you can share your entities between Client and Server, so you don´t need to touch anything.
Also, in our last project using Apache Wink as a REST client, in the server using the correct annotations we were able to have the Entity automatically from the JSON, so is even easier (but I think most of the REST libraries can do the same).
Thanks!
Your question touches a couple of different aspects both client-side but also server-side.
In general there is nothing special about integration between GWT and a REST API.
On the GWT side there are different ways to consume a REST API:
RequestBuilder to manually create the HTTP Requests to the REST API. You have to parse the JSON payload. There are different ways to do this:
Javascript OVerlay Types.
3rd party library (Piriti)
AutoBeans
RestyGWT (backend + GWT. See this tutorial)
Restlet has a GWT client (see this thread for more details).
GIN per se doesn't have anything to do with the communication with a REST API.
It's only responsible for dependency injection on the client side.
The translation of beans to JSON depends on the backend. Spring can basically automatically serialize Java beans into JSON using Jackson.
I am looking for a way to setting up a JSON proxy client in a spring framework way.
We are going to use Spring MVC on the server side. We don't like XML as they are overkill and heavy. JSON seem to be a lightweight and effective message container for us.
However, I've search around and read http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html many times and I don't find any hits to put my spring client into a JSON client.
They provided RMI, Http, JAX-WS, SOAP and others. But nothing related to as a client of MVC (which I guess it could be common as we don't want to write it twice)
RestTemplate looks good but I am wonder is it the suggested way to do in spring 3.0.
The RestTemplate is indeed the preferred way of accessing rest services.
I've been in the same position as you - looking through the Spring docs for how to implement a simple JSON client API. I ended up implementing it myself, as I only needed it for a few RPC-like calls to another webapp. IIRC Jax-RS has this capability so you might want to invest in implementing it - for my needs it seemed overkill.
All there is to it:
write a simple method to perform the HTTP GET to the JSON web service and return a String (I used Apache HttpClient)
pass the String to Jackson to deserialize into a Java object (see mapper.readValue())
This assumes you already know what kind of object you expect to get back from a given JSON web service.
As an aside, the other thing I needed from my Spring MVC JSON web service was the ability to do JSONP (cross site callback) for consumption in the browser with JQuery (note: JSONP is not secure so use at your own risk). The automagic Spring JSON webservices that Bozho outlined does not provide an option for JSONP. The easiest way to provide JSONP is to implement a simple servet filter.