I am building a movies API with a node-js back-end. I have used postman to create the data to be fetched at the API. The first object works fine, I am able to GET and POST only one object like this:
{
"title": "The Dictator",
"genre": "drama, comedy",
"rating": "7.2",
"isReleased": "true"
}
When I try to create more than one object in my POST request, the data returned at the end point is garbage, like this:
[
{
_id: "59b4c78a1157f62f88defdee",
__v: 0,
isReleased: true
}
]
The data I am trying to send to the end point resembles this format, json array of objects:
[
{
"title": "The Dictator",
"genre": "drama, comedy",
"rating": "7.2",
"isReleased": "true"
},
{
"title": "The Dictator",
"genre": "drama, comedy",
"rating": "7.2",
"isReleased": "true"
},
{
"title": "The Dictator",
"genre": "drama, comedy",
"rating": "7.2",
"isReleased": "true"
}
]
I am using postman to create post and mongodb to save data. My code looks like this:
var moviesModel = require('./../models/movieModel');
/**
Get Request For Retrieving All Movies from MongoDB
*/
var getMovies = function(req, res){
moviesModel.find(function(err, movies_data){
if (err) {
console.error(`Collections Empty`);
res.status(500);
res.end('A Server Error Has Occurred');
}
res.status(200);
res.send(movies_data);
});
}
/**
Post Request For Adding Movie to MongoDB
*/
var addMovie = function(req, res){
var m = new moviesModel(req.body);
m.save(function(err){
if (err) {
res.status(500);
res.end(`Save Operation Failed`);
} else {
res.status(201); //movie created
res.send(m);
}
});
}
My schema is defined in movieModel.js file. Could someone share with me how to construct this kind of post request with postman or share a link?
I know this question has no programming relevance but it could help me with building APIs to call from my website and android app. Thanks.
Related
I am using Apollo in my Kotlin Multiplatform Android application. I write requests like this:
apolloClient.query(query).execute().onEach{ response ->
// Here we access data via response.data
}
The problem is that the responses to some requests from the server contain non-standard root fields along with the "data" field.
An example of such a response:
{
"data": {
"user": {
"name": "John",
"surname": "Smith"
}
},
"other_data": {
"some_field": "blah blah blah"
}
}
How do I access the other_data field in the server response?
I have api that return list of workers:
{
"items": [
{
"id": "e0fceffa-cef3-45f7-97c6-6be2e3705927",
"avatarUrl": "https://cdn.fakercloud.com/avatars/marrimo_128.jpg",
"firstName": "Dee",
"lastName": "Reichert",
"userTag": "LK",
"department": "back_office",
"position": "Technician",
"birthday": "2004-08-02",
"phone": "802-623-1785"
},
{
"id": "6712da93-2b1c-4ed3-a169-c69cf74c3291",
"avatarUrl": "https://cdn.fakercloud.com/avatars/alterchuca_128.jpg",
"firstName": "Kenton",
"lastName": "Fritsch",
"userTag": "AG",
"department": "analytics",
"position": "Orchestrator",
"birthday": "1976-06-14",
"phone": "651-313-1140"
},
....
]
}
I want to filter the response so that I only get information about a worker from a specific department.
I tried to do it like this:
interface WorkersApi {
#GET("users")
suspend fun getWorkers(
#Query("department") department: String
): Workers
}
But it return the same list without any filters. How can I filter the response so that I only get information about a worker from a specific department?
*Workers is just data class that hold only one field - list of items(workers)
What you tried to do changes the request to the server. It sends the department as query parameter with the request. If the server doesn't support this parameter nothing happens. I don't know if you work together with the people controlling the backend but you could discuss with them if they could add functionality for filtered results.
If instead, you want to filter the results after getting the full list from the server simply apply a filter on the list that you got.
you could do this on your Workers object
val department = "example"
val filteredList = workersObject.items.filter {it.department == department}
I have a problem when I hit the backend API, I found a difference result on Postman and AsyncTask (httpPost). Why does it happen?
I use the multer-s3-transform nodejs plugin to upload the files into my backend API's, then stored on digitalocean spaces.
Below is a result from AsyncTask:
{
"fieldname":"user_photo",
"originalname":"IMG-20180308_0938_55321.jpg",
"encoding":"7bit",
"mimetype":"application/octet-stream",
"size":84289,
"bucket":"mycdn",
"key":"1e9440387181846f54bece8a5d95a8a9",
"acl":"public-read",
"contentType":"image/jpeg",
"metadata":null,
"location":"https://mycdn.sgp1.digitaloceanspaces.com/1e9440387181846f54bece8a5d95a8a9",
"etag":"\"91ff71e41380602dbc35c94100f88d80\""
}
And this is one from PostMan:
{
"fieldname": "user_photo",
"originalname": "my-photos.png",
"encoding": "7bit",
"mimetype": "image/png",
"transforms": [
{
"id": "or",
"size": 109955,
"bucket": "mycdn",
"key": "users/1520907984802.png",
"acl": "public-read",
"contentType": "image/png",
"metadata": null,
"location": "https://mycdn.sgp1.digitaloceanspaces.com/users/1520907984802.png",
"etag": "\"8e161cab4c516b5eb48c3c1c66987de9\""
}
]
}
My final question, why is the transforms array not showing up in my AsyncTask result?
In my server I have a table called Sync wich looks like that:
}
"name": "Sync",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"uuid": {
"type": "string"
},
"table": {
"type": "string"
},
"action": {
"type": "string"
},
"timeChanged": {
"type": "number"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
and in my database I have the following records in this table:
Sync": {
"34": "{\"uuid\":\"287c6625-4a95-4e11-847e-ad13e98c75a2\",\"table\":\"Property\",\"action\":\"create\",\"timeChanged\":1466598611995,\"id\":34}",
"35": "{\"uuid\":\"287c6625-4a95-4e11-847e-ad13e98c75a2\",\"table\":\"Property\",\"action\":\"update\",\"timeChanged\":1466598625506,\"id\":35}",
"36": "{\"uuid\":\"176aa537-d000-496a-895c-315f608ce494\",\"table\":\"Property\",\"action\":\"update\",\"timeChanged\":1466598649119,\"id\":36}"
}
How to apply a filter to by #GET request and I get all of the records say with timeChanged attribute bigger than or equal to "1466598625506".
I did try that:
#GET("Syncs")
Call<List<Sync>> getAllSyncsAfterThisTimeStamp(#Query(("filter[where][timeChanged]=>")) long timeChanged);
but that returns an empty array "[]". Please, any ideas how to get this filtering done?
There can be solution to this on the server side. I don't think that retrofit alone will be able to accomplish this task.
You can write a logic on server side which takes a get argument as a number and returns all object greater than or equal to that number.
Corresponding to this server script, you can make requests where you can pass a query parameter and get the desired result. You cant run a database query from a get or post request.
The JSON result for getUsers I get from the server looks like this:
{
"result": [
{
"meta": {
"rows": "3"
}
},
{
"items": [
{
"id": "1",
"name": "Steve",
"age": "30"
},
{
"id": "2",
"name": "Mary",
"age": "29"
},
{
"id": "3",
"name": "Bill",
"age": "58"
}
]
}
]
}
How can I deserialize it by GSON in my android app (I'm using retrofit)?
I can't imagine any wrapper classes because of the different object types in result.
Any help would be appreciated!
For good example
Converting JSON to Java
Other way, you can convert your json to a java object
Please use org.json library http://www.json.org/java/index.html
Then, for example
json = new JSONObject(YOUR_JSON).getJSONObject("result");
JSONArray items = data.getJSONArray("items");
String name = items.getJSONObject(0).getString("name");
You can write a TypeAdapter for a type that will be (de)serialized to(from) array. You can even make it generic, so it will work with type like Pair<A, B>. Here is an example for non-generic type: https://github.com/cakoose/json-tuple-databinding-examples/blob/master/java/src/GsonEntryCustomizer.java — it (de)serializes Entry to(from array).
Disclaimer — I have not written nor tested that code, but it seems legit.
If you only encounter such problem once (like in your example), you may not bother making it generic, just write TypeAdapter for your specific pair of 2 different classes. The reading code is quite straightforward:
in.beginArray();
SomeClass1 info1 = gson.getAdapter(SomeClass1.class).read(in);
SomeClass2 info2 = gson.getAdapter(SomeClass2.class).read(in);
in.endArray();
return new SomeContainerClass(info1, info2);
(see https://github.com/cakoose/json-tuple-databinding-examples/blob/master/java/src/GsonEntryCustomizer.java#L52)