DADI API wrapper
A high-level library for interacting with DADI API
Overview
DADI API is a high performance RESTful API layer designed in support of API-first development and the principle of COPE.
This library provides a high-level abstraction of the REST architecture style, exposing a set of chainable methods that allow developers to compose complex read and write operations using a simplistic and natural syntax.
Getting started
-
Install the @dadi/api-wrapper
module:
npm install @dadi/api-wrapper --save
-
Add the library and configure the API settings:
const DadiAPI = require('@dadi/api-wrapper')
const api = new DadiAPI({
uri: 'http://api.example.com',
port: 80,
credentials: {
clientId: 'johndoe',
secret: 'f00b4r'
},
version: 'vjoin',
database: 'testdb'
})
-
Make a query:
api
.in('users')
.whereFieldContains('name', 'john')
.whereFieldIsGreaterThan('age', 18)
.find()
.then(response => {
})
Methods
Each query consists of a series of chained methods to form the request, always containing a terminator method. Terminators return a Promise with the result of one or more requests to the database and can make use of a series of filtering methods to create the desired subset of documents to operate on.
Terminators
.apply(callback)
Updates a list of documents with the result of individually applying callback
to them.
api
.in('users')
.whereFieldExists('gender')
.apply(document => {
document.name =
document.gender === 'male'
? `Mr ${document.name}`
: `Mrs ${document.name}`
return document
})
.create()
Creates a document.
api
.in('users')
.create({
name: 'John Doe',
age: 45,
address: '123 Fake St'
})
.then(function(doc) {
console.log('New document:', doc)
})
.catch(function(err) {
console.log('! Error:', err)
})
.delete()
Deletes one or more documents.
api
.in('users')
.whereFieldDoesNotExist('name')
.delete()
.find(options)
Returns a list of documents.
api
.in('users')
.whereFieldIsGreaterThan('age', 21)
.useFields(['name', 'age'])
.find(options)
options
is one of the following:
extractResults
(Boolean): Selects whether just the results array should be returned, rather than the entire API response.extractMetadata
(Boolean): Selects whether just the metadata object should be returned, rather than the entire API response.
.getCollections()
Gets the list of collections for the API.
api.getCollections()
.getConfig()
Gets the config for a collection or for the API.
api.in('users').getConfig()
api.getConfig()
.getLanguages()
Gets the list of languages supported by the API.
api.getLanguages().then(({metadata, results}) => {
console.log(metadata)
console.log(results)
})
.getSignedUrl()
Gets a signed URL from a media collection.
api.in('images').getSignedUrl({
fileName: 'foobar.jpg'
})
.getStats()
Gets collection stats.
api.in('users').getStats()
.getStatus()
Gets the the API status.
api.getStatus()
.update(update)
Updates a list of documents.
api
.in('users')
.whereFieldIsLessThan('age', 18)
.update({
adult: false
})
Filters
Filtering methods are used to create a subset of documents that will be affected by subsequent operation terminators.
.goToPage(page)
Defines the page of documents to be used.
api.goToPage(3)
.limitTo(limit)
Defines a maximum number of documents to be retrieved.
api.limitTo(10)
.requireFeature(featureCode)
Queries the API for support of a given feature and throws a MISSING_FEATURES
error if it's not supported.
api.requestFeature('aclv1')
.sortBy(field, order)
Selects a field to sort on and the sort direction. Order defaults to ascending (asc
).
api.sortBy('age', 'desc')
.useFields(fields)
Selects the fields to be returned in the response. Accepts array format.
api.useFields(['name', 'age'])
.where(query)
Filters documents using a MongoDB query object or a Aggregation Pipeline array. The methods above are ultimately just syntatic sugar for where()
. This method can be used for complex queries that require operations not implemented by any other method.
api.where({name: 'John Doe'})
.whereClientIs(value)
Applicable when in "client mode". Selects the client with ID equal to value
.
api.inClients().whereClientIs('testClient')
.whereClientIsSelf()
Applicable when in "client mode". Selects the client associated with the bearer token being used.
api.inClients().whereClientIsSelf()
.whereFieldBeginsWith(field, text)
Filters documents where field
begins with text
.
api.whereFieldBeginsWith('name', 'john')
.whereFieldContains(field, text)
Filters documents where field
contains text
.
api.whereFieldContains('name', 'john')
.whereFieldDoesNotContain(field, text)
Filters documents field
does not contain text
.
api.whereFieldDoesNotContain('name', 'john')
.whereFieldEndsWith(field, text)
Filters documents where field starts with text
.
api.whereFieldEndsWith('name', 'john')
.whereFieldExists(field)
Filters documents that contain a field.
api.whereFieldExists('name')
.whereFieldDoesNotExist(field)
Filters documents that do not contain a field.
api.whereFieldDoesNotExist('address')
.whereFieldIsEqualTo(field, value)
Filters documents where field
is equal to value
.
api.whereFieldIsEqualTo('age', 53)
.whereFieldIsGreaterThan(field, value)
Filters documents where field
is greater than value
.
api.whereFieldIsGreaterThan('age', 18)
.whereFieldIsGreaterThanOrEqualTo(field, value)
Filters documents where field
is greater than or equal to value
.
api.whereFieldIsGreaterThanOrEqualTo('age', 19)
.whereFieldIsLessThan(field, value)
Filters documents where field
is less than value
.
api.whereFieldIsLessThan('age', 65)
.whereFieldIsLessThanOrEqualTo(field, value)
Filters documents where field
is less than or equal to value
.
api.whereFieldIsLessThanOrEqualTo('age', 64)
.whereFieldIsOneOf(field, matches)
Filters documents where the value of field
is one of the elements of matches
.
api.whereFieldIsOneOf('name', ['John', 'Jack', 'Peter'])
.whereFieldIsNotEqualTo(field, value)
Filters documents where field
is not equal to value
.
api.whereFieldIsEqualTo('age', 53)
.whereFieldIsNotOneOf(field, matches)
Filters documents where the value of field
is not one of the elements of matches
.
api.whereFieldIsNotOneOf('name', ['Mark', 'Nathan', 'David'])
.whereHookNameIs(name)
Selects the hook with a given name.
api.whereFieldIsNotOneOf('name', ['Mark', 'Nathan', 'David'])
.withComposition(value)
Defines whether nested documents should be resolved using composition. The default is to let API decide based on the queried collection's settings.
api.withComposition()
api.withComposition(true)
api.withComposition(false)
Other methods
.fromEndpoint(endpoint)
Selects a custom endpoint to use. Please note that unlike collections, custom endpoints do not have a standardised syntax, so it is up to the authors to make sure the endpoint complies with standard DADI API formats, or they will not function as expected.
api.fromEndpoint('custom-endpoint')
.in(collection)
Selects the collection to use.
api.in('users')
.inClients()
Selects "client mode", meaning filters and terminators will operate on clients and not on documents.
api.inClients()
.inHooks()
Selects "hook mode", meaning filters and terminators will operate on hooks and not on documents.
api.inMedia('images')
.inMedia(bucket)
Selects a media bucket to be used.
api.inMedia('images')
.inProperty(database)
Selects the property to use. Overrides any property defined in the initialisation options, and is reset when called without arguments.
api.inProperty('testdb')