From monolithic app to Rails API: decoupling front and back end at Hiring Hub

Upgrading the monolith

At Hiring Hub we are working to upgrade our monolithic rails application to a more modern setup consisting of (at a minimum) a React application front end and a Rails API back end.

After making a substantial amount of headway rebuilding the front end in react – still as part of a monolithic Rails app, and using the react_rails gem to handle the integration with Rails – we have begun to work on migrating our back end to a pure API.

The plan is to have our react components query the API for any required data, instead of using the react_component helper from the react_rails library to pass data through to the components as data attributes on initial load of the page.

Moving away from using the react_component helper to supply data and towards a situation in which data is fetched from an API means that our frontend will be less coupled to Rails, and therefore we will be in a good position to split the application into separate front and back ends, when the time arrives.

Choosing the right API framework

When we took the decision to migrate our backend to a pure API, we also decided to adopt the JSON:API specification, in order to standardise API responses and JSON payloads across our application.

Initially we adopted Netflix’s fast_jsonapi library to provide model serialization into the JSON:API format (which could otherwise be quite cumbersome). In addition we began to use the active-resource library client-side.

The fast_jsonapi library was adequate in many respects. Although it doesn’t provide many exciting features compared to, say, graphiti, it does handle serialization in a simple and easy to understand way.

The main problem we discovered was that the library is quite limited in what it tries to do (admittedly, this might be a an argument in its favour, depending on your needs). It does not, for example, provide any serializers for errors, which is obviously essential functionality for a JSON:API-format application. (We didn’t find a library providing error serialization so rolled our own in the end.) Another issue was that response are only half of what your API deals with: the other being request objects, which arrive in JSON:API format and need to be deserialized.

Client-side we ran into some problems as well. One factor was that active-resource does not handle serialized errors in an obvious way, and furthermore there does not appear to be any documentation for this feature. Another annoyance was that updates to existing resources did not work as expected.

Switching to Graphiti

For these reasons we decided to look elsewhere for a fuller and more developed JSON:API solution. In the end we went with the graphiti gem and associated spraypaint client library,which I hope to discuss in more detail in a follow-up post.

What is Hiring Hub?

Originally published 30th September 2019