feathers-versions

0.2.1 • Public • Published

Feathers Versions

ALPHA VERSION DOCUMENTATION

If you're reading this, feathers-versions is in alpha, and not all of the functionality is fully described or finalized.


Why?

  • You're using feathers.js serverside, and you'd like to save versions of service documents.
  • You love your family.

QuickStart

The following assumes you're familiar with feathers.js workflow. If you've never heard of feathers.js before, it's great. Learn it: feathers.js

Install

npm install feathers-versions

Set Up Versions Service

import feathers from 'feathers'
import hooks from 'feathers-hooks'
import versions from 'feathers-versions'
 
//set up a quick app that will allow you to create documents server side
const app = feathers()
  .configure(hooks())
 
  //calling versions without any arguments gives the default configuration
  .configure(versions())

Set up a Service that will use Versioning

Once the version service has been set up, you need to add a couple of hooks to any service that you want to use versions.

The addVersion hook can only be placed as after patch, create and update hooks, and typically you'd want them on all three.

The clearVersions can only be placed as a after remove hook.

 
import { addVersion, clearVersions } from 'feathers-hooks'
import memory from 'feathers-memory'
 
const articles = app
  //for the sake of example, we'll set up an in memory service
  .use('articles', memory())
  .service('articles')
 
//configure your add and clear hooks
const add = addVersion({
  excludeMask: ['id'] //we don't need to save the id for every version.
})
const clear = clearVersions()
 
//apply the hooks to the articles service.
articles.hooks({
  after: {
     //we'll want to add a version whenever a document is patched, created or updated.
    patch: add,
    create: add,
    update: add,
    //and we'll want to remove versions when a document is deleted.
    remove: clear
  }
})

Create a Document

That's it! Now, when you create or edit article documents, they'll have versions saved on the version service.

articles.create({ body: 'I hate sandwhiches!', author: 'James McSoup' })
  .then( article => {
 
    const query = { document: article.id, service: 'articles' }
 
    //get the version for it
    return app.service('versions').find({ query })
  })
  .then( versions => {
    const version = versions[0]
 
    console.log(version)
 
    //A version document in this case would have the following structure:
    {
      id: 0, // id of version document
      document: 0, // id of article document
      list: //each of the saved versions, from earliest to latest
        [{
          saved: Date, //when the version was saved
          user: null,  //if there was a user entity associated with the call, this would be that users id
          data: { body: 'I love sandwhiches!', author: 'James McSoup'} // the actual data of the saved version
        }]
    }
  })
 

Service Configuration

The service configuration comes with a couple of options, most importantly the adapter field:

idType and adapter

If you don't provide a a database adapter, feathers-versions will use feathers-memory by default, which probably won't be very useful.

idType is the constructor for the dataType that your id will be in. Number by default. This is important to set if you are using service adapters that don't user strings or numbers as ids, like mongodb.

To set the versions service to use mongodb:

import feathers from 'feathers'
import MongoService from 'feathers-mongodb'
import { ObjectId, MongoClient } from 'mongodb'
import hooks from 'feathers-hooks'
import versions from 'feathers-versions'
 
import MONGO_DB_URL from './mongo-db-url'
 
//once again, create an app that will allow you to create documents server-side
const app = feathers()
  .configure(hooks())
 
MongoClient.connect(MONGO_DB_URL)
  .then(db => {
 
    //create your mongo adapter
    const adapter = new MongoService({
      Model: db.collection('versions')
    })
 
    //configure your versions service. It's important to set idType to ObjectId, here
    app.configure(versions({
      idType: ObjectId,
      adapter
    }))
 
  })
 

serviceName

By default, the service name for the versions service will simply be versions. If you'd like it to be something else, set this option:

import feathers from 'feathers'
import hooks from 'feathers-hooks'
import versions from 'feathers-versions'
 
const app = feathers()
  .configure(hooks())
  .configure(versions({
    serviceName: 'history'
  }))
 
//ta daa
const historyService = app.service('history')

userEntityField and userIdField

These fields are used for getting a authenticated user object. If a user patches an document that uses versioning, feathers-versions will save that users id with the version data.

By default userEntityField is user and userIdField is _id


addVersion Hook Configuration

There are a couple of options when adding version hooks to documents:

limit

A limit to how many versions can be stored. If the limit is reached, the oldest versions will be deleted to make room for new ones. Default is 1000.

saveInterval

If set, saveInteval should be a number in milliseconds. New versions added in less than the set number of milliseconds will be collapsed together. This is so that if multiple changes are made frequently, they'll be considered one version. By default, a version will be created with every patch or update.

excludeMask and includeMask

You should set EITHER excludeMask or includeMask, not both, and they should be an array of strings, representing field names.

These fields will mask the data that gets saved to a version, so that redundant fields are ignored.


clearVersions Hook Configuration

The clearVersions hook currently receives no configuration.


getVersion helper method.

feathers-versions also exports a helper method called getVersion

It simplifies getting the version data for a specific document.

 
import { getVersion } from 'feathers-versions'
import app from './app' // assume we have a properly set up app here
 
void async function test () {
 
  const articles = app.service('articles')
 
  const doc = await articles.create({ body: 'Informed opinion.', author: 'Some Guy' })
 
  let docVersions
  docVersions = await getVersion(app, 'articles', doc.id)
  // OR, getVersion can also be bound to app for readability
  docVersions = await app::getVersion('articles', doc.id)
 
  console.log(docVersions) /*
  {
    id: 0,
    document: 0,
    service: 'articles',
    list: [{
      user: null,
      updated: [Date],
      data: { body: 'Informed opinion.', author: 'Some Guy' }
    }]
 
  }
  */
}
 
 
 

Further Considerations

  • New versions will not be created if none of the masked data has been changed.

Package Sidebar

Install

npm i feathers-versions

Weekly Downloads

0

Version

0.2.1

License

ISC

Unpacked Size

36 kB

Total Files

13

Last publish

Collaborators

  • benzed