Redux and JSON Schema - Two great tastes that go great together

By
Sam Gentle
September 19, 2016

At Prismatik we’re big fans of JSON Schema, a system for describing and validating JSON in JSON. In this post, I’m going to describe why we use JSON Schema, how we use it together with Redux, and how you can do it too.

JSON Schema


Behold, the Ouroboros!

JSON Schema is a standard that’s been getting a fair bit of attention lately, and for good reason. It gives you a neat way to specify the shape and structure of your data. You can use it for validation, you can use it to generate documentation, and because it’s all just JSON, you can pass the same schema from server to API to client and back.

The standard is pretty daunting to read, but the schemas themselves can be quite simple. The best place to start is Understanding JSON Schema by the Space Telescope Science Institute, especially the basics page.

I know, I know, the web is all about being schemaless and unstructured. But at a certain point when you have a large application in production and lots of people depending on it, that stops being enough.

The truth is that your data has a schema whether you write it down or not. The only question is whether you’ve specified it in a single place, or scattered that definition throughout different bits of logic in your application code.

The flexibility of being schemaless can be great for rapid development, or getting that prototype out the door, but it really comes back to haunt you when you have ten different modules with slightly different interpretations of how your data is structured.

Even more traditional schemas have this issue. You have one specification in your database, another in your server-side logic, another in your API, another in your client code… ugh. In its own paradoxical way, the rise of schemaless databases and untyped application code on the web actually makes this problem easier to solve, because it leaves the validation up to you.

With a JSON document database (like MongoDB, CouchDB or RethinkDB), NodeJS on the server, JSON APIs, and Javascript on the client, chances are your data is JSON all the way through. JSON is the language of the web, and that makes JSON Schema the specification language of the reliable web.

Redux

This now-obsolete model of the atom, used in the logos of many popular Javascript projects, is a subtle reminder that even physicists had to deal with framework churn [wikicommons]


Once “check your JSON” is in the back of your head, opportunities show up in all sorts of places. One that we noticed early on is Redux.

Redux is a popular Javascript framework, often used together with React, that allows you to model all the state in your web application as one big tree that can only be modified by simple, deterministic code. And by tree, I of course mean a Javascript object. One that’s just crying out for a JSON Schema.

The beauty of this approach is that, in a well-designed React/Redux app, everything goes through your state tree. Structured data from the server, the ephemeral data in your UI, even navigation in the app. That means that if invalid data appears somewhere, it must have come through your state tree first.

Checking the validity of your state tree, then, is checking the validity of your entire application. Obviously, you can still have bugs in your logic or UI, but you’d be surprised how many are caught by schema checking your application state.

Unfortunately, although there is a great and emerging ecosystem around JSON Schema, there’s nothing that specifically addresses this use case. You can already validate data using the blazing-fast Ajv library, generate documentation with prmd or docson, even turn schemas into forms using react-jsonschema-form.

A prepackaged Redux JSON Schema validator seems like a logical next step.

Redux + JSON Schema

This friendly octopus tried to save the sinking ship, but without opposable thumbs there was little it could do

So that’s exactly what we built: a library called redux-json-schema that makes it super easy to add JSON Schema validation to Redux.

You just install it:

npm install --save-dev redux-json-schema

And then you can wrap any reducer like so:

// inside reducers/todos.js
import createValidatedReducer from 'redux-json-schema';
import schema from '../schemas/todos.json';// function todoReducer(state = initialState, action) ...export default createValidatedReducer(todoReducer, schema);

Or, since any reducer is just a composition of more reducers, you can apply it to your root reducer and have a schema for your whole application:

import createValidatedReducer from 'redux-json-schema';
import schema from '../schemas/app.json';//const store = createStore(rootReducer, preloadedState); // Old
const store = createStore(
 createValidatedReducer(rootReducer, schema),
 preloadedState
); // New

Now any time that reducer would leave the store in an invalid state, it instead throws a SchemaValidationError with a message telling you what went wrong:

You can find more details and advanced usage on the Github page, or check out this fork of Redux’s todomvc example. The commit history shows all the steps necessary to set up schema checking in an example project.

This library is in its early days, but it’s based on code we’ve been using internally. There are some plans for future improvements including ImmutableJS support and caching, but we’re committed to the open source process and very happy to receive pull requests, bug reports or feature suggestions.

JSON Schema is something we’ve found very useful, and I hope it will prove useful to you in the quest for more reliable and predictable software on the web.


Related Posts