Making POST request containing a list - java

I've been trying to implement a Scala application which makes POST request to given REST web services. In the request, there is a list of strings. I try to use scalaj but it only allows params as the map from String to String.
So, I wonder if there is anyway to make a POST request containing the list of Strings in Scala, solutions in Java are also welcomed.

After looking and trying around, I finally find the answer which is surprisingly simple. Although scalaj only allows Map from String to String, it also allows list of tuples. By keeping the same first value in the tuples, I can send the list of items.
For example, in order to send the list of numbers whose key is "data", I need to:
Http.post("http://localhost/Dummy").params("data" -> "1", "data" -> "2")

Related

Pass list of objects to GET rest service

I would like to pass a list of objects to a java rest service. For example, list of cycles.
class Cycle {
private String id;
private LocalDate date;
}
#GetMapping("results")
public Result results(List<Cycle> cycles)
Or have a CyclesWrapper class that contains the list. Instead of passing a List cycleDates and a List cycleIds.
How would I pass the parameters to the rest service using say POSTMAN or curl?
So, for passing in a List<String> says cycleIds, the request would be:
http://localhost:8080/application/results?cycleIds=xx,yy
For passing in a Cycle says cycle, the request would be:
http://localhost:8080/application/results?date=2020-10-17&id=xx
Thanks
As it currently stands, your endpoint would interpret cycles as a query parameter, meaning that it would expect the following kind of request:
GET /results?cycles=...
With a list of complex objects, this is not the standard approach. You could possibly pass the objects as /results?cycle1Id=abc&cycle1Date=22-10&cycle2Id=def&cycle2Date=10-10&..., but this would be extremely cumbersome, error-prone, and would require custom mapping on your end to make it work. Additionally, as far as I am aware, there is no standard for sending query array parameters.
Note also, in case you might have misconstrued: you cannot send a request body on a GET request - while the standard does not explicitly disallow this, almost every server's handling of GET does not accept (or just flatly ignores) a request body.
Instead, what you could do, is either:
Change the endpoint to a POST endpoint, passing the list of cycles (i.e. filters) as standard #RequestBody JSON. This would look as follows:
#PostMapping("results")
public Result results(#RequestBody List<Cycle> cycles)
Now your request would expect:
POST /results
{
[
{"abc", "22-10"},
{"def", "10-10"}
]
}
Since POST is allowed to pretty much do anything, it could also return a filtered response on this endpoint. This would however, not be very RESTful.
Change your GET to accept two lists of of simple (i.e. non-nested) objects, e.g. String and LocalDate.
#GetMapping("results")
public Result results(#RequestParam List<String> ids, #RequestParam List<LocalDate> dates)
Which would then expect a request as follows:
GET /results?ids=abc,def&dates=22-10,10-10
as a comma-separated list. This is more in tune with RESTful endpoints, although it's also kind of cumbersome.
In the end, it seems like your endpoint is trying to do two things at once: filter on id and date. Since I am not sure what kind of logical work represents a cycle, perhaps these should be split up into two different endpoints, e.g.:
===>
GET /results?dateFrom=22-10&dateUntil=23-10
<===
[abc, def]
==>
GET /results/abc?dateFrom=22-10&dateUntil=23-10
<==
abc detailed view
Where the /abc represents a singular object. Whether this represents a result or a cycle in your specific case, I cannot say. You'd have to evaluate that for yourself.

Sorting rest get request results by field passed as a parameter

I am currently working on a Rest API, in a get method which suppose to return an Array of objects in json format I now have the requirement to sort the result by a field passed as a parameter to the method. Consider for example the object to be
public class ExampleType {
int firstField ;
String secondField ;
}
Now according to the requirements the Rest API user should be able to pass as a parameter among other things either "firstField" or "secondField" and I should be sorting the array containing the result objects using this field.
Apparently my model is not so simplistic as the example, I do have more than 15 fields which could potentially be the one that I need to sort by, so an else if statement is not a choice at this point. My question is does anybody had a similar requirement for a rest api and if so how did you tackle it ? Or any recommendation on what could potentially by an elegant solution to my problem would be greatly appreciated.
You should create a Comparator and then use this to sort your data.
The comparators could be stored in a static map to avoid a switch/case if/else:
map.put("fieldName", Comparator.comparing(ExampleType::getFirstField));
You can combine two or more comparators using the thenComparing method.
The only other option is to create the appropriate comparators using reflection.
Note: requirements of API consumers often are not requirements that should be implemented in the API itself. You may also consider that sorting output is in fact a display problem and not something that an API needs to be concerned with.
It depends on the situation though, if data needs to be paginated then you may have no option other than to sort at the API level.

In a POST does order of JSON variables matter?

Im writing a program to upload my companies orders to an order review site through a POST request. It takes a JSON Object, and it starts like this
{
"utoken": "XVUYvqaRLPtjfuj1OyNbyqw1cv0R0f76g4PadwmR",
"platform": "general",
However when I create my JSONObject using JSON.simple
JSONObject test = new JSONObject();
test.put("utoken", "awooga");
test.put("platform", "general");
It puts it into alphabetical order when I print it out
{
"platform": "general",
"utoken": "awooga"
Does this matter? I dont think it should, but just want to make certain as I've never ran into this before.
As per JSON standard, official definition of object states:
An object is an unordered set of name/value pairs.
Therefore the order does not matter. Obviously from the perspective of the server receiving the POST request, the order can be parsed from HTTP header and reacted upon. I suppose however this is not of your interest, as it does not make much sense to do so.
See an answer here
TL;DR - order isn't promised to stay the same

Code refactoring for integration four projects to one project

I am starting code refactoring for integrating four small projects to one project,the four projects is very similar.
the general logic of the project is as this:a http-server to receive the request,the request is as a json format,for example A(we call A has two objects: a_key, b_key):
{a_key : a_value, b_key : {bb_key: {b_key1 : b_value1}}}
but the four types of request is not the same, there is a little different between them. for example: the second project receive request as this B(we call B has three objects: a_key, c_key, d_key):
{a_key : a_value, c_key : {cc_key: {c_key1 : c_value1}},d_key: [dd1, dd2, dd3]}
just as the above, all the requests is in JSON format, the different is "some key" may have a different name(eg: bb_key, cc_key), and the parameter count may be different(eg: B has dd_key parameter).I can't be sure the concrete parameter's names and counts.
Also, all the responses are in JSON format, but as requests, a little different between them. The process is similar, according to the parameter, after some filters, the response is returned.
I think the difficult of refactoring of this is a general of Request and Response, now in our four projects, most of the code is similar, but a little different for Request and Response, our code use Java, we use Jackson to translate every request, we define a concrete class for every object in the request(eg: a_key, b_key, c_key, d_key). I don't want define so many objects class for the 4 type requests, since there is only one or two parameter different. now I have no idea to general this Request, any guy has ideas? thank you!
In generic class, convert your json parameters into HashMap. Implement Factory Design pattern such that Factory class will return appropriate filter based on whether required key is present in HashMap or not. Use the returned filter to process your result and return JSON response.

2D Array that can hold multiple values with no limits

I am quite new to java currently working on a not-so-simple web browser application in which I would like to record a permanent history file with a 2D array setup with 3 columns containing "Date Viewed", "URL", "How many times this URL has been viewed before".
Currently I have a temporary solution that only saves "URL" which is also used for "Back, Foward" features using an ArrayList.
private List tempHistory = new ArrayList();
I am reading through the Java documentation but I cannot put together a solution, unless I am missing the obvious there is no 2D array as flexible a ArrayList like in Python?
From your description it doesn't sound like you need a 2D array. You just have one dimension -- but of complex data types, right?
So define a HistoryItem class or something with a Date property for date viewed, URL for URL, int for view count.
Then you just want a List<HistoryItem> history = new ArrayList<HistoryItem>().
The reason I don't think you really want a 2D array-like thing is that it could only hold one data type, and you clearly have several data types at work here, like a date and a count. But if you really want a table-like abstraction, try Guava's Table.
No, there is no built-in 2D array type in Java (unless you use primitive arrays).
You could just use a list of lists (List<List>) - however, I think it is almost always better to use a custom type that you put into the list. In your case, you'd create a class HistoryEntry (with fields for "Date viewed", URL etc.), and use List<HistoryEntry>. That way, you get all the benefits a proper type gives you (typechecking, completion in an IDE, ability to put methods into the class etc.).
How do you plan to browse the history then? If you want to search the history for each url later on then ArrayList approach might not be efficient.
I would rather prefer a Map with URL as key.
Map<Url,UrlHistory> browseHistory = new HahMap<Url,UrlHistory> ();
UrlHistory will contains all the fields you want to associate with a url like no. of times page was accessed and all.

Categories

Resources