How to internally call another restapi endpoint in quarkus controller class? - java

I need to call another rest api endpoint inside the controller class to provide filtered user list as a result. I can't find a way to call one rest api from another rest api.Controller class
This is my controller class method code:
#GET
#Path("/filter")
#Produces(MediaType.APPLICATION_JSON)
public Response filterByName(#QueryParam("page") int page, #QueryParam("first_name") String first_name,
#QueryParam("last_name") String last_name) {
try{
String uri = "https://reqres.in/api/users?page="+page;
//Flux<User1> users = restTemplate.getForObject(uri, User1.class);
Mono<List<User1>> result = users.filter(user-> user.getFirst_name().equals(first_name) && user.getLast_name().equals(last_name)).collectList();
return Response.ok(result).build();
}catch(Exception e) {
e.printStackTrace();
return Response.status(204).build();
}
}
My issue got resolved, I used microprofile rest client to create a proxy and called the endpoint from there. Thanks!

Take a look at the HttpClient class in java.
https://docs.oracle.com/en/java/javase/12/docs/api/java.net.http/java/net/http/HttpClient.html

Related

Forcing Twilio Voice Callback to JSON to facilitate deserialization in Spring

I'm using the Java SDK to start a voice call using something similar to
Call.creator(to, from, callbackAddress)
I provide a URL (callbackAddress) that will receive the callback once the call is connected. Is there some way to configure this callback to be in JSON instead of "application/x-www-form-urlencoded; charset=UTF-8"?
The reason why I'm trying to do that is because I'm using Spring and ultimately I'm trying to receive the request parameters already in a deserialized Pojo in my RestController (parameter body in my example below), which is standard in SpringMVC. This is much easier to do using jackson, which requires a JSON request body
As a secondary question, is there a class in the Twilio SDK that encapsulates all the parameters in a request already or I would have to create such class?
Here is a dummy rest controller to illustrate what I'm trying to do. Note that the logic there with the "out of city" error is just a silly demo to show why I need to access the request parameters. All the samples I found about callbacks always ignored the request parameters and returned a static TwiML
#RestController
#RequestMapping(value = "/twilio", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class TwilioCallbackController {
#PostMapping
public String handleCallback(RequestBody body /*this arg should have all request params*/) {
log.info("received callback for callId {}", body.getCallSid())
if (!body.toCity().equals("my-city")) {
throw new Exception("outside of city");
}
return createTwiML(body);
}
}
Twilio developer evangelist here.
There is no way to have Twilio send you the webhook in JSON format, it will be sent as form encoded parameters. However, there shouldn't be an issue having Spring parse them.
As this answer suggests, you can create a class that will parse the parameters into it by creating a class with getters and setters for each of the parameters.
So, for example, you could create the following class:
public class TwilioWebhook {
private String CallSid;
private String From;
public String getCallSid() {
return CallSid;
}
public void setText(String CallSid) {
this.CallSid = CallSid;
}
}
Which you could then use to parse the CallSid from the incoming webhook parameters like:
#RestController
#RequestMapping(value = "/twilio", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public class TwilioCallbackController {
#PostMapping
public String handleCallback(TwilioWebhook request) {
log.info("received callback for callId {}", request.getCallSid())
// rest of the controller.
}
}
You can parse all the parameters by adding to the TwilioWebhook class. You can see all the parameters that Twilio will send in the Twilio voice request documentation. There isn't a class in the Twilio SDK that does this for you though.

Spring restful API, is there a method being used like router to get other method's end points or URL?

#RequestMapping("/accounts")
public class controller {
#GetMapping("/get/{id}")
public final ResponseEntity<?> getHandler(){
}
#PostMapping(value = "/create")
public final ResponseEntity<?> createHandler(){
/*
trying to use some spring library methods to get the url string of
'/accounts/get/{id}' instead of manually hard coding it
*/
}
}
This is the mock code, now I am in createHandler, after finishing creating something, then I want to return a header including an URL string, but I don't want to manually concat this URL string ('/accounts/get/{id}') which is the end point of method getHandler(), so I am wondering if there is a method to use to achieve that? I know request.getRequestURI(), but that is only for the URI in the current context.
More explanation: if there is some library or framework with the implementation of route:
Routes.Accounts.get(1234)
which return the URL for the accounts get
/api/accounts/1234
The idea is, that you don't need to specify get or create (verbs are a big no-no in REST).
Imagine this:
#RequestMapping("/accounts")
public class controller {
#GetMapping("/{id}")
public final ResponseEntity<?> getHandler(#PathVariable("id") String id) {
//just to illustrate
return complicatedHandlerCalculation(id).asResponse();
}
#PostMapping
public final ResponseEntity<?> createHandler() {
//return a 204 Response, containing the URI from getHandler, with {id} resolved to the id from your database (or wherever).
}
}
This would be accessible like HTTP-GET: /api/accounts/1 and HTTP-POST: /api/accounts, the latter would return an URI for /api/accounts/2 (what can be gotten with HTTP-GET or updated/modified with HTTP-PUT)
To resolve this URI, you could use reflection and evaluate the annotations on the corresponding class/methods like Jersey does.
A Spring equivalent could be:
// Controller requestMapping
String controllerMapping = this.getClass().getAnnotation(RequestMapping.class).value()[0];
and
//Method requestMapping
String methodMapping = new Object(){}.getClass().getEnclosingMethod().getAnnotation(GetMapping.class).value()[0];
taken from How do i get the requestmapping value in the controller?

Finding a method exists in rest service or not in Java

Hi i am new to Rest Service in Java. First i want to explain my problem and then at the end i will be asking question.
I am using Mozilla rest CLIENT. My rest class looks like:
#Path("/api1")
public class RestService {
#POST
#Path("/v1")
#Consumes("application/json")
#Produces("application/json")
public String v1(String json){
//Some code here
}
#POST
#Path("/v2")
#Consumes("application/json")
#Produces("application/json")
public String v2(String json){
//Some code here
}
}
Now in this code i have two functions.
To access v1, call will be:
http://localhost:8080/project_name/package/api1/v1
To access v2 call will be:
http://localhost:8080/project_name/package/api1/v2
Question:
Now in my rest service class i want to add a patch of code which detects that whether any function which has been called either v1,v2 or v3 exists in this service or not?
Can i do this? Or anyother way to do this?
Thanks
Well, you could add a wildcard response:
#POST
#Path("/{what}")
#Consumes("application/json")
#Produces("application/json")
public String v2(String json, #PathParameter("what") String what){
return "The path "+what+" does not exist.";
}
However, since the user will never see the direct responses, you can answer with a customized 404:
#POST
#Path("/{what}")
#Consumes("application/json")
#Produces("application/json")
public Response v2(String json, #PathParameter("what") String what){
return Response.status(Status.NOT_FOUND).entity("The path "+what+" does not exist.");
}
This way you can also detect on the client side when something is incorrect.
The best approach for you is to add a fallback response. That will be called when somebody tries to access any non existing WS method.
#RequestMapping(value = {"*"})
public String getFallback()
{
return "This is a fallback response!";
}

How to get xml produced from jax-rs?

I would like to log the xml produced from this. How can I do this ?
#GET
#Path("add")
#Producse("application/xml")
public List<String>getCustomerList(....) {
}
}
UPDATE
why i need this is because , I want to have database logging with the request and response header, body etc
Not sure what you mean by log -- do you mean display on a web page?
So assuming the CustomerList is annotated and the Customer class is also annotated and each has getters and setters.
#GET
#Path("add")
#Produces(MediaType.APPLICATION_XML)
public Response returnListOfCustomers() {
CustomerList returnMe = this.getMyCustomerList(); // <-- Made this method up
return Response.ok(returnMe).build()
}
This is assuming you are trying to create a Restful service: JAX-RS.

How to detect if a call to a REST server in java was from a mobile device?

I have developed a REST based server in java for Android devices and Desktop Devices and now I want to make a difference between those two entities.
I want to know when an Android device is accessing the methods(Create/Read/Update/Delete) and when Desktop Web App.
Here is a snapshot of my code:
#Path("/v2")
public class RESTfulGeneric {
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("/get")
public Response Get() {
ResponseBuilder builder = Response.status(Response.Status.OK);
....
return builder.build();
}
#POST
#Consumes({MediaType.APPLICATION_JSON })
#Path("/create/{Name}")
public Response Post(String Table, #PathParam("Name") String Name) {
ResponseBuilder builder = Response.status(Response.Status.OK);
..........
return builder.build();
}
}
How can I know, or what should verify in order to know that an Android device is calling those methods?
I know that there is this request.getHeader("User-Agent") that could help me, but this request is availabe only in Servlets.
Any idea?
You can grab the user-agent header from the request by adding a parameter to your request handling methods i.e.
public Response Post(String Table, #PathParam("Name") String Name, #HeaderParam("user-agent") String userAgent) {
if (userAgent.contains("Android")) {
// mobile specific logic
}
}
Here's a useful list of Android user-agents...
http://www.gtrifonov.com/2011/04/15/google-android-user-agent-strings-2/
In case of using spring mvc you can use #RequestHeader annotation

Categories