configuration based API request response mapping in java - java

I have requirement where i want to integrate different Service providers REST APIs and switch to one of them based on request parameter.
Example if request parameter has type ="A" than I will be redirecting request to Service Provider A , get data ,map it and then respond back to client.
If type = "B" I will be redirecting request to Service Provider B and same applies for C...Z Types
Here One solution i can think of is having factory Pattern and get Client based on the type. and for Request/Response mapping i have to maintain Mapper classes for each Service Provider.
Is there any framework in java where i can make this configuration based, like all Request/Response mapping will be maintained in either xml/json file and the framework will take care of everything else.
And this can be plug and play kind where in future if new Service Provider is integrated than no code changes are required and the new Service Provider can be integrated by adding Request/Response mapping file directly.

Related

Is it possible to discover endpoint parameters in a Spring Boot application?

I have a Spring Boot application exposing some endpoints for REST requests. I am trying to decouple two components (which currently call each other's code directly), and I want them to make REST requests to each other (for an eventual microservice implementation). I know endpoint discovery can be done through a discovery service (e.g. Eureka), but is there a way to also communicate parameter information from the service which requires it to the client requesting it?
Example: I have a shopping cart service which relies on information about products available for purchase. Using Eureka (or another service discovery tool) I can register my services so that the shopping cart service is now aware of the product service. If the product service has something like:
#GetMapping("/product")
public Product findById(#RequestParam int id) {
return products.find(id);
}
I know to use this endpoint to get product with ID 3 the cart service would have to make a request to http://localhost:1234/product?id=3, but is there a way that it can discover these parameters and their required types at run time? In my example, if I use Eureka, the shopping cart service is dynamically made aware of the product service's location, but is not made aware of the parameters that its endpoints will accept. I know Spring Boot Actuator is supposed to provide this information, but whenever I use it, the params field for my endpoints is always empty.
Is there a way that it can discover these parameters and their required types at run time?
Do you really need this information at runtime?
Because it would be much simpler if you need this at development time. Then you could just use something like Swagger, which will provide a service specification endpoint. It can even generate a client for your service.
But, if you really want it at runtime, you may be better served with a HATEOAS API. HATEOAS (Hypermedia as the Engine of Application State) means that your API is navigable. That means that clients can "crawl" you API following the links presented, like a human navigating through a website. How useful it will be, depend on what you are trying to achieve.
There are two popular "solutions" to this:
HAL (Hypertext Application Language) - Still an Internet Draft
JSON-LD (JSON for Linking Data) - A W3C Standard
Spring Boot has HAL support, see spring-boot-starter-hateoas.
You can use parameter map, that will be dynamically populated with all used parameters:
#GetMapping("/product")
public Product findById(#RequestParam Map<String,String> allRequestParams) {
return products.find(allRequestParams.get("id"));
}
You can iterate the parameter map to find which parameters are present.
You can use Swagger in your product service to generate apis, exposed in a json file. For example you can look at sample project petstore with its json exposed, containing apis and parameters with definition.
Then in your shopping cart service you can navigate at runtime product service apis, iterating for specific api parameters.

Forward http requests based on data from the request body

I have a service with many controller methods. My task is to "split" this service into microservices.
The microservices themselves will be deployed on other machines. Nginx redirect by location.
The main problem is that there is one location, http://mydomain/myservice/srv/data that receives different types of requests.
And the logic after is called based on the value in the a field in the request body.
For example, two requests:
<request type="getname" val="1"/>
<request type="balance" val="1"/>
The first request must be forwarded on http://mydomain/myservice1/data/name and the second on http://mydomain/myservice2/data/balance
Question: Are there any libraries for such purposes?
UPD: I am writing simple jar based on RouteLocator (spring cloud); is there perhaps another way of doing this? Spring cloud not is the stack we're familiar with.
You may have a look to spring integration, it implements most of the enterprise integration patterns, including content based routing
I think the approach of proxying the request based on different request types in the body is not a good way to proxy. The URI ultimately should be responsible for what kind of request it is serving and response it should be responding to.
The client has all the necessary information on the request type and therefore where to send the request. From that fact, I would refactor the resource that you have to different resources that handles the different request types and determine an explicit schema for the payloads for each one.
To summarize, the implementation would look like the following:
Refactor server logic for different types of requests to their own resource URIs
Move the logic of where to send the request into the client, perhaps utilizing something like a factory pattern

Spring boot Rest API internationlization based on request parameter

We have a spring boot REST application with APIs having both GET and POST methods.We have few response messages that need to internationalized based on a parameter "locale" for both GET and POST.In case of GET,locale will be passed as query parameter(eg:http://sampleapp/search?locale=en) and for POST method,locale will be part of request JSON. It would be great if I could get some reference implementation for this scenario.
At first I think you do not need to have locale path param. Instead of you can use the standard Accept-Language HTTP header property. You can read about this header here.
This is the way how you can read the accept-language information from the HTTP request in your rest method:
#RequestMapping(produces = "application/json", method = RequestMethod.GET)
public ResponseEntity<Data> getData(#RequestHeader(value="Accept-Language") String acceptLanguage)
{
//your code goes here
}
Once you get the accepted language info from your client' then you can read language deppendent values from a property file with Java I18N. The following article explain you the way how to do it: https://www.google.hu/amp/s/www.journaldev.com/1370/java-i18n-internationalization-in-java/amp
Finnaly if the language info is not provided by client you can use english language as a default.
Hope that it will help you.
The standard way of detecting user locale in web applications which can be reused in REST services is accept-language header. Browsers send this header with every request automatically. When it comes to detecting user locale in Spring MVC applications Spring provides us with a variety of *LocaleResolver classes that do the job for us. Please refer this article for simple example.
Provided that you are using Spring REST extension to Spring MVC then it is no different here. Everything that is available for MVC can be used in #RestController ones. So you clients may set the accept-language on their requests and automatic detection will work the same way as in web application.
If you have a requirement implement a solution with locale as a POST/GET parameter then you should have a look at LocaleContextHolder. Spring associates a locale information with the current Thread and this is a way to directly access and modify it. When you set the locale using LocaleContextHolder later you can use it in your app components reading form the context as well as Spring standard components will be aware of another locale set.

Jersey: Display possible actions on a resource

I am using the Jersey implementation of JAX-RS spec to develop RESTful web services. There is a url that can uniquely identify a resource. Is there a way to let know the user of the RESTful services, the possible actions that can be performed on the resource? For example,
Resource name - host1
http://localhost:8080/state-fetcher/rest/object/host1/actions
This should give me all the possible actions that can be performed on the resource - {actions: [GET, POST, DELETE]}
Thanks!
Use the OPTIONS HTTP method on the resource. You will get the allowed methods in Allow header, for example: Allow: GET, HEAD, PUT and in a payload you will find the fragment of wadl associeted with the specified resource.
A RESTful service itself is inteded to be self- descriptive! If the user performs a request, the REST service should send back a list of possible links, which can be performed next, along with the response. That's the motivation and general concept of a RESTful serivice. If you provide a graphical WebClient, you just need to provide the initial link (e.g. http:\example.com\restful), and the response sends back a list of valid links which just needs to be visualized within the GUI. Usually the webservice only provides those links which are accessible in terms of the users role. (This is not a security feature!!! It just prevents that unecessary links are displayed) Otherwise the OPTION method of the HTTP protocol provides information concerning the supported protocol methods.

HttpServletRequestWrapper and Filter lifecycle in tomcat

I am coding a Tomcat application and am authenticating against Google's oauth2 services. I was originally going to write a simple Filter to do the authentication but there is no way to set the user principal in a Filter. From my understanding you have to have the Filter call an implemented HttpServletRequestWrapper and set it inside of that class as seen in this post
I'm pretty sure Tomcat only instantiates one Filter of each type you may have defined and all requests go through this single object down the Filter chain (correct me if I'm wrong).
In the linked to code, is it correct for the code to call
next.doFilter(new UserRoleRequestWrapper(user, roles, request), response);
where every request is instantiating a new UserRoleRequestWrapper? Should this Filter instead have one request wrapper instatiated that gets shared amonsgst all requests? I'm having a hard time finding documentation on the specs of classes such as these.
I don't think that a Filter is what you're looking for. Doesn't seem right for this purpose... Filters weren't created for such use cases; they were created for pre/post processing requests and responses, with emphasis on manipulating the actual request/response data, rather than other aspects of the client-server communication (such as security). Remember, authenticating a user may have further repercussions than just handling HTTP request cycles. Security ties into the JavaEE framework in a lower level than HTTP cycles.
If you want to authenticate against oauth2, you should be far better off implementing some sort of a JAAS implementation for it, and plug it into Tomcat.

Categories

Resources