-
Notifications
You must be signed in to change notification settings - Fork 22
API Structure
This is the API structure required for a server to support cTree functionality.
WARNING: this is still under design
- Should the cTree key be part of the path instead of the parameters? (ex.
/get/testTree?...
or/testTree/get?...
instead of/get?cTree=testTree&...
)- In most cases, requests will apply to a single cTree
- We'd need a different way to handle requesting a list of cTrees
- Should there be 1 endpoint for each transaction type (get, put, user-put) or data type (ex. feedback, post, segmentVariation, etc.)?
- Fewer endpoints makes server side processing more complicated
- More endpoints means larger changes may need to be broken down into multiple requests
- More endpoints means client side may need to choose between multiple endpoints for similar requests, based on variations in input data
- More endpoints makes documentation simpler to describe
- Fewer endpoints reduces need for clients and documentation to keep track of growing list of endpoints
- Fewer endpoints allows extending functionality seamlessly on server side if parameter/property keys don't change
- Should
/put-user
use parameters instead of (or in addition to) a JSON request body?- It's probably more efficient to use parameters instead of a JSON body
- Would this violate standards or conventions since it's a POST type?
- Would we need to include more complex (i.e. nested) data for the user?
- Could we have some data in parameters and some in JSON, in case some data needed more complexity?
- If we support mixing parameters and JSON data, should we do this for /put too?
- When sending data, should we use PUT instead of POST for cases which aren't expected to add new data, so they're considered idempotent?
- Is there any efficiency benefit?
- Is there any stability benefit?
- This would make client logic more complicated
- This probably makes server logic more complicated
- This makes it more likely for the server to return an error, if the wrong type is used based on the request
- Would it make sense to start with POST and add PUT support in the future for any requests which don't add new data, in addition to continuing POST support?
- Should we support parameters with no value or empty value, as described below?
- Does this violate any standards or conventions (obviously key-value pairs are more common)?
- Is this incompatible with some frameworks?
- Should we support series within strings by using commas, as described below, or repeating the same key?
- Is one easier than the other to support on the server side?
- Does common convention point more to one way than the other?
- If we had many items in a series, and/or a large key name, it seems like using commas would be more efficient and easier to read the URL for developers/QA
- SignIn and SingUp API methods
- Should we have a unique user (as a service user) to run all authentication or multiple users?
signIn
** All methods must be authorized by JWT. To retrieve a valid token, the frontend application must request a token through a call to /signIn within a form-data content in the body of the request (i.e. email and password), as in the example below:
POST /signUp HTTP/1.1
Host: iurix.com
Content-Type: multipart/form-data;boundary="boundary"
--boundary
Content-Disposition: form-data; name="email"
postmaster@ctree.org
--boundary
Content-Disposition: form-data; name="password"
start
** The method returns a JSON within user data in the body of the response, plus Authorization Bearer in the header.
signUp
** To create a new user, the method /signUp must be called. Then, a user's registered and, once it's approved, permissions will be granted to retrieve data. firstNames and lastNames fields are optional.
Below, there is an example of a form-data to register a user:
POST /signUp HTTP/1.1
Host: iurix.com
Content-Type: multipart/form-data;boundary="boundary"
--boundary
Content-Disposition: form-data; name="email"
postmaster@ctree.org
--boundary
Content-Disposition: form-data; name="password"
start
--boundary
Content-Disposition: form-data; name="firstNames"
Postmaster
--boundary
Content-Disposition: form-data; name="lastNames"
Ctree
- Types always start with a capital letter, for both native types and those defined below.
- Some values may start with a capital letter (ex.
Description
for ParentDataKey, so it uses the appropriate camel case whenfor<ParentDataKey>
is replaced withforDescription
). - In this specification, values are always put inside a
code block
, but types are only put in code blocks when used within<...>
(ex.Segment
vs. ParentDataKey vs.for<ParentDataKey>
). - When a word is enclosed by
<
and>
, it indicates it should be replaced with a value of that type (either native or defined in this specification). - If
|
is used within<...>
it indicates the start of another type which can be used, or a potential value to use (ex.<true|false>
). - For some types, the valid and default values may depend on other types used. This is indicated below as sub-items for a value (ex. ListDataKey).
- In some example JSON data,
<...>
blocks may be inside quotes to ensure proper JSON formatting, but that doesn't mean they shouldn't be replaced (ex.{ "for<ParentDataKey>": <String> }
should still be replaces with something like{ "forDescription": "ABC123" }
).
StringList - a series of strings, separated by a comma, without any additional space (ex. abc,def,hij
)
ItemDataKey - keys used to indicate when specific data should be included (usually details about the cTree itself)
cTreeName
cTreeIcon
ListDataKey - the key used determines which values can be used for each of the others listed (see the Parameters section below)
-
cTree
- always required (may not be required for getting user data, if that becomes part of/get
in the future), indicates cTree key when String or StringList value set- SortType:
id
(default),alphabetical
,popularity
,featured
,suggested
- cTreePageSize value: Integer (default: 10)
- ParentDataKey: N/A
- SubDataKey: N/A
- GroupDataKey: N/A
- nestedDepth value: N/A
- nested ParentDataKey: N/A
- SortType:
-
postType
- SortType:
id
(default),alphabetical
,index
- postTypePageSize value: Integer (default: 50)
- ParentDataKey: N/A
- SubDataKey: N/A
- GroupDataKey: N/A
- nestedDepth value: N/A
- nested ParentDataKey: N/A
- SortType:
-
segmentType
- SortType:
id
(default),alphabetical
- segmentTypePageSize value: Integer (default: 50)
- ParentDataKey: N/A
- SubDataKey: N/A
- GroupDataKey: N/A
- nestedDepth value: N/A
- nested ParentDataKey: N/A
- SortType:
-
post
- SortType:
suggested
(default, not available whenfor<ParentDataKey>
parameter specified),rating
(default fallback if suggested not available) - postPageSize value: Integer (default: 20),
top
(only valid if ParentDataKey set) - ParentDataKey:
Parent
,Child
(optional) - SubDataKey:
description
,segmentVariation
- GroupDataKey:
postType
(optional - only valid if ListDataKey set to a SortType) - nestedDepth value: Integer (default when not included: 1, default when included: 5)
- nested ParentDataKey:
Parent
(default),Child
(ifParentDataKey
set toChild
)
- SortType:
-
description
- SortType:
rating
(default) - descriptionPageSize value: Integer (default: 3),
top
(only valid if ParentDataKey set) - ParentDataKey:
Post
(required if ListDataKey set to a SortType) - SubDataKey:
segmentVariation
- GroupDataKey: N/A
- nestedDepth value: N/A
- nested ParentDataKey: N/A
- SortType:
-
segmentVariation
- SortType:
rating
(default) - segmentVariationPageSize value: Integer (default: 3),
top
(only valid if ParentDataKey set) - ParentDataKey:
Segment
(required if ListDataKey set to a SortType) - SubDataKey: N/A
- GroupDataKey: N/A
- nestedDepth value: N/A
- nested ParentDataKey: N/A
- SortType:
-
feedback
- SortType:
rating
(default) - feedbackPageSize value: Integer (default: 10),
top
(only valid if ParentDataKey set) - ParentDataKey:
Description
,Feedback
(requires either of these if ListDataKey set to a SortType),ChildFeedback
- SubDataKey: N/A
- GroupDataKey: N/A
- nestedDepth value: Integer (default when not included: 1, default when included: 5)
- nested ParentDataKey:
Feedback
(default),ChildFeedback
(ifParentDataKey
set toChildFeedback
)
- SortType:
-
query
- search for posts- SortType: N/A
- queryPageSize value: Integer (default: 20)
- ParentDataKey:
Parent
(optional, does not restrict results to parent, but items with matching parent are listed first) - SubDataKey:
description
,segmentVariation
- GroupDataKey: N/A
- nestedDepth value: Integer (default when not included: 1, default when included: 2)
- nested ParentDataKey:
Parent
Different types return different data, as described below. In cases where the prefix of a data key matches the key for the container, the prefix is dropped (ex. cTreeName
would just be name
when it's returned as an item in the cTree
data). All data types always include id
, so that won't be listed. In some cases (ex. cTree) there may be entries included which are related to the request (ex. NextPageOffset), not the type data, which also won't be listed here.
For some types, like post
, there is nested data which could be moved under for<ListDataKey>
so it's consistent, instead of being inline with the object. This makes it a bit nicer for the client to use, but could be changed in favor of consistency. If that's preferred, this can be updated to remove those nested types and the associated <SubDataKey>NextPageOffset
values.
-
cTree
- none of these are returned by default- name:
<String>
- the human readable name of the cTree (needs localization support) - icon:
<String>
- a URL for the icon associated with the cTree
- name:
-
postType
- all of these are returned by default- name:
<String>
- the human readable name of the cTree (needs plural variation and localization support) - icon:
<String>
- a URL for the icon associated with the post type - color:
<String>
- a HEX color value (starting with #) associated with the post type - description:
<String>
- a human readable description of what the post type represents (needs localization support) - prompt:
<String>
- a human readable phrase to use in the client indicating if users want to create a new post of the specified type (needs localization support & maybe dynamic context variation support) - parentsRequired:
<Boolean>
- true if all posts of the type are required to have a parent associated with them (must be false if parentsMax=0) - parentsMax:
<Integer>
- number indicating how many parents the type can have, with -1 indicating infinite (can't be 0 if parentsRequired=true) - parentTypes:
[<String>, ...]
- (optional) an array of the IDs for each parent type, with no specific sort order enforced
- name:
-
segmentType
- all of these are returned by default- componentName:
<String>
- the name of the web component used to display segment data with this type - canBeThumbnail:
<Boolean>
- true if the segment data of this type can be shown as a thumbnail for a post (used for preview items to surface thumbnails like images)
- componentName:
-
post
- included by default
- type:
<String>
- the ID of the postType for the post - title:
<String>
- the human readable title for the post (needs localization support) - rating:
<Number>
- the rating value associated with the post (may be a decimal value) - description:
[description, ...]
- (optional) array of description variations (seedescription
) for the post (the number and sort order depends on the request) - descriptionNextPageOffset:
<String>
- (optional) offset value which can be used to request the next page of description variations for the post (only included if description is included) - user:
{...}
- (optional) contains info about the post related to the current user, if there is any- bookmarked:
<Boolean>
- indicates if the post has been bookmarked by the current user - rating:
<Integer>
- the rating set for the post by the current user
- bookmarked:
- type:
- not included by default
- isTop:
<Boolean>
- indicates if the post is considered a top post based on the rating - topChildCount:
<Integer>
- count of posts considered top posts based on their rating, with this post as their parent - childCount:
<Integer>
- count of total posts with this post as their parent - parentCount:
<Integer>
- count of total posts with this post as their child - createdDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of when the post was created - lastInteractionDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of the last interaction related to the post (ex. updated, feedback added, rating changed, etc.) - interactionCount:
<Integer>
- count of total interactions - feedbackCount:
<Integer>
- count of total feedback associated with the post
- isTop:
- included by default
-
description
- included by default
- rating:
<Number>
- the rating value associated with the description variation (posts can have multiple description variations) - segments:
[segment, ...]
- the array of segments in the description (this is a fixed order for the description variation, not something to be sorted or split into pages)
- rating:
- not included by default
- isTop:
<Boolean>
- indicates if the description variation is considered a top variation based on the rating - createdDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of when the description variation was created - lastInteractionDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of the last interaction related to the description variation (ex. updated, feedback added, rating changed, etc.) - interactionCount:
<Integer>
- count of total interactions - feedbackCount:
<Integer>
- count of total feedback associated with the description variation
- isTop:
- included by default
-
segment
- all of these are returned by default (don't forget that this should have an ID value too, which we can use for the ParentDataKey when getting asegmentVariation
list)- segmentVariation:
[segmentVariation, ...]
- (optional) array of segment variations (seesegmentVariation
) for the segment (the number and sort order depends on the request) - segmentVariationNextPageOffset:
<String>
- (optional) offset value which can be used to request the next page of variations for the segment (only included if segmentVariation is included)
- segmentVariation:
-
segmentVariation
- all of these are returned by default- included by default
- type:
<String>
- the ID of the segmentVariationType for the segmentVariation - rating:
<Number>
- the rating value associated with the segmentVariation (may be a decimal value) - data:
<Dynamic>
- the data for the segmentVariation (type of data depends on the segmentVariationType, needs localization support)
- type:
- not included by default
- isTop:
<Boolean>
- indicates if the segmentVariation is considered a top variation based on the rating - createdDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of when the segmentVariation was created - lastInteractionDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of the last interaction related to the segmentVariation (ex. updated, feedback added, rating changed, etc.) - interactionCount:
<Integer>
- count of total interactions - feedbackCount:
<Integer>
- count of total feedback associated with the segmentVariation
- isTop:
- included by default
-
feedback
- more complex data is planned, but that can be added later- included by default
- rating:
<Number>
- the rating value associated with the feedback (may be a decimal value) - text:
<String>
- the human readable text of the feedback (needs localization support) - author:
<String>
- the ID of the user who created the feedback - createdDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of when the feedback was created
- rating:
- not included by default
- childCount:
<Integer>
- count of total feedback with this feedback as their parent - nestedChildCount:
<Integer>
- count of all feedback nested under this feedback - isTop:
<Boolean>
- indicates if the feedback is considered top feedback based on the rating - lastInteractionDate:
<Long>
(<String>
?) - numeric timestamp value (in UTC) of the last interaction related to the feedback (ex. updated, feedback added, rating changed, etc.) - interactionCount:
<Integer>
- count of total interactions
- childCount:
- included by default
Get data based on parameters set for URL.
/get
GET
Parameters
- Required - include one or more (cTree required)
-
<ItemDataKey>=<true|false>
- default is true if parameter is included -
<ListDataKey>=<String|StringList|SortType>
- when parameter included, the default value is the default SortType for the ListDataKey, String values are expected to be a UUID (except forquery
, where it's a search term)
-
- List Modifiers
-
for<ParentDataKey>=<String|StringList>
- required for data tied to a parent, empty value looks for items with nothing set for entry of type ParentDataKey (ex. if<ListDataKey>
ispost
,forParent
orforParent=
would list posts with no parent) -
<ListDataKey|SubDataKey>PageSize=<Integer|top>
- default when not included depends on ListDataKey, only valid for query or when SortType used. Default is 1 for subdata (ex. description variations for a post) when not included, subdata returned always uses default sort (can include parameters for each SubDataKey) Depending on the ListDataKey,top
may be specified to return all matching items classified as top rated. -
pageOffset=<String>
- default is none when empty or not included, only valid when there's exactly 1 query or SortType type specified for any<ParentDataKey>
value (including as a default value) and exactly 0 or 1for<ParentDataKey>
value (not 2 or more) -
nestedDepth=<Integer>
- the number of recursive calls (minus 1) made with resulting items as the value offor<ParentDataKey>
before returning bundled result. If the number of items gets too large, the response may return with a reduced value fornestedDepth
. Default depends on ListDataKey. (values <= 0 invalid) -
postType=<String|StringList>
- only valid for post and query, restricts posts in list to those matching the specified type(s) -
groupBy=<GroupDataKey>
- specify a valid GroupDataKey for the ListDataKey to use, only valid when query or SortType used -
<ListDataKey|SubDataKey>Data=<String|StringList>
- specify key(s) of which data to include for ListDataKey and/or SubDataKey items (default data specified in Response Data Documentation, include an empty item in the value list to include all default data) -
exclude<ListDataKey|SubDataKey>=<String|StringList>
- IDs of items to exclude getting the data for, because the data is already known. The item is still included to indicate relationships, but only the ID of the item is contained in the Object data.
-
To avoid duplicate data, the full data is only included for the first occurrence of an item, and all other occurrences only include the ID in the data Object.
{
"request": { // not sure if it's worth including this, but could be useful, especially if a default value ends up being used by the server
"cTree": <String>,
<ItemDataKey>: <Boolean>,
<ListDataKey>: <String>,
"for<ParentDataKey>": <String>,
"<ListDataKey>PageSize": <Integer>,
"pageOffset": <String>,
"<SubDataKey>PageSize": <Integer>,
"nestedDepth"=<Integer>,
"postType"=<StringList>,
"groupBy"=<GroupDataKey>,
"<ListDataKey>Data"=<StringList>,
"<SubDataKey>Data"=<StringList>,
"exclude<ListDataKey>"=<StringList>,
"exclude<SubDataKey>"=<StringList>
},
"cTree": [
{
"id": <String>,
<ItemDataKey>: <ItemDataType>,
<ListDataKey>: [
{
"id": <String>,
<SubDataKey>: [
{}
],
"<SubDataKey>NextPageOffset": <String>
}
],
"<ListDataKey>NextPageOffset": <String>
"for<ParentDataKey>": {
<String>: { // this string is the ID of the parent data
<ListDataKey>: [
{}
],
"<ListDataKey>NextPageOffset": <String>,
"for<GroupDataKey>": {
<String>: { // this string is the ID of the group data
<ListDataKey>: [
{}
],
"<ListDataKey>NextPageOffset": <String>
}
}
}
}
}
],
errors: {},
meta: {
"copyright": <String>,
"application": <String>,
"version": <String>,
"id": <String>,
"status": <String>,
"message": <String>
}
}
DataKey Parameters: using the ParentDataKey and ListDataKey values create correct keys and values
-
/get?cTree=ABC123&post=suggested
- returns up to 20 (default page size) of the top suggested posts for the user, from the cTree with the IDABC123
-
/get?cTree=ABC123&post=suggested&forParent=DEF456
- returns up to 20 of the top suggested posts with the parent having IDDEF456
-
/get?cTree=ABC123&post=suggested&forParent=DEF456&descriptionCount=3&segmentVariationCount=7
- load 3 descriptions with 7 variations for each segment in each post in the returned list of posts -
/get?cTree=ABC123&post=suggested&forParent=DEF456&forChild=CDE345
- NOT valid to use both ParentDataKey values (Parent
andChild
) -
/get?cTree=ABC123&feedback=rating
- NOT valid because feedback requires setting a ParentDataKey -
/get?cTree=ABC123&feedback=rating&forDescription=DEF789
- returns up to 20 of the highest rated feedback for the description with the IDDEF789
Combining Request: this combines the requests to get the name
, list of all post types, and list of all segment types for the cTree with ID ABC123
/get?cTree=ABC123&cTreeData=name&postType=id&segmentType=id
Request Variations: since id
is the default sort type, it can be excluded, and if the server supports it we could even remove "="
-
/get?cTree=ABC123&segmentType=id
/get?cTree=ABC123&segmentType=
/get?cTree=ABC123&segmentType
Paged Data: the <ListDataKey>PageSize
and pageOffset
can be specified to adjust the items returned from list requests
-
/get?cTree=featured&cTreePageSize=3&cTreeData=name,icon
- get name and icon for first 3 featured cTrees -
/get?cTree=ABC123&post=rating&postPageSize=10&pageOffset=FED987
- get next 10 posts, sorted by rating, starting from the offset identified by the valueFED987
-
/get?cTree=ABC123&segmentVariation&forSegment=DEF789&segmentVariationPageSize=5&pageOffset=EDC876
- get next 8 segment variations for segment with IDDEF789
, with default sorting, starting from the offset identified by the valueEDC876
-
/get?cTree=ABC123&query=text%20to%20search%20for&queryPageSize=10
- get the first 10 posts matching the querytext to search for
Post Filters: lists of posts can be filtered by type and/or having a specific parent or child
-
/get?cTree=ABC123&post&postType=FDB369
- get a list of posts who's type has IDFDB369
-
/get?cTree=ABC123&post&postType=FDB369,DBF258
- get a list of posts who's type has either IDFDB369
or IDDBF258
-
/get?cTree=ABC123&post&forParent=ACE765
- get a list of posts who are children of the post (have the parent) with IDACE765
-
/get?cTree=ABC123&post&forChild=ECA567,ACE765
- get a list of posts who are parents of the posts (have the child) with IDECA567
orACE765
(each list of posts and next page offset are returned in different objects in the response, under the keyforChild
and their respective child post ID) -
/get?cTree=ABC123&post&forParent=ACE765&postType=FDB369
- get a list of posts who are children of the post (have the parent) with IDACE765
and who's type has IDFDB369
Sub-data Size: the maximum number of items included in lists within returned data can be modified
-
/get?cTree=ABC123&post&descriptionCount=3&segmentVariationCount=5
- get list of posts, who each have up to 3 descriptions, with each segment having up to 5 variations -
/get?cTree=ABC123&post&descriptionCount=0
- get list of posts, who each have 0 descriptions (default) (they can be loaded later by the post ID) -
/get?cTree=ABC123&description&forPost=DEF537&segmentVariationCount=3
- get list of descriptions for post with IDDEF537
, each with up to 3 segment variations
Requesting Specific Data: changing which data is returned for items
-
/get?cTree=ABC123&post&postData=isTop,
- addisTop
to data returned for all posts returned in search list (added because an empty key is implied after the,
, indicating including the default data) -
/get?cTree=ABC123&post&postData=isTop
- just returnid
(always included) andisTop
data for all posts returned in search list (no,
, so no empty key, thus no default data included) -
/get?cTree=ABC123&post&descriptionData=rating
- just include theid
(always included) andrating
(nosegements
) in description data loaded for each posts returned in search list -
/get?cTree=ABC123&feedback=490ABD&feedbackData=nestedChildCount
- get thenestedChildCount
(count of all feedback and sub-feedback) for the feedback with ID490ABD
Nested Child Request: get a tree containing the children from a specific starting item
-
/get?cTree=ABC123&post&forParent&nestedDepth
- gets the posts at the start of the cTree, with the default nesting depth -
/get?cTree=ABC123&post&forParent=DEF537&postPageSize=top&groupBy=postType&nestedDepth
- gets the top rated posts nested under the post with IDDEF537
, grouped bypostType
-
/get?cTree=ABC123&post&forParent=DEF537&postPageSize=top&nestedDepth=20
- gets the top rated posts nested under the post with IDDEF537
, up to 20 layers deep (the server may reduce the depth to limit the number of items returned, which can be checked in the response valuerequest.nestedDepth
) -
/get?cTree=ABC123&query=text%20to%20search%20for&queryPageSize=10&nestedDepth
- get the first 10 posts matching the querytext to search for
, and their direct decedents -
/get?cTree=ABC123&feedback&forDescription=CAD943&feedbackPageSize=top&nestedDepth
- get the top feedback nested for the description with IDCAD943
-
/get?cTree=ABC123&post&forParent=DEF537&nestedDepth&excludePost=ECA567,ACE765
- gets the posts nested under the post with IDDEF537
, excluding the data for the posts with IDECA567
orACE765
(if found, their IDs will still be returned, but no data, usually because the data was already loaded)
Nested Parent Request: get a tree containing the parent, grandparents, etc. of a specific item
-
/get?cTree=ABC123&post&forChild=DEF537&nestedDepth
- get the nested ancestor posts of the post with IDDEF537
-
/get?cTree=ABC123&post&forChild=DEF537&nestedDepth=20
- get the nested ancestor posts, up to 20 layers deep, of the post with IDDEF537
-
/get?cTree=ABC123&feedback&forChildFeedback=490ABD&nestedDepth
- get the nested ancestor feedback of the feedback with ID490ABD
Response: example for /get?cTree=ABC123&cTreeName&postType&segmentType
- TODO: may want to update to /get?cTree=ABC123&cTreeData=name&postType&segmentType
{
"request": {
"cTree": "ABC123",
"cTreeName": true,
"postType": "id",
"segmentType": "id"
},
"cTree": [
{
"id": "ABC123",
"cTreeName": "Example Tree Name",
"postType": [
{
"id": "DEF456",
"name": "Example Post Type",
"parentsRequired": false,
"parentsMax": 0,
"iconUrl": "/images/post_type_icon.png",
"color": "#FF7700", /* could start using an integer instead */
"description": "This is an example post type",
"prompt": "Button label to add post with type"
}
],
"segmentType": [
{
"id": "BDF789",
"componentName": "example-type-component,
"canBeThumbnail": true
}
]
}
],
errors: {},
meta: {
"copyright": "Copyright (c) 2020 Foundation For an Innovative Future (InnovativeFuture.org)",
"application": "cTree Rest API",
"version": "0.1d",
"id": "HTTP/1.1 200 Authorized",
"status": "true",
"message": "Successful request. Access allowed"
}
}
Add/update stored data based on provided JSON, treated as a single transaction (i.e. no partial updates).
/put
POST
{
"post": {
},
"for<ParentDataKey>": {
<String>: {
<ListDataKey>: [
{}
]
}
}
}
Same as request, but when ID isn't included for data, to indicate new data should be added, the IDs created should be added to the returned data.
Add/update user specific data based, like ratings. The user the data is set for is the user associated with the session token.
/put-user
POST
{
"for<ParentDataKey>": [
<String>
],
"rating": <-1|0|1> // until users are supported this can be treated as a blind update
}
{
"request": {
"for<ParentDataKey>": <String>,
"rating": <Integer>
},
"previous": {
"for<ParentDataKey>": {
<String>: {
"rating": <Integer> // the previous rating by the user - until we have users this can always be 0
}
}
},
"updated": {
"for<ParentDataKey>": {
<String>: {
"rating": <Integer> // the new user rating, even if unchanged - until we have users this should always match the request
}
}
},
errors: {},
meta: {
"copyright": <String>,
"application": <String>,
"version": <String>,
"id": <String>,
"status": <String>,
"message": <String>
}
}