How to forward request to different route in Spring Webflux? - java

For a Spring Boot application based on ‎Spring WebFlux:
When a request hits a route, I want to forward the request internally at the server side to a new route. Currently I am using redirection.
#GetMapping("/oidc/cb")
public Mono<Void> oidcCB(final ServerWebExchange exchange){
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
response.getHeaders().setLocation(URI.create("/cb?" + exchange.getRequest().getURI().getQuery()));
return response.setComplete();
}
But this will go the browser and the request will come back to the server. Is there a way to internally route this at the server side?

Related

Using Resttemplate as a simple API gateway

I am using Resttemplate to build an simple API gateway in spring-boot project. When my gateway receive a request from client, it dispatch the request to another Service through RESTful call, and then pass the response back to client.
My code snippet like below:
#RestController
#RequestMapping("api/v1/message")
public class GatewayController {
#PostMapping
public ResponseEntity<Response> dispatchRequest(#RequestBody Request request) {
validateInput(request);
Response response = restTemplate.post(URL_OF_ANOTHOER_SERVICE, request, ...);
return ResponseEntity.ok(response);
}
}
I have more than 100 requests per second approximately, and I know that Resttemplate is thread-safe.
My questions:
Is Resttemplate OK to do such work? Will it become bottleneck?
Is there any other suggestions?
Thank you very much.
You can try Spring Cloud Gateway or Spring Cloud Netflix.
You don`t need to build a gateway from scratch unless you want. And even if you want to, you could consider aspects such as security, maturity and maintenance
Some modules of Spring Cloud Netflix
have gone into maintenance mode, therefore, Spring Cloud Gateway might be a good option as GJohannes quoted

How to send Response or status of request using springboot-rest api

I have two rest webservice in my applcation as below(using spring-boot rest api)
1- public void processRequest(Request) - This is asynch webservice to process the request, This will return id of request to client with acknowledgement.
2- public Response getResponse(jobid) - This webservice should return the response of the request generated by ProcessRequest.
here i want to send the status if request is not ready yet.
Is there any way to achieve above requirement?

How to call REST API with Oauth Header in Apache Camel?

I am consuming an API with OAuth1.0 authorization. I want to make call to that API with the authorization Oauth header:-
I have created the authorization header from the token/key received from the server using- (ConsumerKey,keyalias and password) and want to send back the token or the OAuth header with the call.
I have did all these things in a Processor(Class implementing Camel Processor) and now want to do:-
Either call the rest API with this Oauth header(of type String) in the processor itself.
Else send this header in exchange and get this value in camel's to() endpoint and then in it call the REST API.
Thing is i just want to make rest a call in processor with Oauth header.
And then if possible try to access the header in to() endpoint and make the call.
You can set the Authorization header in your processor and then send the REST request with .to()
public void process(Exchange exchange) throws Exception {
String token = //your logic to get the token
exchange.getIn().setHeader("Authorization", "Bearer " + token)
}
.to("your/rest/endpoint")
Camel automatically copies over the message headers onto the outgoing message.

Request Forward to another url in spring boot mvc with mustache template

I am trying to forward the request to another url in spring boot.
I know how to forward the request from one endpoint to another endpoint in the same spring boot application. The code for this is like -
#GetMapping("/home")
public ModelAndView home(#PathVariable(name = "env", required = false) String env) {
return new ModelAndView("index");
}
#GetMapping("/forward")
String callForward(){
return "forward:/home";
}
Here If I go to http://localhost:8080/forward then it will be server by "/home" endpoint and we'll get the home page rendered. Interesting thing here is "url" in the browser remains same http://localhost:8080/forward.
My requirement is > I want to forward to the request to any third party url for example when http://localhost:8080/forward is called I want it to be served by https://google.com/forward.
How can I do it.
I am open to any solution which can fulfill the requirement.
There is a difference between Forward vs Redirect.
Forward: happens on the server-side, servlet container forwards the same request to the target URL, hence client/browser will not notice the difference.
Redirect: In this case, the server responds with 302 along with new URL in location header and then client makes another request to the given URL. Hence, visible in browser
Regarding your concern, it can be achieved using multiple ways.
Using RedirectView
#GetMapping("/redirect")
RedirectView callRedirect(){
return new RedirectView("https://www.google.com/redirect");
}
Using ModelAndView with Prefix
#GetMapping("/redirect")
ModelAndView callRedirectWithPrefix(){
return new ModelAndView("redirect://www.google.com/redirect");
}
Usecase for forwarding could be something like this (i.e. where you want to forward all request from /v1/user to let's /v2/user on the same application)
#GetMapping("/v1/user")
ModelAndView callForward(){
return new ModelAndView("forward:/v2/user");
}
The second approach (using ModelAndView) is preferable as in this case, your controller will have no change where it redirects or forwards or just returning some page.
Note: As mentioned in comments, if you are looking for proxying request, i would suggest checking this SO Thread

Invoking web service from a MultivaluedMap jax-rs

I have a web service that takes a client request and sends it to a second web service. It takes the response of second web service and sends it to the client. Actually it's a gateway. Type of request is "form urlencoded". The gateway takes the request from client as below:
#WebMethod
#POST
#Path("/send")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
String send(MultivaluedMap<String, String> encodedRequest, #Context HttpServletRequest httpServletRequest);
Now I have a MultivaluedMap and I want to invoke the second web service with this MultivaluedMap and without performing any process on it. The second web service consumes "application/x-www-form-urlencoded" too. Is there any way to invoke the second web service without performing any process on this MultivaluedMap?
To send a POST request using JAX-RS Client, you call buildPost(Entity<?> entity), where entity is the POST content.
The Entity has many useful helper methods, e.g. form(MultivaluedMap<String,String> formData):
Create an "application/x-www-form-urlencoded" form entity.
So, you write something like this:
Future<Response> response = client.target("http://example.com/foo")
.request()
.buildPost(Entity.form(encodedRequest))
.submit();

Categories