Push-based Architectures with RxJS
For years, you have been programming wrong!

Push-based Architectures with RxJS

Before I can show you HOW to implement Push-Based architectures, I need to first describe WHY Pull-Based solutions are flawed… and WHY Push-Basedsystems are better.

Most developers learn to program, code, and build software architectures using traditional Pull-based approaches. In the world of web applications and asynchronous, rich user experiences this approach is flawed, rampant with myriad problems, and is fundamentally wrong.


Traditional Pull-Based Solutions

With Pull-based architecture, the views will explicitly call service methods to force-reload (aka ‘pull’) the data. This is the traditional approach employed by most developers.

No alt text provided for this image

Consider the simple function call findAllUsers() used to retrieve a list of users… here the code is pulling data to a view. If the user list subsequently changes, views (or services) must issue another pull request with findAllUsers(). But how do the views know when to issue another request?

Notice I have not stated whether the data is currently in-memory or must be retrieved from the server. Nor have I asserted that the pull request is  synchronous  or  asynchronous.
Those aspects are irrelevant here since this is still a  pull-based approach.
No alt text provided for this image

Now it is reasonable to load data or change data asynchronously… using async/await or Promises. Developers may even build a temporary 1-response Observable [like HttpClient] to access remote data.

No alt text provided for this image

But those data request are still a single, 1-x pull-request. And Observables used this way are consider temporary streams; discarded after use/completion.

To design our system for long-term data flows, we could provide notification callbacks or even using polling (AngularJS digest cycle). These quickly become messy and [in some cases] even present performance issues.

And if our data is shared between multiple views then other HUGE architectural concerns must be considered:

  • “How do 1…n views know when the data is updated?”
  • “How do unrelated views get notified that new data is available?”
  • “Should uncoupled view components poll for updated data?”
  • “Why is my shared data changing? Who is changing the data when?”

Push-Based Architectures

So how do we invert the paradigm and change our coding to use Push-basedsolutions and architectures?

No alt text provided for this image

With RxJS and long-lived Observable streams, developers can implement architectures that PUSH data changes to all subscribers.

Views simply subscribe to desired data streams. When the datasource changes that desired data will be auto-pushed through the specified stream [to 1…n subscribing, interested view components].

No alt text provided for this image
This approach to using permanent streams to push-data is a fundamental, HUGE paradigm shift from traditional pull-based architectures.

Benefits

What are the benefits of designing and using Push-based architectures?

  • State Management
  • Immutability
  • Performance
  • Reactive Views

State Management

With Push-based services, direct data access is prohibited. The true source of data is maintained within a virtual vault. The service itself provides an APIthat is intended to be used by the view layer.

Each Push-based service API has:

  • Properties: streams that will deliver data whenever that data changes.
  • Methods: to request changes to the data or request specific custom streams

The actual raw data is only available after it has been pushed through the stream(s).

This protected isolation centralizes all change management and business logic within the service itself and forces view components to simply react passively to incoming pushed-data.

Immutability

With Push-based services, data (aka state) is always immutable. This effectively means that the data is read-only. Changes to the inside properties are not allowed.

Below is an example of pagination state and how developers would update an immutable object:

No alt text provided for this image
When an immutable object needs to be modified then that object is cloned to a new instance with the desired properties/fields updated. After construction this object is also considered  immutable.

With immutable, data change-detection using deep comparisons is not needed!

To detect changes, comparisons simply use === to determine if the data reference is a new instance. And when changes are detected, then the changed data is re-delivered through the streams to any subscribers.

Immutability == fast change-detection == fast performance.

Reactive Views

With Push-based services that deliver data only through streams, developers are encouraged to create applications composed of passive view components. But what are passive views?

  • Views that only render when the data arrives via a push-stream.
  • Views that delegate user interactions to a non-view layer
  • Views that require no business-logic testing
  • Views that require minimal isolated UX testing

With Push-based services, Angular view components that are highly performant use both ChangeDetectionStrategy.OnPush and the async pipe with data delivered via streams.

There are advanced patterns such as Redux or NgRx (etc) that provide all these features and more . We can, however, simply use RxJS and still build elegant, performant  push-based solutions.

These concepts and issues impact developers in ALL technology platforms and frameworks and have huge impacts on developers of web applications. Whether the web app developer uses Angular, React, Vue.js, or another framework… Pull vs Push architectures affect everyone.

In the subsequent sections, let’s dive into Angular code to explore the concepts.

Code Labs

In the following sections, let’s first build a simple pull-based service. Afterwards, we will then convert that same service into an elegant push-based service.

Surprisingly, we will discover that our choice of Push-based or Pull-based architectures affects the UX. Push-based applications feel smoother and more intuitive. We will see this in the labs below…

For the code labs and live demos, go to my full Medium post here: https://bit.ly/2wu24ao

要查看或添加评论,请登录

Thomas Burleson的更多文章

  • Leverage your Git Code Reviews

    Leverage your Git Code Reviews

    During the last few years, I have provided Pull Request code reviews for many FE engineers at Degreed.com.

  • Essence of RxJS

    Essence of RxJS

    RxJS is a great solution and pattern for managing streams of async data emissions. We learn to use operators to…

    1 条评论
  • Universal Dependency Injection

    Universal Dependency Injection

    Dependency injection is a solution in which a system supplies a target 1…n dependencies from external sources; rather…

  • Angular: You may not need NgRx!

    Angular: You may not need NgRx!

    You may not need to use NgRx in your application. But you should use Facades in your application! Let’s explore why…

    2 条评论

社区洞察

其他会员也浏览了