question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Implement a Redux architecture in Syndesis UI

See original GitHub issue

In order to make state management easier in Syndesis UI, while reducing the code boilerplate existing on each component to handle state and digest data back to the data layers on each UI interaction, embracing an architectural pattern such as Redux seems the way to go. This would allow for leaner component and service implementations, less code and a centralized source of truth for all things that impact the overall application state.

After reviewing the entire codebase, I finally managed to come up with a plan for implementing Redux-driven stores in the application, leveraging the excellent @ngrx library (another monorepo, yay!), which has become a de-facto standard in the Angular arena. My major concerns here were, bearing in mind that this is a live application that we still need to grow and maintain in the interim, and that most of those changes tap into architectural calls, how to make everything work while we keep building other features and no feature toggles support is available. The idea would be to build the foundation for Redux in a way that operates in parallel to the rest of the app and then go switching the state implementation for each group of component groups, one group at a time. I figured out the steps required and put them together in an issues list named The Path to a Redux Architecture, (yes, it’s a cheesy name and I’ll burn in hell for the rest of my life because of this).

The Path to a Redux Architecture (15 issues)

  1. Build our own HttpClient wrapper + tests
  2. Strip WebSocket Client implementation out from store/entity/events.service to its own service provider + tests
  3. Strip EventSource Client implementation out from store/entity/events.service to its own service provider + tests
  4. Implement EventServiceFactory wrapping our new WebSocketService and EventSourceService and expose it as an Observable events emitter from @syndesis/ui/core (read below about @syndesis/ui packages)
  5. Implement support for @ngrx v4.* plus Side Effect Events modeller and Store Dev Tools.
  6. Port ACTIONS state management to a local store, managed by a set of typed Actions handled by reducers.
  7. Wire all events emitted by EventService and all HTTP calls required by ACTIONS into streams piped to middleware Effects triggering Redux actions.
  8. Hook up all ACTIONS components with data selectors pointing to the Store. Bind UI events to action dispatchers.
  9. Repeat the above steps with CONNECTIONS
  10. Repeat the above steps with CONNECTORS
  11. Repeat the above steps with ENTITIES
  12. Repeat the above steps with INTEGRATIONS
  13. Repeat the above steps with OAuth USER GRAPH
  14. Phase out Restangular in favor of our own HttpClient wrapper
  15. Phase out all entities in src/app/store in favor of our new implementations for Effects-driven HTTP calls

While this is pretty ideal, problem is that Redux requires A LOT of new files to be created per each entity, and in order to swap references later seamlessly we need a better project layout in regards of filesystem design, folder names and locations, etc. I also need a better tooling to track down errors and debug stuff and this makes a good case to centralize settings ina centralized service so we can strip URLs and stuff out from services and components. So I put together all the steps required and defined a set of packages that will summarize the application architecture, just by embracing the industry conventions for large Angular applications. For the record, this is not a big application, but it will likely become one upon time. Once this architecture is implemented, the different packages will allow for better refactoring operations and will help repurposing our components’ data implementation more easily. The resulting to-do list looks as follows:

The Path to an Angular 5/6 Architecture (12 Issues)

  1. Upgrade Angular to v5.x and Angular CLI to v1.5.x
  2. Create @syndesis/ui/* alias as a symlink to ui/src/app/* to better manage code refactorings and module reshuffling based on façades (this is done from tsconfig.json).
  3. Wrap aplication models, Redux constructs (when available) and abstract service classes into separate contexts exposed from @syndesis/ui/platform
  4. Wrap common-use components, directives and pipes in a new SharedModule exposed from @syndesis/ui/shared
  5. Wrap application-wide service providers mapped to platform abstract service classes into new CoreModule exposed from @syndesis/ui/core
  6. Move connections, customizations, dashboard, integrations, settings (and templates?) to @syndesis/ui/web
  7. Remove hardcoded references to services/URLs/ENV variable and expose it from a centralized settings service in exposed from @syndesis/ui/core
  8. Implement custom global application error handler wired to Angular’s ErrorHandler provider
  9. Wrap vendor libraries in @syndesis/ui/vendor abstracting their APIs through our own façade (mostly logging operations).
  10. Introduce yarn DEBUG MODE command and log messages in console when triggered. Do not log anything otherwise
  11. Rename files and folders according to Angular’s Official Styleguide
  12. OPTIONAL - Transition from Angular CLI to Webpack v3 + Rollup w/ AOT compilation support.

Summary

The idea here is to port the application to a proper Angular 5/6 environment first and then implement Redux afterwards, as a follow up EPIC.

Just to summarize, this is the final set of packages proposed:

  • @syndesis/ui/platform: Application model types, abstract services, Redux entities (when available), and routing guards.
  • @syndesis/ui/core: Actual implementations of platform abstract services as injectable providers.
  • @syndesis/ui/shared: Application shared components, directives and pipes, consumed from all routed modules, lazy loaded or not. Additionally, we will expose here all static functions such as application helpers and TypeScript decorators.
  • @syndesis/ui/web: All our UI components, grouped by contexts exposing a routed feature module each.
  • @syndesis/ui/vendor: All our 3rd party libraries, plus our own façade services for them,
  • @syndesis/ui/debug: Initially a no-op NgModule, but a future home for debug components and directives, and feature toggles.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:10 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
deelemancommented, Jan 10, 2018

Done!

1reaction
gashcrumbcommented, Nov 17, 2017

Create @syndesis/ui/* alias as a symlink to ui/src/app/* to better manage code refactorings and module reshuffling based on façades (this is done from tsconfig.json).

Good thing I moved off of Windows, I think this should be okay 😃

Wrap vendor libraries in @syndesis/ui/vendor abstracting their APIs through our own façade (mostly logging operations).

I definitely like the idea behind this one. Would we do this for third-party components or just APIs? The main one I have in mind is the dynamic forms library, we use the API from that. And then there’s ng-patternfly which has components that we use and some API services, would we facade that stuff too?

Introduce yarn DEBUG MODE command and log messages in console when triggered. Do not log anything otherwise

+1 and I’m actually not a fan of our current logger, I kinda want something that’s as easy to use as console.log

Read more comments on GitHub >

github_iconTop Results From Across the Web

Designing a Scalable Redux Architecture for Large Scale ...
Adding Redux to your react application is not difficult. However, how to structure redux well to fit your application is a big problem....
Read more >
The best way to architect your Redux app - freeCodeCamp
There are four stages to building a Redux app: Visualise the state tree; Design your reducers; Implement Actions; Implement Presentation. Step 1 ...
Read more >
Import/Export Additional Features · Issue #333 - GitHub
Create UX interaction design to support exporting integrations/connections from an environment and importing them into another environment.
Read more >
Building a scalable User Interface using React and Redux
Enter Redux.​​ Redux provides a JavaScript object, along with a few useful methods called a store which is like a state tree for...
Read more >
Modular Redux - a Design Pattern for Mastering Scalable ...
If a component doesn't directly use or update shared state, it shouldn't be dependent on it. To see how apply modular design principles...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found