We are in the era of micro services, and soon or later, if you are involved in a full stack development, your client application would have to consume various web services in order to deliver the business requirements. With multiple services comes the complexity of handling various data formats, protocols, authentication, etc… Ideally we would like to keep things single responsiblity and thin, but that is not always practical.

If the term ViewModel caught your attention, thats good, but don’t get confused with other framework’s (e.g. WPF, Angular) view model concept and binding. In this post a  ViewModel refers to a data representation that can be consumed by the UI for presentation.

The image below demonstrates a set of possible json responses from different providers for the same information. As you notice, a one letter mismatch in the name of an object key e.g. startTime compared to startime, is enough to push your design in such direction.

Deliverables

We will talk about how to solve the problem in different ways, and I will demonstrate a React-Redux application, Laps Viewer, that is responsible to fetch and view ununified data originating from various web sources. We utilise common patterns, façade & factory in the code design.

Source code is accessible via GitHub (check out the branches).

Design Time

Of course there are many ways to skin the cat. It can be handled on the backend or frontend side. Of course each one has pros and cons, but we dont always have the freedom choosing the best approach i.e. the loosely coupled, extensible, scalable, etc… what we could do though, is get the best of whatever is available to us.

Server side: By putting the facade pattern in action, we could introduce a Gateway API sitting between client side and external/internal services, aka BFF (Backend for frontend).

However, if you dont have the freedom of introducing changes on the server side, you could handle that on the client side.

Client side: The same facade pattern applies here. When data is fetched from a specific source, it will be converted via a factory pattern into a unified data object format that is meaningful to the view. This new object is the view model. The scope of this post is to demonstrate client side solution.

The key benefits of applying such design pattern:

  1. Abstract away the knowledge of different data providers from the presentation layer.
  2. Isolate presentation layer from future changes e.g. support new data providers, or an existing data format requires changing.

Coding Time

Will develop a React-Redux application that fetches racing car laps from different external providers. For the sake of the demo the data will be coming from local json. Different providers pass back different json objects, although they overlap in the information they carry.

If you already had peeked the source code, you must have noticed the two approaches of creating view models of the lap gateway reducer (each one on a branch). On both approaches we have one high level gateway action dispatcher that delegates data fetching to specific implementation. As a point of extension in the code design we still need to have the specific implementation of action & reducer for each service.

Actions

Reducers

Based on the image above, we still implement independent reducers per service plus the gateway reducer in order to preserve the canonical data.

1. On-the-Fly

Every time a connection ReactComponent call the BFF selector, the selector gets the data from request reducer then calls a factory method that knows how to convert data to ViewModels. Use this approach if data conversion is cheap, and data get stale relatively fast.

TIP: For further optmisation, its worth looking at memoising, using reselect library.

2. One-off

This approach is the more optimised in terms of performance. This is achieved by converting data to view models as soon as it hits the arrival reducer. This means there are at least two reducers listening to the same action type; the one related to service and the gateway laps reducer. Next is a simple implentation where the BFF reducer holds laps view models from the selected service.

ViewModel Factory

Lastly, we put the factory method pattern in action to produce the unified viewmodel that the UI is capable to display from various data structures.

Leave a Reply

Your email address will not be published. Required fields are marked *