We use FeathersJS as our REST and realtime API layer. All requests support a common way for querying, sorting, limiting and selecting find
method calls as part of params.query
. Querying also applies update
, patch
and remove
method calls if the id
is set to null
.
This allows us use more broad and generic API endpoints and allow the user to be more declarative on what data they actually want to consume or send to the API. For example, retrieving a single tenant would be /tenants/32
where 32 is the tenant id to return.
Also, when calling any endpoint, you can specify a tenantId
as a query string param like /dids/?tenantId=37
to get all DID's from tenant id 37.
{% hint style="warning" %} Important: When used via REST URLs all query values are strings {% endhint %}
Our API allows access and return data based on assigned user roles.
The following roles apply:
- 1 - Platform Administrator
- 3 - Tenant Administrator
- 5 - Basic User
When using your own front-end (React-Native or Browser) to consume the VOXO-API, it is encouraged to use the Feathers Client Libraries and specifically @feathersjs/socketio-client
to make all of your requests in a socket connection.
Creating a back-end server can be simplified by using the @feathersjs/feathers package.
All fields that do not contain special query parameters are compared directly for equality.
// Find all unread messages in room #2
app.service('messages').find({
query: {
read: false,
roomId: 2
}
});
GET /messages?read=false&roomId=2
$limit
will return only the number of results you specify:
// Retrieves the first two unread messages
app.service('messages').find({
query: {
$limit: 2,
read: false
}
});
GET /messages?$limit=2&read=false
$skip
will skip the specified number of results:
// Retrieves the next two unread messages
app.service('messages').find({
query: {
$limit: 2,
$skip: 2,
read: false
}
});
GET /messages?$limit=2&$skip=2&read=false
$sort
will sort based on the object you provide. It can contain a list of properties by which to sort mapped to the order (1
ascending, -1
descending).
// Find the 10 newest messages
app.service('messages').find({
query: {
$limit: 10,
$sort: {
createdAt: -1
}
}
});
/messages?$limit=10&$sort[createdAt]=-1
$select
allows to pick which fields to include in the result. This will work for any service method.
View More
// Only return the `text` and `userId` field in a message
app.service('messages').find({
query: {
$select: [ 'text', 'userId' ]
}
});
app.service('messages').get(1, { query: { $select: [ 'text' ] }});
GET /messages?$select[]=text&$select[]=userId
GET /messages/1?$select[]=text
Find all records where the property does ($in
) or does not ($nin
) match any of the given values.
// Find all messages in room 2 or 5
app.service('messages').find({
query: {
roomId: {
$in: [ 2, 5 ]
}
}
});
GET /messages?roomId[$in]=2&roomId[$in]=5
Find all records where the value is less ($lt
) or less and equal ($lte
) to a given value.
View More
// Find all messages older than a day
const DAY_MS = 24 * 60 * 60 * 1000;
app.service('messages').find({ query: { createdAt: { $lt: new Date().getTime() - DAY_MS } }});
GET /messages?createdAt[$lt]=1479664146607
Find all records where the value is more ($gt
) or more and equal ($gte
) to a given value.
View More
// Find all messages within the last day
const DAY_MS = 24 * 60 * 60 * 1000;
app.service('messages').find({ query: { createdAt: { $gt: new Date().getTime() - DAY_MS } }});
GET /messages?createdAt[$gt]=1479664146607
Find all records that do not equal the given property value.
// Find all messages that are not marked as archived
app.service('messages').find({
query: {
archived: {
$ne: true
}
}
});
GET /messages?archived[$ne]=true
Find all records that match any of the given criteria.
View More
// Find all messages that are not marked as archived
// or any message from room 2
app.service('messages').find({
query: {
$or: [
{ archived: { $ne: true } },
{ roomId: 2 }
]
}
});
GET /messages?$or[0][archived][$ne]=true&$or[1][roomId]=2