Client-side models are becoming more common. Most work with JSON-REST interfaces by default. However, there is no standards around manipulating the set of data returned by a rest service. This attempts to come to some standard.
- Make it easy to understand and have close parallels with common SQL paradigms and relational algebra.
- Make work with standard server-side Query string libraries.
This: ownerId<>Foo
would be so choice. But not supported by most query-string operators.
// Task
{
id: 1,
name: "do dishes",
ownerId: 5,
cost: 10,
parentTaskId: 7
}
// User
{
id: 5,
name: "Justin",
efficiency: 6
}
sort =(PROP_NAME ASC|DESC)* sort=owner.name ASC,cost ASC
Sorts the set by the property name in the direction described.
group =(PROP_NAME)* group=ownerId
Adds a grouping by a specified property name
join =(TYPE_NAME)* join=owner
Includes data for TYPE_NAME relationship within every data object.
include =(TYPE_NAME)* include=owner
Adds the unique related TYPE_NAME data to the data to be returned.
add add=count
Adds some additional information to the returned data. In this case, adds the total size of the result set without limit/offset.
sum sum=cost
Sums a specified column. This should be used with group.
limit limit=10
offset offset=20
FILTER_PROP_NAME owner.name=Justin
GET /tasks
{
data: [
{id: 1, name: "do dishes", ownerId: 5}, ...
]
}
GET /tasks?ownerId=5
GET /tasks?owner.name=Justin
GET /tasks?join[]=owner
{
data: [{id: 1, name: "dishes", ownerId: 5, owner: {id: 5, name: "Justin"}}, ...]
}
GET /tasks?include[]=owner
{
data: [{id: 1, name: "dishes", ownerId: 5}, ....],
owners: [{id: 5, name: "Justin"}, ...]
}
GET /tasks?
group=ownerId
sum=cost
[
{cost: 20, ownerId: 5},
{cost: 12, ownerId: 2},
...
]
GET /tasks
ownerId=5
limit=10
sort=cost DESC
add=count
{
data: [{id: 1, name: "dishes", ownerId: 5}, ... }]
count: 300
}
GET /tasks
ownerId=5
limit=10
offset=10
sort=cost DESC
GET /tasks
parentTaskId=7
include=parentTask
[{
data: [tasks],
parentTask: [parentTasks]
}]
Yeah this is a problem we run into all the time and it doesn't have a standard solution. I like it. Moving this logic into a library makes the server even thinner (in terms of application code).