Front end development boundary in a Rails app

During my recent trip to our Vancouver office, our frontend developers think if we have more Rails developers building backend APIs, the frontend development works could go swifter and faster.

I conducted a team learning session on this topic. I talked about the font end development boundary and how far we can push the frontend work without any help from the server end. The final take away is that with some preparation and simple technics, it is possible to build an entire React frontend app without any server end APIs. Once the server end APIs are in place, we would only need to touch a couple of places at max, to “turn on” the frontend React app to be production ready.

Let’s talk about the boundary between frontend and backend first. React with Flux gives us an easy to understand uni-directional data flow. We know our React app should be fully functional as long as we have “data” in our store. All this means is that our store should be the boundary between our React app and the server APIs. As long as our store is the only place that cares about retrieving and persisting data, once the store emits changes, other parts of our React app should just work! React with flux makes defining the boundary super easy. I still remember in the old days with hand-rolled JS frontend apps, this defining boundary business takes a lot more consideration and discipline. Not so much these days!!!

Now knowing the boundary. What are the technics we could use to make our React app behave as if it is connected to the backend APIs? The answer is easy: FAKE IT.

Take a look at data retrieval for example. In a React store, we typically retrieve data like this

class DummyStore extends EventEmitter {
  // many lines left out
  loadServerData() {
    const url = Envisio.Js.Routes.dummy_data_path();
    Ajax.get(url, (data) => {
      this.setData(data); // setData calls this.emitChange();
    });
  }
  // many lines left out
}

Dispatcher.register((payload) => {
  switch (payload.type) {
    case Constants.DUMMY.LOAD_DATA:
      DummyStore.loadServerData();
      break;

    // many lines left out
  }
});

The only interesting part is the Ajax.get with the callback lines. We have a couple of things need to fake here. First, we need to be able to get some fake data, which we can pass to this.setData(). Second, we need to make sure we fake the async nature of the Ajax.get call. We are looking at something like below

  loadServerData() {
    // const url = Envisio.Js.Routes.dummy_data_path();
    // Ajax.get(url, (data) => {
    //   this.setData(data); // setData calls this.emitChange();
    // });
    setTimeout(()=> {
      const fakeData = FixtureDataFactory.getDummyData();

      this.setData(fakeData);
    }, 1);
  }

The Ajax.get call is replaced by setTimeout, which is async. In order to pass fake data to this.setData, we created a FixtureDataFactory class with a getDummyData method. The getDummyData method is super simple. It just returns some fixture JSON data.

The above technics are very simple, but very effective and has some awesome side effects.

  • The use of setTimeout to simulate async behaviour means once we switch to the real Ajax.get, all React components’ lifecycle calls will not be upset. It’ll be an async to async switch. Nothing should care, nothing should change.
  • The introduction of FixtureDataFactory means 2 things. First, FixtureDataFactory will be used to provide fixture data for our tests. Second, the JSON data returned by getDummyData is an easy to read contract between the frontend app and the backend APIs. Backend API developers should be able to take the fixture JSON data and write the API accordingly. Easy job!
Published: 2016-05-24
blog comments powered by Disqus