@dadi/api-wrapper

A high-level library for interacting with DADI API

Stats

stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
611May 9, 2021Apr 2, 2016Minified + gzip package size for @dadi/api-wrapper in KB

Readme

DADI API wrapper

A high-level library for interacting with DADI API

npm (scoped) Coverage Status Build Status JavaScript Style Guide

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

  1. Install the @dadi/api-wrapper module:

    npm install @dadi/api-wrapper --save
    
  2. 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'
      },
      property: 'test'
    })
    
  3. Make a query:

    // Example: getting all documents where `name` contains "john" and age is greater than 18
    api
      .in('users')
      .whereFieldContains('name', 'john')
      .whereFieldIsGreaterThan('age', 18)
      .find()
      .then(response => {
        // Use documents here
      })
    

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.

// Example
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.

// Gets the collection config
api.in('users').getConfig()
// Gets the API config
api.getConfig()

.getLanguages()

Gets the list of languages supported by the API.

api.getLanguages().then(({metadata, results}) => {
  /*
    {
      "defaultLanguage": {
        "code": "en",
        "name": "English",
        "local": "English"
      },
      "totalCount": 2
    }  
  */
  console.log(metadata)

  /*
    [
      {
        "code": "en",
        "name": "English",
        "local": "English",
        "default": true
      },
      {
        "code": "pt",
        "name": "Portuguese",
        "local": "Português"
      }
    ]
  */
  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.

// Example
api.goToPage(3)

.limitTo(limit)

Defines a maximum number of documents to be retrieved.

// Example
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.

// Example
api.requestFeature('aclv1')

.setSearchQuery(query)

Sets the query to use for a collection search.

// Example
api
  .in('users')
  .setSearchQuery('John')
  .find()

.sortBy(field, order)

Selects a field to sort on and the sort direction. Order defaults to ascending (asc).

// Example
api.sortBy('age', 'desc')

.useFields(fields)

Selects the fields to be returned in the response. Accepts array format.

// Example
api.useFields(['name', 'age'])

.useLanguage(language)

Sets the language to be used when querying. Accepts an ISO 639 language code in string format.

// Example
api.useLanguage('en')

.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.

// Example
api.where({name: 'John Doe'})

.whereClientIs(value)

Applicable when in "client mode". Selects the client with ID equal to value.

// Example
api.inClients().whereClientIs('testClient')

.whereClientIsSelf()

Applicable when in "client mode". Selects the client associated with the bearer token being used.

// Example
api.inClients().whereClientIsSelf()

.whereFieldBeginsWith(field, text)

Filters documents where field begins with text.

// Example
api.whereFieldBeginsWith('name', 'john')

.whereFieldContains(field, text)

Filters documents where field contains text.

// Example
api.whereFieldContains('name', 'john')

.whereFieldDoesNotContain(field, text)

Filters documents field does not contain text.

// Example
api.whereFieldDoesNotContain('name', 'john')

.whereFieldEndsWith(field, text)

Filters documents where field starts with text.

// Example
api.whereFieldEndsWith('name', 'john')

.whereFieldExists(field)

Filters documents that contain a field.

// Example
api.whereFieldExists('name')

.whereFieldDoesNotExist(field)

Filters documents that do not contain a field.

// Example
api.whereFieldDoesNotExist('address')

.whereFieldIsEqualTo(field, value)

Filters documents where field is equal to value.

// Example
api.whereFieldIsEqualTo('age', 53)

.whereFieldIsGreaterThan(field, value)

Filters documents where field is greater than value.

// Example
api.whereFieldIsGreaterThan('age', 18)

.whereFieldIsGreaterThanOrEqualTo(field, value)

Filters documents where field is greater than or equal to value.

// Example
api.whereFieldIsGreaterThanOrEqualTo('age', 19)

.whereFieldIsLessThan(field, value)

Filters documents where field is less than value.

// Example
api.whereFieldIsLessThan('age', 65)

.whereFieldIsLessThanOrEqualTo(field, value)

Filters documents where field is less than or equal to value.

// Example
api.whereFieldIsLessThanOrEqualTo('age', 64)

.whereFieldIsOneOf(field, matches)

Filters documents where the value of field is one of the elements of matches.

// Example
api.whereFieldIsOneOf('name', ['John', 'Jack', 'Peter'])

.whereFieldIsNotEqualTo(field, value)

Filters documents where field is not equal to value.

// Example
api.whereFieldIsEqualTo('age', 53)

.whereFieldIsNotOneOf(field, matches)

Filters documents where the value of field is not one of the elements of matches.

// Example
api.whereFieldIsNotOneOf('name', ['Mark', 'Nathan', 'David'])

.whereHookNameIs(name)

Selects the hook with a given name.

// Example
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.

// Example
api.withComposition()
api.withComposition(true) // same as above
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.

// Example
api.fromEndpoint('custom-endpoint')

.in(collection)

Selects the collection to use.

// Example
api.in('users')

.inClients()

Selects "client mode", meaning filters and terminators will operate on clients and not on documents.

// Example
api.inClients()

.inHooks()

Selects "hook mode", meaning filters and terminators will operate on hooks and not on documents.

// Example
api.inMedia('images')

.inMedia(bucket)

Selects a media bucket to be used.

// Example
api.inMedia('images')

.inProperty(property)

Selects the property to use. Overrides any property defined in the initialisation options, and is reset when called without arguments.

// Example
api.inProperty('test')

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.