This is a simple proof of concept. In a lot of cases, where mobile apps are simply meant to show some static data, it may be necessary to create an endpoint that the app could connect to and update its stale data.
Its unnecessary for the server to serve the complete data. What's needed is to serve only that subset of data that's been changed after the client's last update. The concept works when the data can be logically arranged in a hierarchical order.
The nodes of the tree can hold any information, and thus, this can be used as a generic API for syncing elements with any kind of data.
- Calling the
SyncTree(**root_info_data)
frombase.py
will return a SyncTree - You can add a node to the parent by calling
tree.add_node(parent_node, **child_node_data)
. This returns anNode
- You can save any data in the attributes of the
Node
frombase.py
. - You can keep updating the data in any of the nodes. At the end, call
tree.refresh_tree()
so that theSyncTree
updates everything in one go, and doesn't need to traverse the tree for every update. - Every
Node
has a_pk
attribute, and the node can be accessed usingtree.get_node(pk)
. - The node's childrens can be found by
node._children
- Every node has a hash assosiciated with it. It's a 3-tuple of hashes
(complete_hash, self_information_hash, children_hash)
# replace the "basic_example_tree_create" method in "serve.py"
from base import SyncTree
self.sync_tree = SyncTree(name="MyRetailStoreInformationAPI") # creates a root node
root = self.sync_tree.root
# realise that the nodes can contain _any_ information
info = self.sync_tree.add_node(root, name="Information",
description="About the app")
items_categories = self.sync_tree.add_node(root, type="Items categories holder",
details="Stuff")
store_info = self.sync_tree.add_node(info, description="lorem ipsum",
owner="Dohn Joe", branch_id=42)
pc_games = self.sync_tree.add_node(items_categories, discount=0.2)
console_games = self.sync_tree.add_node(items_categories, discount=0.5)
WoW = self.sync_tree.add_node(pc_games, reviews="wOw")
GoW3 = self.sync_tree.add_node(console_games, developers="Epic")
# That's enough sample data
self.sync_tree.refresh_tree()
# let's change something
WoW.price = 1200
WoW.currency = "INR"
store_info.manager = "Smith"
self.sync_tree.refresh_tree() # need to remember to do this.
So long as you use this sync_tree and refresh it finally, you can get the latest data from the server. Now let's see how the client should understand the API responses.
You can start up the server by python serve.py
- The first end point that the client app connects to is
/api/sync
with the GET parameterupdated_time
. - The server responds with the nodes that have been changed after that time. Example of a JSON format returned:
{
"data": {
"0": {
"hash": [
"3e9bd92dc32ed410c0558d7f94a39995",
"0495dd1b6406ade2ceecb94508acb64d",
"0a7c0e8cdbec85456071c611f0a7b99e"
],
"updated_time": 1433082211.372208
},
...
"2": {
"hash": [
"2627d89cd762977b0175a9404b851898",
"bd1707ea84f9ebeaa768cee3c32430e4",
"b48e96208c0d0aa32a48aa4ea6bd38b2"
],
"updated_time": 1433082211.372125
},
},
"success": true
}
- The data returned in the json is of the format
pk -> hash, updated_time
- The client should handle the following cases for each object returned in data. The client should should handle the objects according to the sorted order of pk.
- The first hash matches. This means everything is up to date for that object. Simply update the updated_time of the corresponding object on the app.
- The third hash doesn't match. This means a child has been changed. However the server sends the data of the child too. So simply update the hash and updated_time to the hash and updated_time sent by the server.
- The second hash doesn't match. This means that data of that node has been changed.
Append this object's pk to
pks_data_fetch_left = []
. Update the updated_time of the corresponding object on the app. - If a pk doesn't exist in the client side, this signifies a new node. Add it to a
new_children
list. Get its parent by calling the API endpoint/api/sync/node/type=get_parents&pk=<pk>
. Create a new object and add the pk topks_data_fetch_left
.
- Now call
api\sync\nodes
with GET paramstype=fetch
and multiplepk
params for each pk inpks_data_fetch_left
. For examplehttp://localhost:5000/api/sync/node?type=fetch&pk=1&pk=5&pk=2
- The returned JSON gives the complete data that's been added in the node. Update the data, hash and updated_time on the client side. Example JSON response
{
"data": {
"1": {
"data": {
"description": "About the app",
"name": "Information"
},
"hash": [
"71d4ad2c887f5f932cf1eaed086c16ba",
"f056140f9aab63cf3b388143b64c3a3a",
"2c26891b91903f65b5cc0e427ed0a1b1"
]
},
"2": {
"data": {
"details": "Stuff",
"type": "Items categories holder"
},
"hash": [
"2627d89cd762977b0175a9404b851898",
"bd1707ea84f9ebeaa768cee3c32430e4",
"b48e96208c0d0aa32a48aa4ea6bd38b2"
]
},
"5": {
"data": {
"discount": 0.5
},
"hash": [
"c4eba8badd0f23f3a55070dde8064522",
"b899471983dd7e12f4ea656e78d68ca6",
"699ff75480a6af339717756b0c578341"
]
}
},
"success": true
}
- Create a django app that can keep the sync tree updated on receiving signals. Parent-Children relationships are defined between models.