Search¶
Prerequisite to test following examples is to have an API key with permissions:
Path | Methods | ACL |
---|---|---|
/resources/car | GET, POST | off |
/resources/car/[0-9a-fA-F]{24} | GET | off |
/resources/trip | GET, POST | off |
/resources/driver | GET, POST | off |
/resources/driver/[0-9a-fA-F]{24} | GET | off |
/resources/fleet | GET, POST | off |
/resources/fleet/[0-9a-fA-F]{24} | GET | off |
/resources/company | GET, POST | off |
Search examples require car documents created with following API requests:
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "car",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [ "navigation", "park assistent" ]
}
}
}' \
-X POST https://api.jazer.io/resources/car
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "car",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [ "navigation" ]
}
}
}' \
-X POST https://api.jazer.io/resources/car
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "car",
"attributes": {
"name": "Tesla Model S P85",
"mileage": 30000,
"year": 2016,
"options": [ "navigation", "parking sensors", "homelink" ]
}
}
}' \
-X POST https://api.jazer.io/resources/car
Documents¶
Fetching documents of a certain type is doable using GET method on the collection path: /resources/<DOCUMENT_TYPE>
.
Documents of type car can be fetched using GET method on path /resources/car
. Complete API request is:
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/car
The response contains created car documents:
{
"meta": {
"count": 3
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [ "navigation", "park assistent" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [ "navigation" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
},
{
"type": "car",
"id": "59e3aca5ac61050ba8b970a6",
"attributes": {
"name": "Tesla Model S P85",
"mileage": 30000,
"year": 2016,
"options": [ "navigation", "parking sensors", "homelink" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3aca5ac61050ba8b970a6"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
All cars documents are returned since there are only three documents in car collection and default page size is 20. Metadata contains property count
which holds value of a total number of documents accross all pages.
Pagination¶
Query parameter page supports collection pagination. Offset-based and page-based strategies can be used:
- offset-based utilizes page[offset] and page[limit]
- page-based utilizes page[number] and page[size]
Offset-based¶
Example of an offset-based API request:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET 'https://api.jazer.io/resources/car?page[offset]=0&page[limit]=2'
The response contains data and pagination links based on the given page offset and limit:
{
"meta": {
"count": 3
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [ "navigation", "park assistent" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [ "navigation" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?page[offset]=0&page[limit]=2",
"last": "https://api.jazer.io/resources/car?page[offset]=2&page[limit]=2",
"prev": null,
"next": "https://api.jazer.io/resources/car?page[offset]=2&page[limit]=2"
}
}
Page-based¶
Example of a page-based API request:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET 'https://api.jazer.io/resources/car?page[number]=1&page[size]=2'
The response contains data and pagination links based on the given page number and size:
{
"meta": {
"count": 3
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [ "navigation", "park assistent" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [ "navigation" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?page[number]=1&page[size]=2",
"last": "https://api.jazer.io/resources/car?page[number]=2&page[size]=2",
"prev": null,
"next": "https://api.jazer.io/resources/car?page[number]=2&page[size]=2"
}
}
Filtering¶
Query parameter filter supports collection filtering. Two syntaxes are supported:
- filter[*] - filter applies to an entire document
- filter[<FIELD>] - filter applies only to a document field
Example:
filter[*]={ "$and": [{ "x": { "$gt": 10 }}, { "y": { "$lt": 5 } }] }
produces the same result as:
filter[x]={ "$gt": 10 }&filter[y]={ "$lt": 5 }
Comparison operators¶
Following comparison operators use the syntax: { "<FIELD>": { "<OPERATOR>": <VALUE> } }
.
Operator | Description |
---|---|
$eq | Equivalence, matches documents where field value is equal to a given value |
$ne | Negated equivalence, matches documents where field value is not equal to a given value |
$gt | Greather than, matches documents where field value is greater than a given value |
$gte | Greather than or equal, matches documents where field value is greater or equal to a given value |
$lt | Less than, matches documents where field value is less than a given value |
$lte | Less than or equal, matches documents where field value is less or equal to a given value |
Equivalence operator provides sugar syntax: { "<FIELD>": <VALUE> }
. In other words if operator is not specified, equivalence operator is used.
An array based operators use the syntax: { "<FIELD>": { "<OPERATOR>": [ <VALUE_1>, <VALUE_2> ... ] } }
.
Operator | Description |
---|---|
$in | In, matches documents where field value is in a given array |
$nin | Not in, matches documents where field value is not in a given array |
Example filtering using filter[*] with the value {“mileage”: {“$lt”: 40000}} which is URL encoded:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/car?filter[*]=%7B%22mileage%22%3A%20%7B%22%24lt%22%3A%2040000%7D%7D
The response contains car documents with a mileage field less than 40000:
{
"meta": {
"count": 1
},
"data": [
{
"type": "car",
"id": "59e3aca5ac61050ba8b970a6",
"attributes": {
"name": "Tesla Model S P85",
"mileage": 30000,
"year": 2016,
"options": [ "navigation", "parking sensors", "homelink" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3aca5ac61050ba8b970a6"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22mileage%22%3A%20%7B%22%24lt%22%3A%2040000%7D%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22mileage%22%3A%20%7B%22%24lt%22%3A%2040000%7D%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
The same result would be using a filter[mileage] with the value {“$lt”: 40000}.
Logical operators¶
Following logical operators use the syntax: { "<FIELD>": { "<OPERATOR>": <EXPRESSION> } }
.
Operator | Description |
---|---|
$not | Negation, matches documents where expression is falseful for a field |
An array based logical operators use the syntax: { "<OPERATOR>": [ <EXPRESSION_1>, <EXPRESSION_2> ] }
.
Operator | Description |
---|---|
$and | Conjunction, matches documents where all expressions in an array are truthful |
$or | Disjunction, matches documents where at least one expression in an array is truthful |
$nor | Joint denial, matches documents where all expressions in an array are falseful |
Example filtering using a filter[*] with the value {“$or”: [{“year”: {“$gte”: 2016}}, {“mileage”: {“$lt”: 40000}}]} which is URL encoded:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/car?filter[*]=%7B%22%24or%22%3A%20%5B%7B%22year%22%3A%20%7B%22%24gte%22%3A%202016%7D%7D%2C%20%7B%22mileage%22%3A%20%7B%22%24lt%22%3A%2040000%7D%7D%5D%7D
The response contains car documents which match query year or mileage field:
{
"meta": {
"count": 2
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [ "navigation", "parking assistent" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3aca5ac61050ba8b970a6",
"attributes": {
"name": "Tesla Model S P85",
"mileage": 30000,
"year": 2016,
"options": [ "navigation", "parking sensors", "homelink" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3aca5ac61050ba8b970a6"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22%24or%22%3A%20%5B%7B%22year%22%3A%20%7B%22%24gte%22%3A%202016%7D%7D%2C%20%7B%22mileage%22%3A%20%7B%22%24lt%22%3A%2040000%7D%7D%5D%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22%24or%22%3A%20%5B%7B%22year%22%3A%20%7B%22%24gte%22%3A%202016%7D%7D%2C%20%7B%22mileage%22%3A%20%7B%22%24lt%22%3A%2040000%7D%7D%5D%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Array operators¶
Array fields can use these special operators:
Operator | Description |
---|---|
$all | Inclusion, matches documents where all given values are included in the field array |
$elemMatch | Element matching, matches documents where all expressions in given array are truthful for at least one item in the field array |
$size | Cardinality, matches documents where the given integer is a field cardinality |
Syntax:
- $all -
{ "<FIELD>": { "$all": [ <VALUE_1> , <VALUE_2> ... ] } }
- $elemMatch -
{ "<FIELD>": { "$elemMatch": [ <EXPRESSION_1>, <EXPRESSION_2> ... ] } }
- $size -
{ "<FIELD>": { "$size": <INTEGER> } }
Comparison operators can be used for array fields. Comparison operator matches documents where operator expression is truthful for at least one item in field array.
Example filtering using a filter[*] with the value {“$or”: [{“options”: {“$size”: 1}}, {“options”: {“$eq”: “homelink”}}]} which is URL encoded:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/car?filter[*]=%7B%22%24or%22%3A%20%5B%7B%22options%22%3A%20%7B%22%24size%22%3A%201%7D%7D%2C%20%7B%22options%22%3A%20%7B%22%24eq%22%3A%20%22homelink%22%7D%7D%5D%7D
The response contains Mercedes-Benz car document which matches options cardinality and Tesla car document which contains homelink in options:
{
"meta": {
"count": 2
},
"data": [
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [ "navigation" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
},
{
"type": "car",
"id": "59e3aca5ac61050ba8b970a6",
"attributes": {
"name": "Tesla Model S P85",
"mileage": 30000,
"year": 2016,
"options": [ "navigation", "parking sensors", "homelink" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3aca5ac61050ba8b970a6"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22%24or%22%3A%20%5B%7B%22options%22%3A%20%7B%22%24size%22%3A%201%7D%7D%2C%20%7B%22options%22%3A%20%7B%22%24eq%22%3A%20%22homelink%22%7D%7D%5D%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22%24or%22%3A%20%5B%7B%22options%22%3A%20%7B%22%24size%22%3A%201%7D%7D%2C%20%7B%22options%22%3A%20%7B%22%24eq%22%3A%20%22homelink%22%7D%7D%5D%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Regular expression operator¶
Perl Compatible Regular Expressions (PCRE) are used for pattern matching. Regular expression operator syntax is: { "<FIELD>": { "$regex": "<PATTERN>", "$options": "<OPTIONS>" } }
.
Argument $options is optional and can contain values:
- i - case insensitive
- m - match multi-line strings against each line separately
- s - dot character matches new line characters
Example filtering using a filter[*] with the value {“name”: {“$regex”: “p(70|85|90|100)”, “$options”: “si”}} which is URL encoded:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET 'https://api.jazer.io/resources/car?filter[*]=%7B%22name%22%3A%20%7B%20%22%24regex%22%3A%20%22p(70%7C85%7C90%7C100)%22%2C%20%22%24options%22%3A%20%22si%22%20%7D%20%7D'
The response contains Tesla car document since name field contains P85:
{
"meta": {
"count": 1
},
"data": [
{
"type": "car",
"id": "59e3aca5ac61050ba8b970a6",
"attributes": {
"name": "Tesla Model S P85",
"mileage": 30000,
"year": 2016,
"options": [ "navigation", "parking sensors", "homelink" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3aca5ac61050ba8b970a6"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22name%22%3A%20%7B%20%22%24regex%22%3A%20%22p(70%7C85%7C90%7C100)%22%2C%20%22%24options%22%3A%20%22si%22%20%7D%20%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22name%22%3A%20%7B%20%22%24regex%22%3A%20%22p(70%7C85%7C90%7C100)%22%2C%20%22%24options%22%3A%20%22si%22%20%7D%20%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Full-text operator¶
Full-text search syntax is: { "$text": { "$search": "<TEXT>" } }
. All document fields of type string are included in the search. The comparison is not case sensitive.
Example filtering using a filter[*] with the value {“$text”: {“$search”: “benz”}} which is URL encoded:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/car?filter[*]=%7B%22%24text%22%3A%20%7B%20%22%24search%22%3A%20%22benz%22%20%7D%20%7D
The response will contain Mercedes-Benz car document since name contains Benz:
{
"meta": {
"count": 1
},
"data": [
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [ "navigation" ]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22%24text%22%3A%20%7B%20%22%24search%22%3A%20%22benz%22%20%7D%20%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?filter%5B*%5D=%7B%22%24text%22%3A%20%7B%20%22%24search%22%3A%20%22benz%22%20%7D%20%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Geospatial operators¶
Operator | Description |
---|---|
$geoIntersects | matches documents where a document field geospatial primitive intersects with the given geospatial primitive |
$geoWithin | matches documents where a document field geospatial primitive is bounded by the given geospatial primitive |
$near | sorts documents based on a document field geospatial primitive and the given geospatial point from nearest to farthest with optional filtering of minimum and/or maximum distance |
$nearSphere | variation of the $near operator which uses a spherical geometry |
Geospatial primitives are explained in GeoJSON.
Following API request creates trip document to be used for geospatial operator queries:
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "trip",
"attributes": {
"name": "Nashville to Memphis",
"location": {
"type": "LineString",
"coordinates": [
[ -86.77551272, 36.16005299 ],
[ -87.50610352, 35.96911508 ],
[ -88.76403809, 35.66175942 ],
[ -89.31335449, 35.44724606 ],
[ -90.04394531, 35.14910871 ]
]
}
}
}
}' \
-X POST https://api.jazer.io/resources/trip
The response contains a created trip document:
{
"data": {
"type": "trip",
"id": "59ffb122ac61052bff2f400e",
"attributes": {
"name": "Nashville to Memphis",
"location": {
"type": "LineString",
"coordinates": [
[ -86.77551272, 36.16005299 ],
[ -87.50610352, 35.96911508 ],
[ -88.76403809, 35.66175942 ],
[ -89.31335449, 35.44724606 ],
[ -90.04394531, 35.14910871 ]
]
}
},
"links": {
"self": "https://api.jazer.io/resources/trip/59ffb122ac61052bff2f400e"
}
}
}
$geoIntersects¶
Syntax:
{
"<LOCATION_FIELD>": {
"$geoIntersects": {
"$geometry": <GEO_JSON_DATA>
}
}
}
Test whether any trip document intersecting with the given road expressed as LineString.
{
"location": {
"$geoIntersects": {
"$geometry": {
"type": "LineString", "coordinates": [
[ -89.21894073, 35.44221152 ],
[ -89.23988342, 35.44584761 ],
[ -89.25619125, 35.47507018 ],
[ -89.28133965, 35.47576916 ],
[ -89.37515259, 35.44780543 ],
[ -89.55505371, 35.51657874 ]
]
}
}
}
}
API request with URL encoded query is:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/trip?filter[*]=%7B%22location%22%3A%7B%22%24geoIntersects%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22LineString%22%2C%22coordinates%22%3A%5B%5B-89.21894073%2C35.44221152%5D%2C%5B-89.23988342%2C35.4458476%5D%2C%5B-89.25619125%2C35.47507018%5D%2C%5B-89.28133965%2C35.47576916%5D%2C%5B-89.37515259%2C35.44780543%5D%2C%5B-89.55505371%2C35.51657874%5D%5D%7D%7D%7D%7D
The response contains a trip document:
{
"meta": {
"count": 1
},
"data": [
{
"type": "trip",
"id": "59ffb122ac61052bff2f400e",
"attributes": {
"name": "Nashville to Memphis",
"location": {
"type": "LineString",
"coordinates": [
[ -86.77551272, 36.16005299 ],
[ -87.50610352, 35.96911508 ],
[ -88.76403809, 35.66175942 ],
[ -89.31335449, 35.44724606 ],
[ -90.04394531, 35.14910871 ]
]
}
},
"links": {
"self": "https://api.jazer.io/resources/trip/59ffb122ac61052bff2f400e"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/trip?filter%5B*%5D=%7B%22location%22%3A%7B%22%24geoIntersects%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22LineString%22%2C%22coordinates%22%3A%5B%5B-89.21894073%2C35.44221152%5D%2C%5B-89.23988342%2C35.4458476%5D%2C%5B-89.25619125%2C35.47507018%5D%2C%5B-89.28133965%2C35.47576916%5D%2C%5B-89.37515259%2C35.44780543%5D%2C%5B-89.55505371%2C35.51657874%5D%5D%7D%7D%7D%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/trip?filter%5B*%5D=%7B%22location%22%3A%7B%22%24geoIntersects%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22LineString%22%2C%22coordinates%22%3A%5B%5B-89.21894073%2C35.44221152%5D%2C%5B-89.23988342%2C35.4458476%5D%2C%5B-89.25619125%2C35.47507018%5D%2C%5B-89.28133965%2C35.47576916%5D%2C%5B-89.37515259%2C35.44780543%5D%2C%5B-89.55505371%2C35.51657874%5D%5D%7D%7D%7D%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
$geoWithin¶
Syntax:
{
"<LOCATION_FIELD>": {
"$geoWithin": {
"$geometry": <GEO_JSON_DATA>
}
}
}
Operator $geoWithin needs bounding geospatial primitive. Therefore only Polygon and MultiPolygon can be used.
Test whether any trip document within given area expressed as Polygon.
{
"location": {
"$geoWithin": {
"$geometry": {
"type": "Polygon", "coordinates": [
[
[ -81.60644531, 41.31082388 ],
[ -81.91406252, 30.33495388 ],
[ -100.28320312, 34.63320791 ],
[ -81.60644531, 41.31082388 ]
]
]
}
}
}
}
API request with URL encoded query:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/trip?filter[*]=%7B%22location%22%3A%7B%22%24geoWithin%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22Polygon%22%2C%22coordinates%22%3A%5B%5B%5B-81.60644531%2C41.31082388%5D%2C%5B-81.9140625%2C30.33495388%5D%2C%5B-100.28320312%2C34.63320791%5D%2C%5B-81.60644531%2C41.31082388%5D%5D%5D%7D%7D%7D%7D
The response contains a trip document since it is entirely within given area.
{
"meta": {
"count": 1
},
"data": [
{
"type": "trip",
"id": "59ffb122ac61052bff2f400e",
"attributes": {
"name": "Nashville to Memphis",
"location": {
"type": "LineString",
"coordinates": [
[ -86.77551272, 36.16005299 ],
[ -87.50610352, 35.96911508 ],
[ -88.76403809, 35.66175942 ],
[ -89.31335449, 35.44724606 ],
[ -90.04394531, 35.14910871 ]
]
}
},
"links": {
"self": "https://api.jazer.io/resources/trip/59ffb122ac61052bff2f400e"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/trip?filter%5B*%5D=%7B%22location%22%3A%7B%22%24geoWithin%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22Polygon%22%2C%22coordinates%22%3A%5B%5B%5B-81.60644531%2C41.31082388%5D%2C%5B-81.9140625%2C30.33495388%5D%2C%5B-100.28320312%2C34.63320791%5D%2C%5B-81.60644531%2C41.31082388%5D%5D%5D%7D%7D%7D%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/trip?filter%5B*%5D=%7B%22location%22%3A%7B%22%24geoWithin%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22Polygon%22%2C%22coordinates%22%3A%5B%5B%5B-81.60644531%2C41.31082388%5D%2C%5B-81.9140625%2C30.33495388%5D%2C%5B-100.28320312%2C34.63320791%5D%2C%5B-81.60644531%2C41.31082388%5D%5D%5D%7D%7D%7D%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
$near/$nearSphere¶
Syntax:
{
"<LOCATION_FIELD>": {
"<OPERATOR>": {
"$geometry": {
"type": "Point" ,
"coordinates": [ <LONGITUDE>, <LATITUDE> ]
},
"$maxDistance": <METERS>,
"$minDistance": <METERS>
}
}
}
Only Point can be used with $near and $nearSphere operator. Properties $maxDistance and $minDistance are optional. Distance values are expressed in meters.
Example query with a maximum distance of 30 km:
{
"location": {
"$nearSphere": {
"$geometry": {
"type": "Point",
"coordinates": [ -86.53381348, 36.16227047 ]
},
"$maxDistance": 30000
}
}
}
API request with URL encoded query:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/trip?filter[*]=%7B%22location%22%3A%7B%22%24nearSphere%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22Point%22%2C%22coordinates%22%3A%5B-86.53381348%2C%2036.16227047%5D%7D%2C%22%24maxDistance%22%3A%2030000%7D%7D%7D
The response contains a trip document:
{
"meta": {
"count": 1
},
"data": [
{
"type": "trip",
"id": "59ffb122ac61052bff2f400e",
"attributes": {
"name": "Nashville to Memphis",
"location": {
"type": "LineString",
"coordinates": [
[ -86.77551272, 36.16005299 ],
[ -87.50610352, 35.96911508 ],
[ -88.76403809, 35.66175942 ],
[ -89.31335449, 35.44724606 ],
[ -90.04394531, 35.14910871 ]
]
}
},
"links": {
"self": "https://api.jazer.io/resources/trip/59ffb122ac61052bff2f400e"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/trip?filter%5B*%5D=%7B%22location%22%3A%7B%22%24nearSphere%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22Point%22%2C%22coordinates%22%3A%5B-86.53381348%2C%2036.16227047%5D%7D%2C%22%24maxDistance%22%3A%2030000%7D%7D%7D&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/trip?filter%5B*%5D=%7B%22location%22%3A%7B%22%24nearSphere%22%3A%7B%22%24geometry%22%3A%7B%22type%22%3A%22Point%22%2C%22coordinates%22%3A%5B-86.53381348%2C%2036.16227047%5D%7D%2C%22%24maxDistance%22%3A%2030000%7D%7D%7D&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Fields¶
Documents do not have to be returned in the response will all fields. Query parameter fields supports document field customization.
Syntax: fields[<DOCUMENT_TYPE>]=<FIELD_NAMES>
, where FIELD_NAMES is a comma-separated list of field names.
Example:
Created car documents have fields: name, mileage, year and options. To fetch car documents with only name and year fields, omitting mileage and options, following API request can be used:
curl --globoff -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/car?fields[car]=name,year
The response contains car documents with the selected fields:
{
"meta": {
"count": 3
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"year": 2016
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"year": 2015
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
},
{
"type": "car",
"id": "59e3aca5ac61050ba8b970a6",
"attributes": {
"name": "Tesla Model S P85",
"year": 2016
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3aca5ac61050ba8b970a6"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?fields%5Bcar%5D=name,year&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?fields%5Bcar%5D=name,year&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Inclusion¶
A document can specify related documents using relationships. Related documents can be included in the response alongside primary documents using query parameter include.
Syntax: include=<RELATIONSHIP_PATHS>
, where RELATIONSHIP_PATHS is a comma-separated list of relationship paths.
To-one relationship inclusion¶
Example API request creating driver document with to-one relationship car:
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "driver",
"attributes": {
"name": "John Smith"
},
"relationships": {
"car": {
"data": {
"type": "car",
"id": "<MERCEDES_BENZ_CAR_DOCUMENT_ID>"
}
}
}
}
}' \
-X POST https://api.jazer.io/resources/driver
The response contains a created driver document:
{
"data": {
"type": "driver",
"id": "5a04e205ac61052d59b453c0",
"attributes": {
"name": "John Smith"
},
"relationships": {
"car": {
"links": {
"self": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0/relationships/car",
"related": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0/car"
},
"data": {
"type": "car",
"id": "59e3ac8dac61050ba8b970a4"
}
}
},
"links": {
"self": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0"
}
}
}
Fetching driver documents and documents linked via relationship car is doable via query parameter include=car. Complete API request is:
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/driver?include=car
The response contains a primary driver document and an included car document:
{
"meta": {
"count": 1
},
"data": [
{
"type": "driver",
"id": "5a04e205ac61052d59b453c0",
"attributes": {
"name": "John Smith"
},
"relationships": {
"car": {
"links": {
"self": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0/relationships/car",
"related": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0/car"
},
"data": {
"type": "car",
"id": "59e3ac8dac61050ba8b970a4"
}
}
},
"links": {
"self": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0"
}
}
],
"included": [
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [
"navigation"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/driver?include=car&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/driver?include=car&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
To-many relationship inclusion¶
Example API request creating fleet document with to-many relationship cars:
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "fleet",
"attributes": {
"name": "Premium cars"
},
"relationships": {
"cars": {
"data": [
{
"type": "car",
"id": "<BMW_CAR_DOCUMENT_ID>"
},
{
"type": "car",
"id": "<MERCEDES_BENZ_CAR_DOCUMENT_ID>"
}
]
}
}
}
}' \
-X POST https://api.jazer.io/resources/fleet
The response contains a created fleet document:
{
"data": {
"type": "fleet",
"id": "5a04e066ac61052d59b453bc",
"attributes": {
"name": "Premium cars"
},
"relationships": {
"cars": {
"links": {
"self": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc/relationships/cars",
"related": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc/cars"
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2"
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4"
}
]
}
},
"links": {
"self": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc"
}
}
}
Fetching fleet documents and documents linked via relationship cars can be done via query parameter include=car. Complete API request is:
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/fleet?include=cars
The response contains a primary fleet document and an included car documents:
{
"meta": {
"count": 1
},
"data": [
{
"type": "fleet",
"id": "5a04e066ac61052d59b453bc",
"attributes": {
"name": "Premium cars"
},
"relationships": {
"cars": {
"links": {
"self": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc/relationships/cars",
"related": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc/cars"
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2"
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4"
}
]
}
},
"links": {
"self": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc"
}
}
],
"included": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [
"navigation",
"park assistent"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [
"navigation"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/fleet?include=cars&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/fleet?include=cars&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Deeply nested relationship inclusion¶
Document inclusion is not limited to relationships on the primary document, i.e. the first level of inclusion. Deeply nested relationship inclusion is supported.
Example API request creating company document with to-many relationship drivers and to-one relationship fleet:
curl -H 'Content-Type: application/vnd.api+json' \
-H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-d '
{
"data": {
"type": "company",
"attributes": {
"name": "Rent-a-car"
},
"relationships": {
"drivers": {
"data": [
{
"type": "driver",
"id": "<DRIVER_DOCUMENT_ID>"
}
]
},
"fleet": {
"data": {
"type": "fleet",
"id": "<FLEET_DOCUMENT_ID>"
}
}
}
}
}' \
-X POST https://api.jazer.io/resources/company
The response contains a created company document:
{
"data": {
"type": "company",
"id": "5a04e57bac61052d59b453ca",
"attributes": {
"name": "Rent-a-car"
},
"relationships": {
"drivers": {
"links": {
"self": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/relationships/drivers",
"related": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/drivers"
},
"data": [
{
"type": "driver",
"id": "5a04e205ac61052d59b453c0"
}
]
},
"fleet": {
"links": {
"self": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/relationships/fleet",
"related": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/fleet"
},
"data": {
"type": "fleet",
"id": "5a04e066ac61052d59b453bc"
}
}
},
"links": {
"self": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca"
}
}
}
Fetching company documents with an included documents of a relationship drivers and documents of a relationship cars from documents of a relationship fleet is doable using query parameter include=drivers,fleet.cars. It is not necessary to explicitly put fleet as a standalone path in the include, i.e. to use include=drivers,fleet,fleet.cars. Relationship fleet has to be traversed to resolve documents on path fleet.cars. The system will automatically resolve fleet relationship documents and include them.
curl -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/company?include=drivers,fleet.cars
The response contains a primary company document and related fleet, driver and car documents:
{
"meta": {
"count": 1
},
"data": [
{
"type": "company",
"id": "5a04e57bac61052d59b453ca",
"attributes": {
"name": "Rent-a-car"
},
"relationships": {
"drivers": {
"links": {
"self": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/relationships/drivers",
"related": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/drivers"
},
"data": [
{
"type": "driver",
"id": "5a04e205ac61052d59b453c0"
}
]
},
"fleet": {
"links": {
"self": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/relationships/fleet",
"related": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca/fleet"
},
"data": {
"type": "fleet",
"id": "5a04e066ac61052d59b453bc"
}
}
},
"links": {
"self": "https://api.jazer.io/resources/company/5a04e57bac61052d59b453ca"
}
}
],
"included": [
{
"type": "fleet",
"id": "5a04e066ac61052d59b453bc",
"attributes": {
"name": "Premium cars"
},
"relationships": {
"cars": {
"links": {
"self": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc/relationships/cars",
"related": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc/cars"
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2"
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4"
}
]
}
},
"links": {
"self": "https://api.jazer.io/resources/fleet/5a04e066ac61052d59b453bc"
}
},
{
"type": "driver",
"id": "5a04e205ac61052d59b453c0",
"attributes": {
"name": "John Smith"
},
"relationships": {
"car": {
"links": {
"self": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0/relationships/car",
"related": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0/car"
},
"data": {
"type": "car",
"id": "59e3ac8dac61050ba8b970a4"
}
}
},
"links": {
"self": "https://api.jazer.io/resources/driver/5a04e205ac61052d59b453c0"
}
},
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [
"navigation",
"park assistent"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [
"navigation"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/company?include=drivers,fleet.cars&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/company?include=drivers,fleet.cars&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
Inclusion security¶
Documents for which a client does not have read rights will not be included. Basically, if the client can read a document (i.e. fetch it using ID), it can be included.
API key with permission path /resources/fleet/[0-9a-fA-F]{24} and allowed GET method allows the client to read a fleet document using ID. Fleet document with ID 5a04e066ac61052d59b453bc therefore was able to be included in the response.
Sorting¶
Sorting is supported with query parameter sort. Syntax: sort=<ATTRIBUTE_NAMES>
, where ATTRIBUTE_NAMES is a comma-separated list of attributes to sort by. Default sort order is ascending. Prefix attribute name with - (minus) to sort in descending order.
Sorting car documents by attribute year descending and then by attribute name ascending can be done using query parameter sort=-year,name. Complete API request is:
curl -H 'Accept: application/vnd.api+json'
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/car?sort=-year,name
The response contains car documents sorted by year descending and by name ascending:
{
"meta": {
"count": 1
},
"data": [
{
"type": "car",
"id": "59e3ac5cac61050ba8b970a2",
"attributes": {
"name": "BMW 320d",
"mileage": 50000,
"year": 2016,
"options": [
"navigation",
"park assistent"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac5cac61050ba8b970a2"
}
},
{
"type": "car",
"id": "59e3aca5ac61050ba8b970a6",
"attributes": {
"name": "Tesla Model S P85",
"mileage": 30000,
"year": 2016,
"options": [
"navigation",
"parking sensors",
"homelink"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3aca5ac61050ba8b970a6"
}
},
{
"type": "car",
"id": "59e3ac8dac61050ba8b970a4",
"attributes": {
"name": "Mercedes-Benz C200D",
"mileage": 80000,
"year": 2015,
"options": [
"navigation"
]
},
"links": {
"self": "https://api.jazer.io/resources/car/59e3ac8dac61050ba8b970a4"
}
}
],
"links": {
"first": "https://api.jazer.io/resources/car?sort=-year,name&page[offset]=0&page[limit]=20",
"last": "https://api.jazer.io/resources/car?sort=-year,name&page[offset]=0&page[limit]=20",
"prev": null,
"next": null
}
}
ACL¶
API key permission can undergo ACL. When it does and the client does not have ACL read right for a certain document, the document will not be shown in the response.
API key permission with path /resources/car and allowed GET method with disabled ACL will provide the client to search across all car documents. Turning ACL on will provide search across only those documents for which user has read rights. Other documents will be not visible to the user.
Conditional get¶
Successful search API request will return a response with an ETag header. Repeating the same request with an additional header If-None-Match with the value of an ETag header from the previous response can have two outcomes. The server can return 200 OK and the whole body if primary documents or any of the included documents have changed or 304 Not Modified without the body when there have been no changes to the documents since the last request, i.e. given ETag is still valid.
Example API request searches for documents of type news.article:
curl -i -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-X GET https://api.jazer.io/resources/news.article
The response will be 200 OK with the body containing news.article documents. Response headers will contain an ETag. Repeat the same API request with an additional header If-None-Match with the value of an ETag header returned from this response:
curl -i -H 'Accept: application/vnd.api+json' \
-H 'api-key: <YOUR_API_KEY_SECURE_ID>' \
-H 'application-id: <YOUR_APPLICATION_ID>' \
-H 'If-None-Match: <ETAG_VALUE>' \
-X GET https://api.jazer.io/resources/news.article
The response will be 304 Not Modified if in the meantime new news.article documents have not been created or existing modified/removed.
Note
Web browsers support local caching using an ETag automatically.