Wednesday 6 July 2016

Reactive Programming Part 2: Building a reactive auction site

In the previous post, we were introduced to the basic concepts of reactive programming. In this part, we will cover prototyping a real time auction application using some of the reactive programming concepts and the toolset listed above. The application will support:
  • Setup an auction with basic attributes such as title, initial price, and the product id
  • The live auctions be viewed and an user can bid for the item if the user is logged in.
but will not support: client side validation on forms, reporting highest bid, security rules.

We are going to use Google Firebase (https://firebase.google.com)  as our backend.  The Firebase Real-time Database is a cloud-hosted database where Data is stored as JSON and synchronised in real-time to every connected client. Although the technology is still evolving, it is a fantastic tool for prototyping reactive behaviour and building highly collaborative event driven applications.

The data model:

First let us define a model for our auction data. It will be a JSON list of auction objects. However, instead of nesting bids within the auction object, we will have a separate node of bids with child nodes as auction object. This relatively flat structure makes it easy and fast to search and index objects later on.

{   
  "auctions" : {   
   "auctionkey1" : {   
   "prodId" : "2",   
   "startingBid" : 1,   
   "title" : "auction 1"   
   },   
   "auctionkey2" : {   
   "prodId" : "2",   
   "startingBid" : 1,   
   "title" : "auction 2"   
   }  
  },   
  "bids" : {   
   "auctionkey1" : {   
   "bidkey1" : {   
    "price" : "10.01",   
    "userid" : "user1"   
   },   
   "bidkey2" : {   
    "price" : "10.02",   
    "userid" : "user2"   
   }  
   }   
  }   
}   

Landing Page and Navigation

Next we setup the landing page (app.component.ts) which is a simple nav bar with a content placeholder in which the single page application will load content based on the route configuration in app.routes.ts. The template for the landing page is shown below with navigations that are defined in app.routes.ts.


app.component.html
The template for the landing page page is shown below. It uses navigation routes that are defined in app.routes.ts.


app.routes.ts
The default route will load the AuctionsComponent that will display the list of auctions. Actions are setup in the AuctionsFormComponent.


app.component.ts
For authentication, we will use firebasese authentication provider that supports various social network authentications in addition to email/password authentication. For the purpose of this project, I have implemented only Google authentication. Also, the firebase provides a defaultFirebaseConfig object that can be bootstrapped into the AppComponent via main.ts.

Setting up a new auction


auction-form.component.html
The auction form template is setup as a model driven form template.

auction-form.component.ts
The form's DOM elements are bound to the view model via form controls. Controls can be seen as proxy objects to the DOM elements. A Control can be bound to an input element, and takes 3 arguments (all optional); a default value, a validator and a asynchronous validator. Controls can be grouped together within a controlgroup. The state of the form is available  through the control objects within the control group but in this case we are also using the [(ngModel)] binding to bind the form to a model object in AuctionFormComponent. This is not advisable but as the duality of state access may cause some confusion but some may prefer the less verbose approach of the ngModel.



auction.service.ts
The AuctionFormComponent uses a service component to create an auction node in the firebase server. The angularfire reference object gets injected into the service component by angular within the constructor of the service. The getProducts() call returns a dummy list of product. Alternatively, instead of createAuction, you could bind to an observable array representing the auctions node and push directly new auction data onto the Observable array using the 3-way binding of the Angular Fire2 framework. This concept is used in the auction listing and bidding user story as we will see in the next session.

Listing auction items and bidding

Before we get into the implementation of auction lists, we should familiarize ourselves with a couple of key concepts related to using firebase as a real-time datastore.

3-way binding

2-way binding (model to view synchronisation) is a well-known concept.  However, angularfire offers 3-way synchronisation which is the view to model to database synchronisation. Push changes on to the synchronised object and now any changes in the DOM are pushed to Angular, and then automatically to our database. And inversely, any changes on the server get pushed into Angular and straight to the DOM.

Concurrent writes

If a user adds a new bid it could be stored as /bids/auction/2. This would work if only a single user were adding auctions or bids, but in our real time auctions application many users may bid at the same time. If two bid simultaneously, then one of the bids would be deleted by the other. To handle this, Firebase provides a push() function that generates a unique key every time a new child is added. By using unique keys names for each new element in the list, several clients can add children to the same location at the same time without worrying about write conflicts. The unique ID generated by push is based on a timestamp, so list items will automatically be ordered chronologically.



We can see these concepts in play in the auctions listing and bidding component.

auctions.component.html
The auction listing template has ngFor loop that iterates over the auctions observables array. The async pipe unwraps the each item in the auctions observable as they arrive. The product images are stock images picked from the lorempixel images site indexed to the product id within the auction object. Any selected auction is highlighted and the selectedAuction property is set to the currently selected item in the list and you can then bid on the item.



auction.component.ts
The AuctionsComponent maintains a list of auctions as an Observable of auction items which get inistialised through the auction service. You can then select the item  and make bids using pushes onto auctions model object. The implementation of the getAuctions() method is interesting - it returns an observable that mimics the JSON data structure we saw earlier. When we select an auction and place bids, we can access the bids arrays using selectedAuction.bids and push new bids onto the observable array of bids with the selected auction as the key. In an implementation where the bids are in a separate component, you would have a getBids(key) method in the the service to access the bids node directly and then push bid objects using the same auction key. We can see the auction selection and bidding actions in the animated gif below.



Selecting and bidding

Once you have selected an item and logged in, we can bid for the item. This is implemented as a template driven form. Submitting the form, pushes a JSON object onto the bids node using the selected auction as a key.




What's missing

Besides the obvious lack of form validations and a more elaborate auction data model, the  application is missing some functionality such as ensuring that bids can be placed only if they are higher than the current highest bid. This could be implemented on the client side but any robust implementation would ensure that the server maintains ultimate control of who is the highest bidder. Currently,Firebase has a limitation of server side rules (although basic validation on access and data updates in the security rules console). There is a workaround to implement a server component (such as a nodejs client) that can listen to event updates and make post-facto updates to the firebase state e.g. set the highest bidder. This pattern is illustrated below:


ref: https://www-staging.firebase.com/resources/images/blog/client_server.png

Conclusion:

This is a first attempt at putting recent angular2 learning into practice but hopefully, this can provided you with enough motivation to embrace responsive programming and that you are as excited by the power of the reactive paradigm as I am. There will be more updates as I try to keep pace with angular and firebase developments, and learn more about reactive application architectural patterns within our projects.

Tuesday 5 July 2016

Reactive Programming Part 1: An Introduction

Reactive programming is a hot topic and something that I have been following with interest. Essentially, it involves a programming paradigm that reacts to stimulus which can be modelled as an event or data stream. It isn’t really a new paradigm, as spreadsheets have been using this for a long time. When you create a chart based on the value of certain cells, as you change the input in the cells, the chart ‘reacts’ to the input stream and modifies itself. The reactive programming model permeates right through all application layers from backend services (data changes), front-end applications ( user stimulus such as keyboard events)  and interactions with external services (twitter streams) . It also implies a shift from imperative style of programming to asynchronous, functional-style code (no callback hell).  This results in high responsive user experiences and communication patterns that enable a decoupled micro-services architecture.


What is it good for?

There are numerous applications where reactive principles can bring immense benefits and simplify the programming and architectural models. Some of the more obvious ones are:

  • User experience related features: search, sign up process (checking if the user already exists)
  • Social or networking style apps: collaborative document authoring, group calendars, messaging/chat apps 
  • Multiplayer games
  • Financial event based systems
  • Robotics
  • Sensor networks and IoT

Key Constructs: Streams and Observables

Modern reactive programming framework such as RxJS (and other language flavours) offer efficient semantics and constructs for writing non-blocking services and applications. The core concepts of reactive programming models are streams, operators and subscriptions (bindings).

Streams:

As mentioned before, streams are sequences of events ordered in time. Stream events can be almost anything -  a mouse clicked, a page view, an error event, an Instagram post, a person of interest entering a watch zone.  



Transformation:

Streams can be transformed, combined to create new immutable streams that can then be subscribed or listened to by consumers. This is the old observer pattern from the GOG book but there are some key distinctions which I will cover later.



Also, event streams can be generated from continuos sources as as illustrated below:

Subscription/Binding:

Streams are ‘observed’ or ‘listened’ to by means of a special implementation of the Observer patter called as an Observable. The Observable is similar to the Iterable but unlike the Iterable where the consumer pulls the data from the Iterable, the observable pushes data to the consumer when data is available, signals to the consumer when no more data is available and signals when an error has occurred.

The Reactive Toolset

While there is a plethora of choices available to programmers for building reactive applications, these are my leanings:
  • RxJS with bindings for several languages
  • Akka Streams,
  • Angular2, AngularFire, Firebase

In the next part of this article, I will cover prototyping a real time auction application using some of the reactive programming concepts and the toolset listed above.