Cerebral with JSON Schema

Post by Saul Shanabrook

Problem

For this stage lighting control system I am making, I send my whole state back and forth from client to server on every update. This might seem insane, but it makes sense for my use case. In this great talk on Falcor, Jafar Husain says something like "What we would really like is to push the whole database to the client on every load. However that would take too long." Luckily for me, my database is very small, so this is doable.

The point is that I have a big JSON tree flying back and forth between a backend in Go and a frontend in Javascript. One of the problems with this is the lack of data verification. Both server and client should be able to make sure they aren't putting incorrect data into the tree.

Solution

Luckily, we have a standard for that, called JSON Schema. There are loaders written in most languages.

In the frontend, I am using Cerebral with baobab. I can use baobab's validate config to pass in a function that validates the tree based on the JSON schema.

My controller.js file looks like this:

import Controller from 'cerebral'  
import Model from 'cerebral-baobab'  
import signals from './signals'  
import schema from './schema'  
import state from './state'

const baobabOptions = {  
  asynchronous: false,
  validate: (previousState, newState, affectedPaths) => {
    var valid = schema(newState.synced)
    if (!valid) {
      console.error('Invalid schema', newState, schema.errors)
      return new Error(schema.errors)
    }
    return true
  }
}

const model = Model(state, baobabOptions)  
const services = {}  
var controller = Controller(model, services)  
signals(controller)  
export default controller  

Then in the schema.js file I just compile my schema with AJV:

import Ajv from 'ajv'  
import schema from '../../api/schema.json'

export default Ajv().compile(schema)