Caching based on Cache-Control Headers with Feign Client - java

We are moving away from HttpClient to now use RestTemplate, even better FeignClient. But looking at the https://github.com/OpenFeign/feign it seems Response Caching is in road map of feign 11.
I was looking at possibility of writing a custom mechanism to support Caching based on Cache Control headers. I will try to explain this with sample example
Service A exposes an API /greet/{name}. This API sends max-age
response header so that client can cache the response.
Service B calls this API using FeignClient
Below is sample Feign Interface.
#FeignClient(name="app/app", contextId="AppService", configuration=AppConfig.class)
public interface AppFeignService {
#GET
#Path(value = "/api/greet/{name}")
public String greet(#PathParam("name") String name);
}
One way to support caching is, add an intermediate layer above feign client and cache the response based on needs. But this takes the caching logic to client side and I want to make sure the decision of how much to cache (max-age header) should be left to server and client shouldn't drive it.
Question here is - do we know when we can expect caching support in Feign? Is there any interim solution we can go with to still have caching support? Feign is really good considering its abstraction and we do not really want to write code to call it using RestTemplate.
Your recommendations are highly appreciated.

I am actually building my own hobby app and was thinking about exactly same thing and then I hit upon your question. What I have decided so far is to use a okhttpClient as proxy (this one has a very good caching support) to my micro-service. I am using spring boot. I am looking for a way to do it.
So every request from the Fiegn client will first hit my okhttp client with caching support and then it will do all the magic, to forward the request to eureka server micro service or not.
My micro service uses a very specific http client to do the request and I don;t want to touch that part.

Related

How to develop a client web application that execute Rest Ws Spring

In my application server Wildfly I have a war which contains code of a RESTful Web Service done with Apache CXF and Spring Framework, this war call an external ws.
With Postman I call API inside my war with success :-) , I ask what technology is better to develope my new client web application to emulate Postman.
Thanks in advance
I always use the Apache HTTP client to call external web services, regardless if it is SOAP or REST using JSON or XML or whatever other data format.
The reason is: In real live, more than 50% of all web services do not follow the standards. Working around the standards is often hard work when you use frameworks. But with the Apache HTTP client it is easy to implement workarounds for whatever might happen, for example:
Fix wrong XML Namespaces or content by search/replace before parsing it.
Process HTTP result codes in non-standard way
Send and receive custom HTTP headers
Use requests that combine GET (Url-) parameters with POST body
non-standard encryption
non-standard authentication (not everything that they call OAuth2 is really OAuth2)
Work with certificates - even self-made certifictes that do not match any root certificate
All that might sound ridiculous to you but it happens very very often in the projects where I was involved in. The Apache HTTP client gives you full access to the HTTP protocol and is easy to understand.
You can still marshal and unmarshal the objects to XML/JSON using your framework. But it is better to keep control over the many small details of the HTTP communication.
I prefer Spring RestTemplate. You can inject the RestTemplate in your beans and send GET and POST easily:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.ResponseEntity;
public class Test {
#Autowired
RestTemplate restTemplate;
public ResponseEntity<Response> test(String url, Request request){
return restTemplate.postForEntity(url, request, Response.class);
}
}

How do I test a REST client?

I have a REST client in Java that is ready to connect to a REST server, send a specific request and get a response back. However, the actual REST server is not available during development time (it is hosted by a 3rd party and only available in the isolated local net of the target machine) and we still want to test connectivity and interaction with the server.
Can you point me to a product or technology that in the first place lets me quickly create a fake REST server (or at least mock it) according to the specification of the REST call parameters? I did some research on the web but haven't had a "yes, this is it!" moment yet.
You can use any rest mocking framework to achieve this. As per my experience
Wiremock is the best framework for RES API Mocking.
http://wiremock.org/
You can use mockwebserver library by square. It's pretty simple to use and do exactly what you attempt to do.
Little usage sample:
MockWebServer server = new MockWebServer();
server.enqueue(new MockResponse().setBody("hello world"));
server.start();
For client testing, I would recommend a tool like SOAP UI or Postman. But for mocking the REST service itself, I would actually recommend just creating some dummy endpoints in your Java web application and using that. At each endpoint you could do something hard code a simple response, in JSON, XML, or whatever would make sense with your service. Then, when you finally come to actual development, you will already have a functioning framework for your REST service. You would just need to fill in the missing pieces.
This makes sense because you are going to need to setup REST support in your Java code anyway, and the amount of effort to just add stubs should be minimal. This approach is also attractive from the point of view that it avoids any potential surprises from switching from a mock REST service to the actual one.

Consuming a REST API in Java

I need to consume REST API. There are many REST clients for Java. Are there any areas of concerns before proceeding this?
You can use HttpClient for that. However, if you are working on a spring enabled project, I would recommend using RestTemplate.
Rest template provides an abstraction over HTTP client as a result of which you will not have to deal with serialization/deserialition, error handling, SSL configuration in every part of code where you make a REST call. You will just need to configure those with REST template configuration once and not worry about it. This makes your code clean and easily maintainable in case you wish to change the way your application talks to the back-end restful application in future.

I have REST API and want to reuse it for exposing differen format API on same server

I implemented and exposed REST API on my server. Now I need to expose same API, but I can't use REST (it's actually websocket messages), it will be some custom format. Don't ask why )
I imagine message transformation from my custom format to http request, then process it in my web-server, transform response back to my custom format, and send to client.
The simplest way is regular http call to localhost. For example (java):
HttpURLConnection con = (HttpURLConnection) new URL("http://localhost/api/...").openConnection();
and so on, or using some http client library.
But I'm afraid there will be too much overhead, creating connection, etc.
Another ways:
I use Tomcat. Push my request directly to tomcat somehow.
I use Guice, and all requests go through GuiceFilter. Craft ServetRequest, ServletResponce and FilterChain objects and directly call GuiceFilter.doFilter.
I use GuiceContainer for Jersey. Some test frameworks use it for REST API testing, but also need to craft request/response objects.
There is no standard way to craft request object at all.
And I don't know on which level it's better to add my custom requests.
Hope I described my problem clearly.
Atmosphere may be a good fit here. It's allegedly compatible with both Resteasy and Jersey, so that's a plus, it simply adds WebSocket functionality on top of these.
Caveat: I haven't tried this myself, but came across it when looking for the same capability. :-)

Implementing an HTTP proxy to overcome cross-site AJAX requests restrictions (?)

I have a Spring-MVC webapp (3.0.5-RELEASE) which needs to access JSON webservices from another webapp on a different sub-domain (from the client/browser via AJAX).
I've solved this in the past by either:
writing a simple controller that proxies the requests, using Apache Commons HttpClient to handle the requests. Thus overcoming the cross-site/cross-origin request security limitations of most browsers
implementing a JSONP service on the server side (when calling our own JSON services) - not always possible
In the case where JSONP is not possible, is there a better way of doing (1.)?
and/or
Is there a library that will handle this for me? So I don't have to write all the HttpClient code myself - its not a lot of code, but I wonder if I'm (badly) re-inventing the wheel.
I have often had to consume third party web services (API), and as you mentioned, JSONP is not always an option. This is how I go about designing:
If the API is user centric, it has to provide a jsonp interface and that's what I will use. User centric means that you cannot perceive any reason to call the API, do some computations with the response, may be call one of your ajax services and then combine the response and show the user.
If my use case includes calling the API, and then acting on the response, like calling additional services from my application, combining the data and then showing it to the user, I would prefer not doing this in the browser. I would instead use RestTemplate and make backend api calls to the service. In which case there are no cross domain restrictions.
The only case where using a Server Proxy to bypass jsonp is when you are creating a Product that allows people to build custom plugins, plugins which are hosted on your page, but need to make Ajax calls to the app developers servers. This is a very involved case! (As as example look at how Apigee creates Public Facing REST API around your existing urls, or how Zendesk allows you to develop apps)
Hope this helps.

Categories