Spring MVC handle multiple REST commands in a single HTTP request - java

I want to be able to generically handle a mass of commands as a single POST request represented as a map of URL => Body, that processes each command via its matching RequestMapping and returns a map of URL => Response.
Request:
{
"/api/things/34?huh=wat": {
"method": "GET"
},
"/api/dogs": {
"method": "POST",
"body": /* some dog-esque json */
}
}
Response:
{
"/api/things/34?huh=wat": {
"response": /* thing-esque json */
},
"/api/dogs": {
"response": /* some error json */
}
}
I am not concerned too much with the shape of the request/response objects, I just don't know how to handle this in Spring.

It sounds like the client should be splitting the individual requests up and sending them one at at a time. Think about it this way, what happens if the POST succeeds but the GET returns a 500 server error? Do you take the status of the whole request to be 500? And what about the POST, does it now need to be rolled back?

Related

Mock/not-mock response on a per request basis in Integration test

I am writing Integration tests. I have a need where for a positive test case request hit an actual service and recieve the response. But for a negative test case I must get the mocked response.
I am curious to understand if there is a way that I can mock/not-mock the request on a per configuration basis. Like for example if request accepts email address in request and I provide
"invalid#email.com" - response from mockoon must be a mocked response.
"valid#email.com" - mocking must not happen but rather it must hit the actual server to get the response. may be via redirecting or calling the actual service and responding the response to the caller.
I have tried Mockoon but feature is not yet present. So trying to help from the community :)
Regards,
You can use separate stub/mappings that match on different emails.
Assuming that your url is some-Url and uses a queryParameter of email...
{
"request": {
"url": "/some-Url",
"queryParameters": {
"email": {
"equalTo": "invalid#email.com"
}
}
},
"response": {
"status": 200
}
}
{
"request": {
"url": "/some-Url",
"queryParameters": {
"email": {
"equalTo": "valid#email.com"
}
}
},
"response": {
"proxyBaseUrl": "http://my-other-url.com"
}
}
This is possible with mockswitch - it supports various request / response pairs kinda like a switch case. You can define different cases and do request matching based on for each. If one the case matches it breaks the response flow and responds. Also easy to proxy requests to actual service based on certain case.
Their docs is available here https://mockswitch.com/docs/#switch-case-responses

Using Spring MVC and Kotlin, why does this Body is ignored?

I would like to know why this code runs but doesn't filter the data as it should.
The same request in postman works but in Kotlin it doesn't what is happening?
The goal is to filter the data by timestamp value.
val getFiltered = restTemplate.exchange(
"https://X.X.X.X:6200/ble_flow-$da/_search/?size=50&pretty=1",
HttpMethod.GET, HttpEntity("{\\r\\n\\\"query\\\": { \\r\\n \\\"bool\\\": { \\r\\n \\\"filter\\\": [ \\r\\n { \\\"range\\\": { \\\"timestamp\\\": { \\\"gte\\\": \\\"2019-08-12T06:00:00\\\",\\\"lt\\\":\\\"2019-08-12T011:00:00\\\"}}} \\r\\n ]\\r\\n }\\r\\n }\\r\\n}", headers),
ResultsFlow::class.java)
println(getFiltered)
It would solve the problem if I could transform the body:
{
"query": {
"bool": {
"filter": [
{ "range": { "timestamp": { "gte": "2019-08-12T06:00:00","lt":"2019-08-12T07:00:00"}}}
]
}
}
}
into url query. But I don' really know how to do this.
Thanks.
The Spring RestTemplate does not send your Body in a GET request, as a GET request should not contain a body but use query parameters instead. Read more on it here HTTP GET with request body
Therefore the Elasticsearch API allows also POST to send a query with a body. I would recommend this as your first solution:
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html
Both HTTP GET and HTTP POST can be used to execute search with body. Since not all clients support GET with body, POST is allowed as well.
If you really want to use a GET request from Spring RestTemplate to transfer a body you need to replace and extend the RequestFactory. You can find an example for exactly your case in this blog post.

REST api for field validation

I have to create a couple of web services for validating possible values of given fields. I'm contemplating having something like:
POST /entity/fieldName body { fieldValues }
where the POST will return 400 (Bad request) if the arguments are invalid and 422 (Unprocessable entity) otherwise. However I do not really like the 422 response part very much since it makes the request always return an error. On the other hand since I'm only doing validation and this is a POST I don't want to actually create a new resource on the server (i.e. return 200). Is there another HTTP method / API endpoint that is better suit for this? For what it's worth I will be checking that the entity field with <fieldName> has its value in a given range.
If all you do is validating, then I think you should send 422 by validation error and 200 by validation success. The POST does not mean you have to always create a new entity.
The action performed by the POST method might not result in a
resource that can be identified by a URI. In this case, either 200
(OK) or 204 (No Content) is the appropriate response status, depending
on whether or not the response includes an entity that describes the
result.
If a resource has been created on the origin server, the response
SHOULD be 201 (Created) and contain an entity which describes the
status of the request and refers to the new resource, and a Location
header (see section 14.30).
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
I'm prefer google's api error response style.
So my service sends error response as json or xml and 400 Bad request error code:
{
"status": "INVALID_REQUEST",
"type": "ERROR_MSG",
"data": {
"request": "/v2/data?age=23d",
"errors": [
"age: not a number"
]
},
"time": -1
}
otherwise 200 and corresponding message

How to get JSON data from POST request using Servlet

This is my code on the client side:
$.ajax({
type:'POST',
charset:'utf-8',
url:'http://localhost:8180/GisProject/MainService',
data:JSON.stringify(params),
success:function(msg)
{
console.log(msg);
},
error:function(xhr,status)
{
console.log(status);
},
contentType:"application/json"
});
I have previously parsed this data in Node using express.bodyParser but now I have to parse it using the servlet.I have seen people assign variables here without using JSON.stringify and getting that variable using request.getParameter(myData).
What is the standard way of getting the JSON data into the servlet?
And why do people seem to be sending Javascript objects with JSON embedded as a String within like data:{mydata:JSON.stringify(actualData)}?
In case I was not being clear,I want to use the doPost method's request object to get the data I sent from the client side.
On the server side in a servlet you can read POST data payload from request.getReader()
And you can use JSON library like GSON to parse JSON. Something like:
YourClass obj = new Gson().fromJson(request.getReader(), YourClass.class)
Try this:
$.ajax({
type:"POST",
url:'http://localhost:8180/GisProject/MainService',
data:{mydata:JSON.stringify(params)},
datatype:"json",
success:function(msg)
{
console.log(msg);
},
error:function(xhr,status)
{
console.log(status);
},
});
you can send request and response object to doGet method and than get the json in the same way.
Way to send object to doGet
doGet(request, response); call it in to the post method.
Hope this should help for you:
var obj = jQuery.parseJSON( '{ "name": "John" }' );
alert( obj.name === "John" );

Rest API method is returning value but still receive 500 error

I'm working on a Java Jersey REST API and a website using this API.
This is my server side method
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<TreeViewModel> getTreeList() {
User user = User.getByCredentials("team", "team");
List<TreeViewModel> list = user.getTreeViewModels();
return list;
}
And this is my javascript request
function requestTrees() {
$.ajax({
type: "GET",
url: window.api + "tree",
dataType: 'json',
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", make_base_auth('team', 'team'));
},
success: function(data) {
console.log('suc');
},
complete: function(jqxhr, txt_status) {
console.log('com');
},
failed: function(data) {
console.log('fai');
}
});
}
If I debug my server the method gets called and returns the list. But at client side I receive a 500 error which indicates something is wrong at server side?
Any suggestions?
Thanks in advance.
500 means internal server error, and should usually be accompanied by log messages or even in some cases an exception embedded in the message body sent to the client.
What has most likely happened is that your method has processed and returned the List<TreeViewModel> but that could not then be serialized for sending.
For example some serializers do not like working with raw collections. You need to have your own object and then put the list within that. The only way to find the actual cause of the problem though is to find that exception and see what it is telling you.

Categories