What should an iOS JSON payload submitting to an API look like? - ios

We have an iOS application that grabs model data from an API. The user of the iOS device performs actions that link up the model data and creates relationships between them. The iOS then submits back to the API to save the relationship and allow for the relationship to be viewable in the web application.
The JSON payload has the potentially of being large if all the objects that were associated with the new relationship are submitted with their attributes.
"peoples_vehicles": [
{
"owner" : {
"id" : 8282, <----------this would be a UUID
"name" : "John Smith",
"address": "123 Fake Street",
},
"vehicles" : [
{
"id" : 1234, <----------this would be a UUID
"name" : "FORD F150",
"make" : "F150",
"model" : "FORD",
"year" : "2017",
},
{
"id" : 5678, <----------this would be a UUID
"name" : "FORD ESCAPE",
"make" : "ESCAPE",
"model" : "FORD",
"year" : "2013",
}
]
},
{
... another person with their vehicles
}
]
Since the data being sent back is all data that was originally from the API, should the iOS application even bother sending all the attributes back? Should the iOS application simply send back all the relationships with only the objects ids? We use UUIDs
"peoples_vehicles": [
{
"owner" : {
"id" : 8282, <----------this would be a UUID
},
"vehicles" : [
{
"id" : 1234, <----------this would be a UUID
},
{
"id" : 5678, <----------this would be a UUID
}
]
},
{
... another person with their vehicles
}
]
We seem to be leaning more towards just sending ID for pre-existing data. It makes the submit payload from iOS to API have very few attributes that are actually strings (none in this example).
There are cases when we would have to create new custom objects. In that case, all the attributes would be sent over and the ID of this new object would be null to indicate that this object has to be created.
"peoples_vehicles": [
{
"owner" : {
"id" : 8282, <----this would be a pre-existing object
},
"vehicles" : [
{
"id" : 1234, <----this would be a pre-existing object
},
{
"id": null <----new object that needs to be saved
"name" : "FORD F150",
"make" : "F150",
"model" : "FORD",
"year" : "2017",
}
]
},
{
... another person with their vehicles
}
]
Would this be a decent approach? Looking at Stripe and Shopify API as examples, this seems to work nicely, but I wanted to make sure I wasn't missing anything and if I should be included the attributes for objects that are pre-existing.

Related

Using aws-api-gateway models, how can I require an object contains AT LEAST 1 valid key

I am using API gateway's request validation. Here is my model so far:
{
"type" : "object",
"required" : [ "dc", "uid", "data" ],
"properties" : {
"dc" : {
"type" : "string"
},
"uid" : {
"type" : "string"
},
"data" : {
"type" : "object"
}
},
"title" : "MyApi"
}
So similar to the required function, I want to ensure that the data object has at least one key in a list I define [a, b, c, whatever]
If this is not possible, is there a way to at least prevent a null value from being sent? I tried "nullable": false but AWS said that was an invalid model schema.
Setting minProperties to '1' may work. See https://swagger.io/docs/specification/data-models/data-types/
Can (should) data be strongly typed? If so you could use composition, inheritance, and polymorphism to indicate that the data is a defined schemas. See https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/

Query object in child array

I am trying to use a query to retrieve data of student who are only 4 years old from my database but i cant figure out how to use Firebase to query the age (The array in each child).
{
"student" : {
"-Kv2RVDDsI-v6V7g_LBn" : [ {
"name" : "sam",
"age" : "6"
}, {
"name" : "tom",
"age" : "4"
}
],
"-hguyu-v6V7g_LBn" : [ {
"name" : "Tim",
"age" : "12"
}, {
"name" : "tom",
"age" : "4"
}
]
}
}
This is my code but it does no return anything.
ref.child("student").queryOrdered(byChild: "age").queryEqual(toValue: 4).observe(.childAdded, with: { (snapshot) in
let value = snapshot.value
print(value)
}) { (error) in
print(error.localizedDescription)
}
However, if i remove the queryOrdered(byChild: "age") it works.
Thanks.
You are referencing "Student" when actually your JSON database format child path name is "Students".
Also make sure that you are querying by key. Refer to the Firebase documentation to see how to query by key. I don't understand your structure though why you have 2 children per key.
Why not have a new key for each child?

Neo4j cypher with parameters returns success but doesn't create anything?

If I send this:
{
"query" : "MATCH (p) WHERE p.id={id} CREATE (c {props}) CREATE UNIQUE p-[r:CHILD]->c",
"params" : {
"id" : ["{0000-0000-0000-0000}","{0000-0000-0000-0000}","{0000-0000-0000-0004}"],
"props" : [ {
"id" : "{0000-0000-0000-0004}",
"type": 48,
"title" : "TestNode"
},{
"id" : "{0000-0000-0000-0005}",
"type": 49,
"title" : "TestNode"
},{
"id" : "{0000-0000-0000-0006}",
"type": 49,
"title" : "TestNode"
}]
}
}
Via the restful cypher api, I get back "success" but nothing was created. If I send through this:
{
"query" : "MATCH (p) WHERE p.id={id} CREATE (c {props}) CREATE UNIQUE p-[r:CHILD]->c",
"params" : {
"id" : "{0000-0000-0000-0000}",
"props" : [ {
"id" : "{0000-0000-0000-0001}",
"type": 48,
"title" : "TestNode"
},{
"id" : "{0000-0000-0000-0002}",
"type": 49,
"title" : "TestNode"
} ]
}
}
It creates two children of 0000-0000-0000-0000 as expected. So something about the way I'm specifying two arrays isn't working.
I was hoping to be able to create large tree structures by essentially specifying parent ID/child to create parameters. The other option is that I use the latter style cypher and the transactional endpoint... but I'm just not sure what I'm doing wrong in the first one. Any advice much appreciated.
You probably need to do:
MATCH (p) WHERE p.id IN {id}
CREATE (c {props})
CREATE UNIQUE (p)-[r:CHILD]->(c)
The = operator is an exact comparison.

Ruby on rails polymorphic model: dynamic fields

Suppose I have base model class Item
class Item
include Mongoid::Document
field :category
end
Each category determines which fields should item contain. For example, items in "category1" should contain additional string field named text, items in "category2" should contain fields weight and color. All the fields are of basic types: strings, integers and so on.
These additional values are to be stored in mongodb as document's fields:
> db.items.find()
{ "_id" : ObjectId("4d891f5178146536877e1e99"), "category" : "category1", "text" : "blah-blah" }
{ "_id" : ObjectId("4d891f7878146536877e1e9a"), "category" : "category2", "weight" : 20, "color" : "red" }
Categories are stored in the mongodb, too. Fields' configuration is defined at runtime by an administrator.
> db.categories.find()
{ "_id" : "category1", "fields" : [ { "name" : "text", "type" : "String" } ] }
{ "_id" : "category2", "fields" : [
{
"name" : "weight",
"type" : "Integer"
},
{
"name" : "color",
"type" : "String"
}
] }
Users need to edit Items with html forms entering values for all additional fields defined for the category of particular item.
The question is
What approaches could I take to implement this polymorphism on rails?
Please ask for required details with comments.
Just subclass the Item, and Mongoid will take care of rest, e.g. storing type.
class TextItem < Item; end
Rails will like it, but you'll probably want to use #becomes method, as it will make form builder happy and path generation easier:
https://github.com/romanbsd/mongoid/commit/9c2fbf4b7b1bc0f602da4b059323565ab1df3cd6

MongoDB/Mongoid: Can one query for ObjectID in embedded documents?

For the record, I'm a bit of a newbie when it comes to Rails and MongoDB.
I'm using Rails+Mongoid+MongoDB to build an app and I've noticed that Mongoid adds ObjectID to embedded documents for some reason.
Is there any way to query all documents in a collection by ObjectID both the main documents and nested ones?
If I run this command
db.programs.findOne( { _id: ObjectId( "4d1a035cfa87b171e9000002" ) } )
I get these results which is normal since I'm querying for the ObjectID at root level.
{
"_id" : ObjectId("4d1a035cfa87b171e9000002"),
"created_at" : "Tue Dec 28 2010 00:00:00 GMT+0000 (GMT)",
"name" : "program",
"routines" : [
{
"name" : "Day 1",
"_id" : ObjectId("4d1a7689fa87b17f50000020")
},
{
"name" : "Day 2",
"_id" : ObjectId("4d1a7695fa87b17f50000022")
},
{
"name" : "Day 3",
"_id" : ObjectId("4d1a76acfa87b17f50000024")
},
{
"name" : "Day 4",
"_id" : ObjectId("4d1a76ecfa87b17f50000026")
},
{
"name" : "Day 5",
"_id" : ObjectId("4d1a7708fa87b17f50000028")
},
{
"name" : "Day 6",
"_id" : ObjectId("4d1a7713fa87b17f5000002a")
},
{
"name" : "Day 7",
"_id" : ObjectId("4d1a7721fa87b17f5000002c")
}
],
"user_id" : ObjectId("4d190cdbfa87b15c2900000a")
}
Now if I try to query with an ObjectID with one of the embedded document (routines) I get null like so.
db.programs.findOne( { _id: ObjectId( "4d1a7689fa87b17f50000020" ) } )
null
I know one can query embedded objects like so
db.postings.find( { "author.name" : "joe" } );
but that seems a bit redundant if you get passed an ObjectID of some sort and want to find in what document that ObjectID resides.
So I guess my question is this...
Is it possible, with some method I'm not familiar with, to query by ObjectID and search the ObjectID's in the embedded documents?
Thanks.
You can't query ObjectIDs globally like that. You would have to do
db.programs.find({"routines._id": ObjectId("4d1a7689fa87b17f50000020")})
no, you can search only by field like { "routines._id" : ObjectId("4d1a7689fa87b17f50000020")}
If you want to get the matched sub-document only you can use $elemMatch with '$' operator like below:
db.programs.find({"_id" : ObjectId("4d1a035cfa87b171e9000002"),
routines:{$elemMatch:{"_id" : ObjectId("4d1a7689fa87b17f50000020")}}},{"routines.$":1})
It will return you only that matched sub-document instead of the complete sub-document.

Resources