Rifiniti was looking to revamp its analytics product and provide its customers with a superior user experience and robust product functionality. Rifiniti has chosen to select a modern technology stack and work with ST6 on implementing it. Rifiniti’s choice for front-end technology was React. There was one critical thing to the client - the newly created and modernized web application (Optimo X) had to be done in approximately 6 months. The ST6 team was to assist from a front-end perspective and offer architectural assessment. Rifiniti’s product and strategy teams were key to providing the deep domain expertise and guidance in order to bring our engineering team up to speed quickly. With the help of ST6, Rifiniti successfully modernized their product!
As the saying goes, when you step into an old car, you realize that the rust isn’t the only problem you have to deal with.
During the discovery phase, we sat down and reviewed the legacy implementation of the Optimo web application. Early in the process, we found some bottlenecks in the present system. The data was consumed via RESTful API which, despite following good practices, required a lot of separate network requests and respectively high latency. Having several more roundtrips doesn’t mean unresponsive design, but the requests were compute-intensive to the servers and the retrieved data interrelated with other requests. All this caused a sluggish user experience masked with loading screens (sometimes for as long as a couple of minutes) even though the only thing the user did was to switch the tabs within the app.
Inspecting these requests suggested that there might be a little more to the application layer than expected.
With the help and collaboration of the back-end team, we collected enough knowledge of the system architecture and data domain, which turned out to be more complex than we initially assumed. Apparently, the front-end wasn’t the only thing that had to be reworked, redesigning the architecture of the back-end was in progress, too. The back-end team was starting to work on a microservice architecture exposing different KPIs as different services where each KPI was a different segment of data. The problem was that some of the KPIs had relations in between, so all services used the same database. On the other hand, the team was composed of only 4 developers and the burden of creating good architecture and coping with the deployment and management of the services didn’t allow them to focus on the implementation. In effect, completely eliminating the advantages of microservice architectures - productivity, speed, flexibility, and autonomy. But most important of all was that the data provided by the services didn’t satisfy the needs of the consumers in this case - the web application and, respectively, the user experience.
Microservices were hype when the Rifiniti’s back-end development started and if you don’t mind the hype, it’s not that difficult to catch a case of Maslow’s hammer syndrome. But always remember: “If you can’t build a well-structured monolith, what makes you think microservices is the answer?”
So having a really small backend team of about 4 developers to cope with Microservice architecture, development and deployment where each microservice would be a different KPI (and there were a lot) doesn’t prove to boost productivity. Furthermore, KPIs were interrelated, shared the same database. I’d like to believe that this decision we took (going for the monolith) was critical for Optimo X’s success and aggressive release target, allowing us to spend more time in the business values the KPI services would bring (and namely the implementation necessary to the web application) and less time on enforcing the best practices for microservices implementation and deployment thus accelerating the time to market of Optimo X.
And finally, we recommended to keep backend technologies that are familiar to the Rifiniti development team and that makes sense in the context of the system design, share knowledge about the newly introduced technologies and apply best practices.
We are big fans of GraphQL and, surely, we are always biased when it comes to selecting the technology and approach for exposing an API, but here, it was obvious from the very first touch that GraphQL is the right way to go. Considering the already discussed pain points that had to be resolved:
- Heavy and frequent network communication causing the user to wait a significant amount of time for almost every action taken
- Combined with the really complex domain data increasing the burden of implementing really RESTful API
We had a limited amount of options. At first sight, the easiest one (especially if you are not familiar with GraphQL) was to implement our own custom API. Although fiat standards can boost productivity for the initial phase of development, they quickly become tedious, unreliable, difficult to port and easy to break which would slow down the development process even more.
Having all these in mind, introducing GraphQL was really easy to reason about:
- Network communication and latency could be reduced by making a single request to the server and querying all and only necessary data, improving the responsiveness of the app and respectively the user experience
- GraphQL is all about data and the relations within, and the data is the API, hence designing the API around the complex domain model comes naturally. This makes our API layer more scalable, portable, reliable and, of course, increases productivity, which all leads to quick iterations and reduced development costs.
- On the other hand, GraphQL and React are practically “made for each other” and developing React Web Apps with GraphQL is much faster and agile which allows quick and progressive rollouts.
Of course, there are always some trade-offs and this case wasn’t much different. Although GraphQL is the standard for many of the biggest players in the space (Facebook, Twitter, Yelp, PayPal, GitHub, and hundreds of other leading tech companies) it still isn’t as recognizable and commonly adopted as the RESTful APIs. The backend team, that already had some limited resources, hadn’t had much experience with GraphQL. In theory, all this could jeopardize the success and on-time release of Optimo X. But even with the noted drawbacks, we had extensive experience with GraphQL and we were sure we could help with providing additional resources for the initial setup and possibly even the development. We were confident that the Rifiniti back-end team would quickly get the grasp of GraphQL and would be able to take full advantage of the noted benefits, and, surely, this was the end result of it.
The complete re-writing of the UI with React was the primary effort. In addition, the Rifiniti team saw that as a good opportunity to take care of some long-standing issues with the navigation and map UX. Since the timeline was so tight, there was an immense effort to achieve an impeccable channel of communication and collaboration between the different stakeholders. The product management team was in Rifiniti’s Boston office, while the project management was in their Bulgarian office. The ST6 team had to collaborate with both offices remotely in order to gain the domain knowledge necessary to deliver the new Optimo X user experience. The product and project managers had deep understanding of the client needs and they provided superbly defined stories, which were crucial to the engineering team’s success.
One of the key features of Optimo, identified by product management, is the ability to generate analysis reports. Generating a report required navigating to 3 different screens to make a selection in order to get a report rendered. This was partly the result of technological restrictions and partly due to the UX choices made when the app was initially built. With the addition of Redux, ST6 was able to store the entire state of the application and achieve a better user experience. The users could now make a selection on a single screen and the results were rendered immediately. Redux allowed us to keep track of every change in the filters or the parameters, automatically reflect them, and generate a new analysis report.
The map used for displaying the results of the analysis report for the selected office spaces (buildings or floors) had to be state of the art. In order to achieve a fluid transition from the map view to the floor plan view, we picked Mapbox as our map solution since it was well-documented and easy to customize right out of the box. Also, it uses OpenStreetMap under the hood and has some flexible pay-as-you-go pricing model. For better integration with React, we decided to take advantage of the react-map-gl library - a nice wrapper for Mapbox GL, created by Uber. In addition, Mapbox has a great track record of adoption amongst the leading tech companies: Facebook, Snapchat, Shopify, Adobe, and more.
We also used Data Clustering to manage a large number of office spaces at different zoom levels based on their office space on the map. The result was an improvement of the overall user workflow when navigating across different floor plans of an office space: the user now had an integrated view of the building in relation to other geographic components (streets, other buildings, etc.).
Utilizing MapBox Layers was an excellent solution which allowed us to provide a superb user experience: users are able to drill-down from the “outside world” to the floor plan of a building. Substantially more user friendly than having modal windows pop up when you try to open a floor plan.
ST6 always looks for ways in which we can help our clients beyond what they think they need. When Rifniti came to us, they wanted to modernize their front-end with a more mature, modern, and future-proof technology. We saw the need for improvements in the back-end, so we not only helped our client solve the front-end challenges but also helped the back-end team implement a new API layer. In addition, Rifiniti expanded their team with new front-end engineers. ST6 successfully handed off the project to the new front-end team, along with the transfer of knowledge needed for the continued evolution of OptimoX.
Rifiniti provided us with a very challenging opportunity to deliver a high quality solution with a limited budget and limited time. We’ve all heard the saying: speed, quality, cost… pick two. I think we managed to allow Rifiniti to pick all three!