Debugging RestEasy RestClient - resteasy

I am using the framework in quarkus to build a rest client for the mandrill API
#RegisterRestClient
#Path("1.0")
#Produces("application/json")
#Consumes("application/json")
public interface MailService {
#POST
#Path("/messages/send-template.json")
JsonObject ping(JsonObject mandrillInput);
}
This is the relevant portion of my application.properties
com.example.service.MailService/mp-rest/url=https:/mandrillapp.com/api
And my example resource
#Path("/hello")
public class ExampleResource {
#Inject
#RestClient
MailService mailService;
#Produces(MediaType.TEXT_PLAIN)
#GET
public String hello() {
System.out.print("In the API");
JsonObject key = Json.createObjectBuilder().add("key", "ABCD").build();
System.out.println("The json built is "+key);
JsonObject response = mailService.ping(key);
System.out.println("The response is " + response);
return "hello";
}
}
What I saw is that if the API I am calling (Mandrill in this case) returns an error response (If my key is wrong for example), then the variable I am using to store the response doesnt get the response. Instead the REST API I am exposing to my application wrapping around this, gets populated with the response from Mandrill.
Is this expected behaviour? How can I debug the output of a rest client implementation in Quarkus?
The REST API being called is https://mandrillapp.com/api/docs/users.JSON.html#method=ping2

If you want to be able to get the body of the response when an error occurs, I suggest you use javax.ws.rs.core.Response as the response type.
You could also go another route and handle exceptions using ExceptionMapper

Related

Optional response body for rest client using RESTEasy

I'm writing a POC for Quarkus. I'm using this quick start guide to build a REST client. The REST service I'll be integrating with is third party. Here is a simple example of my current implementation:
#Path("/v1")
#RegisterRestClient
public class EmployeeApi {
#POST
#Path("/employees")
ApiResponse createEmployee(#RequestBody Employee employee)
}
This works fine. The issue I'm having is that the third party API will, depending on success / failure, return a response body. In the scenario it does fail, it provides details in the response body (ApiResponse) on why it was unsuccessful. When it succeeds, it returns nothing. This causes Quarkus to throw the following exception:
javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type application/octet-stream and type com.test.app.ApiResponse
I've tried to wrap ApiResponse in an Optional type but does not solve the problem. I see absolutely nothing in Quarkus / RESTEasy documentation that would indicate a work-around.
I'm wondering if I should be using javax.ws.rs.core.Response instead.
The problem is JaxRS tries to fit ApiResponse to a default return type being application/octet-stream
You should make sure to specify explicitly that you're returning application/json
This is possible using #Produces(APPLICATION_JSON) on top of your service.
Here is the correct code snippet
#Path("/v1")
#RegisterRestClient
public class EmployeeApi {
#POST
#Path("/employees")
#Produces(APPLICATION_JSON)
ApiResponse createEmployee(#RequestBody Employee employee)
}

How to send image from React app to api server

I need help with implementation send image from React app to server api.
In React I use library FilePond for send image, and that work great, but I dont know how to get this image on server, I use NETTE framework and also apitte library for request. If you know how to send and get images another way, write please. Thank you very much!
For example how I use FilePond in react
<FilePond allowMultiple={true} server={"http://localhost:3000" + this.baseProperties.uploadUrl}/>
and part of php code
/**
* #Path("/upload")
* #Method("POST")
* #param ApiRequest $request
* #return string
*/
public function uploadImage(ApiRequest $request)
{
return 'check';
}
It is not very clearly document but file pond will hit whatever API you specified (http://localhost:3000 in your case) simply using the HTTP verb that corresponds to the REST action being taken. so for example if you set this. (note this in react)
server={
{
'url': 'localhost:3000/filepondBackend',
Then file pond would hit the localhost:3000/filepondBackend endpoint with the follow HTTP verbs: POST, GET, DELETE
Here's an example of how the backend would be mapped in spring
#RequestMapping("/filepondBackend")
#DeleteMapping(produces = "application/json")
#ApiOperation(value = "Deletes file from DataBase")
public ResponseEntity<ResponseDTO> deleteFile(
#RequestHeader HttpHeaders headers
{
delete logic
});
#PostMapping(produces = "application/json")
#ApiOperation(value = "Inserts file into DataBase")
public ResponseEntity<ResponseDTO> postFile(
#RequestHeader HttpHeaders headers, #RequestParam("filepond") MultipartFile file
{
post logic
});
#GetMapping(produces = "application/json")
#ApiOperation(value = "Retrieve file from DataBase")
public ResponseEntity<ResponseDTO> getFile(
#RequestHeader HttpHeaders headers
)
{
get logic
});
Hope that helps.

Wildcards in camel route

I have rest controller with request mapping as follows:
#PostMapping(value = "fpl/generate/{legIdentifier:.+}"
My camel route is defined as from("direct:/fpl/generate/").
The controller calls web service, web service calls FluentEndpointInvoker class which calls route defined above.
public class FluentEndpointInvoker {
#EndpointInject(uri = BASE_ENDPOINT_URI)
private FluentProducerTemplate producer;
#Value("${server.servlet.context-path}")
private String contextRoot;
public <T, R> T request(Class<T> type, R request, HttpHeaders headers) {
return producer.withProcessor(exchange -> {
exchange.getIn().setBody(request, request.getClass());
headers.forEach((key, value) -> exchange.getIn().setHeader(key, value));
String endpoint = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()
.getRequestURI();
exchange.getIn().setHeader(ROUTE_ENDPOINT_HEADER, "direct:".concat(endpoint.replaceFirst(contextRoot, "")));
}).request(type);
}
}
The endpoint that is generated is something like direct:///fpl/generate/LH.1234.30Jun2016.FRA.BOG.X1. How can I configured wildcards in camel route so that endpoint can get called
Well, if you are not forced to use an endpoint with the full URI, you could simplify the case.
Instead of creating a dynamic endpoint, you could send all messages to the endpoint direct:///fpl/generate and set the full request URI as header on the message.
That way you have a simple route endpoint to use and the URI header to make decisions etc based on the full URI.

400 Bad Request with a $http.post that does not contains a body

I have an angular js application, and when trying to issue the following post request :
$resource('api/'+API_VERSION+'/projects/:projectId/users/:userId')
.save(
{
projectId:$scope.project.id,
userId:id
},
{}
,function(){
// Handle callback
});
I get a 400 bad request error.
the request is handled by a spring RestController and the method looks like the following :
#RequestMapping(value = "/projects/{projectId}/users/{userID}",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
#RolesAllowed(AuthoritiesConstants.USER)
void addUsers(#PathVariable Long projectId, #PathVariable Long userId) {
log.debug("REST request to add admin to project");
projectService.addUser(projectId, userId);
}
I Checked the request that is been sent to the server, and nothing bad strikes me.
The url is correct (all parameter are of valid type), and the content type is set to Application json.
Thanks in advance for any help.
Your API consumes JSON and returns void, so I think you should have consumes = MediaType.APPLICAT_JSON_VALUE in your #RequestMapping.
[Edit]:
Apart from the consumes annotation everything is fine with your back-end. Can you try making your post request with the following code :
$resource('api/'+API_VERSION+'/projects/:projectId/users/:userId',
{projectId: $scope.project.id, userId: id}).$save();
or again, creating an instance of the resource :
var Project = $resource('api/'+API_VERSION+'/projects/:projectId/users/:userId',
{projectId: $scope.project.id, userId: id});
var newProject = new Project();
newProject.$save();
And let me know if it worked ?

RPC call to external server

I am a new bie on GWT, I wrote an application on abc.com, I have another application i.e. xyz.com, xyz.com?id=1 provides me a data in json format, I was thinking to find a way that how to get that json file in abc.com via RPC call, because I have seen tutorials in which RPC calls are used to get data from its server. any help will be appreciated.
EDIT
I am trying to implement this in this StockWatcher tutorial
I changed my code slightly change to this
private static final String JSON_URL = "http://localhost/stockPrices.php?q=";
AND
private void refreshWatchList() {
if (stocks.size() == 0) {
return;
}
String url = JSON_URL;
// Append watch list stock symbols to query URL.
Iterator iter = stocks.iterator();
while (iter.hasNext()) {
url += iter.next();
if (iter.hasNext()) {
url += "+";
}
}
url = URL.encode(url);
MyJSONUtility.makeJSONRequest(url, new JSONHandler() {
#Override
public void handleJSON(JavaScriptObject obj) {
if (obj == null) {
displayError("Couldn't retrieve JSON");
return;
}
updateTable(asArrayOfStockData(obj));
}
});
}
before when I was requesting my url via RequestBuilder it was giving me an exception Couldn't retrieve JSON but now JSON is fetched and status code is 200 as I saw that in firebug but it is not updating on table. Kindly help me regarding this.
First, you need to understand the Same Origin Policy which explains how browsers implement a security model where JavaScript code running on a web page may not interact with any resource not originating from the same web site.
While GWT's HTTP client and RPC call can only fetch data from the same site where your application was loaded, you can get data from another server if it returns json in the right format. You must be interacting with a JSON service that can invoke user defined callback functions with the JSON data as argument.
Second, see How to Fetch JSON DATA

Resources