Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 21 Next »

Overview

This document outlines the OpenLMIS-UI v7 architecture, which is being introduced to avoid AngularJS paradigms that make extending the OpenLMIS-UI difficult. The OpenLMIS-UI is a URL driven application with a modular architecture that allows implementers to modify workflows and logic to meet their communities needs. During the development of OpenLMIS v3.2.1, a need for a more explicit application architecture is needed to keep application components decoupled so modifications by implementers can be more easily maintained. The extensions developed by OpenLMIS Malawi implementation have shown flaws in the AngularJS-based application architecture.

The v7 architecture aims to improve the following issues that have become problematic in the OpenLMIS-UI as of OpenLMIS v3.2.1:

  • Brittle business logic
    Much of the business logic in the OpenLMIS-UI is implemented without a layered application architecture, which has made documenting and debugging the OpenLMIS-UI harder as the application has grown. The OpenLMIS-UI v7 architecture introduces a layered application architecture to formalize a separation between domain objects, UI route configurations, and a component driven design.
  • Configuration-heavy controllers
    Controllers are used to pass variables defined in the URL state to the HTML view — many of these controllers are hundreds of lines long, but don't improve code clarity or add logic to the HTML view. During the development of OpenLMIS v3.1, we found controllers difficult to extend in maintainable ways. The v7 architecture will avoid controllers entirely.
  • Tightly-coupled views: HTML is complex and often contains business logic
    HTML in the OpenLMIS-UI has become increasingly complex, as many pieces of HTML implement business logic. A best practice is to keep HTML as simple as possible, since HTML is difficult to unit test and much harder for an implementer to extend.
  • Too many singletons
    AngularJS creates lots of singletons, which are single objects persisted in memory while the UI is running in the web browser. Singletons in the AngularJS framework are often the cause of memory leaks and other performance bugs in large AngularJS applications. The OpenLMIS-UI v7 architecture will use plain javascript objects, written in modern Javascript, which will make the logic defined in the UI more reusable in other Javascript applications.  

Architecture

Below is a high level description of the v7 architecture, with a description of how and why the application behaves differently than the AngularJS-based OpenLMIS-UI that was deployed as part of OpenLMIS 3.2.1

Note: Many of the concepts in the v7 architecture are similar to OpenLMIS-UI at v3.2.1, the largest differences are in how the concepts interact. 

Router Moderated Architecture

In a URL-Driven application every screen is directly accessible by a URL, which is moderated by a "router" that loads data into the application state and renders HTML templates. Angular-UI Router provided a great start for an application, but as complexity in the OpenLMIS-UI has grown, configuring UI routes has become verbose and error prone.

To solve these issues, we are going to wrap Angular-UI Router in a way that will force presentation and business logic to be separate. The goal is to create a route registry that implements a facade pattern, such that routes are primarily responsible for loading objects into the application's current state. This way routes can focus on configuration, not presentation.

  • Page transitions only in route files — we don't want HTML or other layers to be responsible for directly showing a modal
  • Auto-inject resolved objects into view state — which will remove the need for verbose controller files, which generally just contain configuration

OpenLMIS Layout Service

OpenLMIS router states will be able to express presentational needs by adding key/value pairs to the route configuration. The route configuration will be interpreted by a completely separate layout system, which can be changed or evolve separately from the business logic. This will allow implementers to create large UI layout changes with minimal code.

  • HTML templates rendered by route files will not contain "wrapper" elements — these will be provided by the layout service
  • Allows developers to set default layouts, that can be globally overwritten by developers.

Layered Architecture

In the OpenLMIS-UI, we try to keep each module focused on a single application function. Yet, in OpenLMIS v3.2.1, a module would be responsible for providing HTML for a view and sending/receiving HTTP requests — which is a bad practice in that it makes debugging difficult, and extendability much more fragile.

Our solution is to adopt a layered architecture, which will consist of:

  • Infrastructure layer that interacts with local databases and external services
  • Domain layer that organizes business logic around domain objects
  • Application layer that combines infrastructure and domain layers with UI specific workflow requirements
  • Router layer where routes and simple HTML are configured to display domain object
  • Components layer where simple HTML is transformed into richer interactive experiences

Domain Objects

Currently the OpenLMIS-UI implements logic that is structured around resourceServices that closely map to OpenLMIS Services. This has lead to repeated code with complicated methods. Javascript objects recieved from an OpenLMIS Service are directly passed to route and component level modules, which makes reasoning about the current behavior of a screen difficult. There are many cases where implementation logic is difficult to follow because of how objects are mutated and passed between services.

Articulating a domain layer in an application will help avoid these pitfalls by encouraging a clear object oriented style that is expressed in HTML — rather than convoluted methods that can implement business logic.

  • No labels