How to Set Up a RESTful API with Spring - java

I am trying to set up a RESTful API with Spring, using react for the front-end. The client is meant to send a POST request that looks something like this:
{
"previousDecisions": [0, 1, 2]
}
Then the server will respond with an Object called Node which looks like this after being converted to JSON:
{
"id": 0,
"text": "Something here...",
"decisions": [],
"children": [],
"speaker": 0,
"checkpoint": true
}
I am struggling to follow some of the example code I have seen for how to set this up using Spring.
The way the back end is set up is:
There is a Decide class, a Node class, and a DecideController class. DecideController is supposed to take a POST request like above and then use the Decide class to get an instance of the Node class and use it as a response to the client.
I haven't begun testing the client side of things yet, but I am using Intellij Restful API tool to check if its working and it is giving me an error. Heres what I have for the actual method which should be handling the POST Request:
#RestController
public class DecideController {
#PostMapping("/decide")
public Node decide(#Valid #RequestBody Decide decide) {
return decide.getNode();
}
}
I am getting an error response when I send a request with this body:
{
"previousDecisions": [0, 1, 2]
}
And with these headers:
Accept: application/json
Cache-Control: no-cache
This is the error response:
{"timestamp":"2019-09-01T23:54:58.037+0000","status":500,"error":"Internal Server Error","message":"Content-Type cannot contain wildcard type '*'","path":"/decide"}
The last thing I can think of that you might need to help me out is the Decide class and it is pretty short so I will include that here as well:
public class Decide {
private int[] decisionList;
public Decide(int[] decisionList) {
this.decisionList = decisionList;
}
public Node getNode() {
//Use the game class to get a root node for the entire story tree
Node rootNode = (new Game()).getFullStoryTree();
//Traverse the story tree using the decisionList to get to the current node
Node currentNode = rootNode;
for (int whichChild : this.decisionList) {
currentNode = currentNode.getChild(whichChild);
}
return currentNode;
}
}
As said about what I am expecting from that POST request is a response that looks like this:
{
"id": 0,
"text": "Something here...",
"decisions": [],
"children": [],
"speaker": 0,
"checkpoint": true
}
Sorry I am pretty new to all of this so hopefully everything I said here makes sense, but if not I am happy to clarify or provide more information. Thank you!!

The error is coming from the server, because of the client:
"Internal Server Error","message":"Content-Type cannot contain wildcard type '*'"
Even though the PAYLOAD looks ok, your react client is setting the Content-Type HTTP header to "*". You need to fix the problem in react.
SUGGESTION:
Follow this link to set Content-Type to application/json.

Related

Show object scheme in Swagger while maintaining a data/meta structure

Designing a REST API I'd like to implement the following structure with a clear distinction between the returned object(s) and any relevant metadata
{
"data": [
{
"id": 1,
"clockingTime": "2022-08-10T15:32+02:00[Europe/Paris]",
"comment": 101,
"crudType": 1
}
],
"meta": {
"creationTime": "2022-08-11T17:10:40.045+0200",
"correlationId": "93b058ad-5383-4054-b284-342d3041f79f"
}
}
This is achieved by having a top level object RestResponseObject containing data and meta with the data object being extended by all objects-to-return
#GetMapping(value = "/test")
public ResponseEntity<RestResponseObject> test() {
RestResponseObject restResponseObject = new RestResponseObject();
restResponseObject.setData(new FooDTO());
restResponseObject.setMeta(new RestMetaObject());
return new ResponseEntity<>(restResponseObject , HttpStatus.OK);
}
the issue is that this obfuscates the actual object being returned and swagger will not show the scheme with relevant variables and/or types
Is this the wrong way to implement a data/meta object structure or is there no other way to show the actual objects being returned

How can I dynamically find the end of an object array inside of a JSON response using GSON?

I am working with a given JSON response. The API I'm using provides responses like such:
{
"data":[
{
"sample-value": "sample"
}
{
"sample-value": "sample"
}
{
"sample-value": "sample"
}
{
"sample-value": "sample"
}
],
"meta": {
"current-page": 1,
"next-page": 2,
"prev-page": null,
"total-pages": 5,
"total-count": 4338,
"filters": {}
},
"links": {
"self": "linktothisquery",
"next": "linktonextquery",
"last": "linktolastpagequery"
}
}
As you can see, the response provided contains what I interpret to be 1 object array (size changes depending on what is being queried) and 2 objects. (data is the array, meta and links are the objects) I have ran into a situation where I need to run multiple requests in order to get the full amount of data required for my project. I'm attempting to get around this by iterating through requests, but due to the variance in response length per-request I cannot use the same logic to locate only the array in the response and thus end up with unexpected characters making GSON unable to parse. I'm currently doing this by using String.substring() and manually inputting the location inside of the response that I want GSON to parse. Basically, I want GSON to ONLY see the "data" array and ignore everything else. I have model classes in my project to serialize the data, but they are built around the objects inside of the afforementioned array and not the array itself.
Your posted JSON is invalid .In data array comma is missing in between two objects. It should be
{
"sample-value": "sample"
},
{
"sample-value": "sample"
}
Now if you just want the data array part you can manually parse it using JsonParser. It will be the easiest way to do it.
String json = "{\"data\":[{\"sample-value\":\"sample\"},{\"sample-value\":\"sample\"},{\"sample-value\":\"sample\"},{\"sample-value\":\"sample\"}],\"meta\":{\"current-page\":1,\"next-page\":2,\"prev-page\":null,\"total-pages\":5,\"total-count\":4338,\"filters\":{}},\"links\":{\"self\":\"linktothisquery\",\"next\":\"linktonextquery\",\"last\":\"linktolastpagequery\"}}";
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
JsonArray jsonArray = jsonObject.get("data").getAsJsonArray();
jsonArray.forEach(System.out::println);
Output:
{"sample-value":"sample"}
{"sample-value":"sample"}
{"sample-value":"sample"}
{"sample-value":"sample"}

How to validate a list of values from the response using RestAssured

Could someone please me understand how to validate a list of items from the response. Say the response looks something like below,
{
"store":{
"book":[
{
"author":"Nigel Rees",
"category":"reference",
"price":8.95,
"title":"Sayings of the Century"
},
{
"author":"Evelyn Waugh",
"category":"fiction",
"price":12.99,
"title":"Sword of Honour"
},
{
"author":"Herman Melville",
"category":"fiction",
"isbn":"0-553-21311-3",
"price":8.99,
"title":"Moby Dick"
},
{
"author":"J. R. R. Tolkien",
"category":"fiction",
"isbn":"0-395-19395-8",
"price":22.99,
"title":"The Lord of the Rings"
}
]
}
}
The element Book has four lists under it with different data, now if I want to validate the author name and the price sequentially (in a loop for instance) how can I achieve that..?
I usually convert the response into a Json document and then validate, but in this case, if I use the Json path "Store.book.author", out of the four lists from the response, which list would it refer to..? That's where my confusion is.
There is in-build method in rest assured which you can use to get all item of Array as List of map.
String key="book";//array key (as it mentioned in your Json)
Response response=//your API call which will return Json Object
List<Hash<String,Object>>booksList=response.jsonPath().getList(key);
//Now parse value from List
Hash<String,Object> firstBookDetails=booksList.get(0);// for first index
String author=(String)firstBookDetails.get("author");
When using Rest Assured with BDD, you can try this out.
given()
.when()
.get(API URL)
.then()
.assertThat().body("store.book.author[0]", equalTo("Nigel Rees"));

Retrofit 2. Posting a list of objects that include a file

I need to be able to send a list of objects that include an image per object.
{
id: 0,
file="/yy/xx.png",
answers=[yellow, brown]
},
{
id: 1,
file="/zz/foo.png",
answers=[not yellow, not brown]
}
How would I go about doing that? My idea right now is to do a List<PartMap> and post that.
Make an object with 3 atrbutes: int id, String file, String[] answers..then you set these objects, make a list and send then in the body os the #POST

Migrate Python Dict to Java and JSON

I was a decent programmer in Python. Now i am forced to do a Wowza Module for my chat application. An application which will login by facebook account and the status of each user is saved on a Wowza Server, which use java for app development, connected via flash client & RTMP. The online status datastructure will be like this in Python.
Please tell me how to represent it in Java, I am not so familar with variable 'Types' in java :(
x = {
10001: {
'status': 0,
'friends': {}
},
10002: {
'status': 1,
'friends': {
10001: 0,
10003: 1
}
},
10003: {
'status': 1,
'friends': {
10001: 0,
10003: 1
}
}
}
10001,10002 etc will be facebook user ids.. and 0,1 will be their online/offline status.
If 10001 is connected, the datastructure will have some little modifications, it will change the status of 10001 to 1, and add all his friends ids, retrieved from facebook and update their status too.
x = {
10001: {
'status': 1,
'friends': {
10002: 1,
10003: 1
}
},
10002: {
'status': 1,
'friends': {
10001: 1,
10003: 1
}
},
10003: {
'status': 1,
'friends': {
10001: 1,
10003: 1
}
}
}
And if the user 10001 is disconnected, it will goto earlier stage.
Is there anyway i can store it as a json object? or is there any simple way to Store and retrieve data?
I assume that by store and retrieve, you mean cache it in memory, so:
(1) Create javabean classes to encapsulate the data. A java HashMap is very similar to a python dictionary. Why don't you try to write the classes in java as if they were python, update your question with the result, and then people can help you with details such as java generics which have no real python equivalent.
(2) Use one of the Object<-->JSON mapping frameworks that are out there to serialize instances to/from JSON. Gson and Jackson are popular.
It depends on what you want to do...
If you can use a json library such as Google Gson, it's perfect to manage JSON from Java.
then if you want to code it by yourself and you just manage integers and strings, it's not very difficult...
a Json structure is just an array or a map key/value where key is a String and Value is either a simple value or a complex one hence a hashmap or an array...
Anyway, generally, it's easier to use directly GSon ;)
All i needed was http://www.json.org/javadoc/org/json/JSONObject.html library.
I could use it with little struggle like adding 'type' to every object and can't create the tree in one step as in python.
Thanks mandubian and jtoberon :))
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
public class JSONExample {
JSONObject json;
JSONObject objJSON;
JSONObject objObjJSON;
public void addtoJSON(){
json = new JSONObject();
objJSON= new JSONObject();
objObjJSON =new JSONObject();
//adding last tree
objObjJSON.put(10001, 0);
objObjJSON.put(10002, 1);
//adding secondary tree
objJSON.put("status",1);
objJSON.put("friends",objObjJSON);
//added root tree
objJSON.put(10003,objJSON);
System.out.println("JSON is " + objJSON);
}
}

Categories

Resources