Tuesday, December 23, 2014

Service Patterns - Simple is Better

I have experimented with a variety of patterns for persistence services in Angular. Invariably, these require us to GET or POST (among others) to a RESTful endpoint.

I'm a huge fan of dto's and ui-side models. I like to define my models in an Angular .factory, and include all the UI-side logic in the model. They are very easy to test.

By design, a service is a singleton (using Angular .service). It consumes and emits models. Simple ... I like simple. By what patterns and providers should you use for your service?

I Don't Like ngResource

When I first started with Angular, ngResource was a seductive option for interfacing with a RESTful endpoint.  Minimal code.  But that's about it for me!   

I like a separation between the service and the model.  ngResource melds the 2.  You add your model logic to the service ... but it doesn't make it easy to test!

The biggest dis-likes of ngResource:
  1. It's polymorphic.  You could get a singleton object, you could get an array.
  2. It's not strongly typed.  I like to test to see if an account an instance of Account.  ngResource only produces "Resource" objects.  I like to validate types in key functions.  Strong types are easier to debug, as Chrome tells you what your object is.
That said, if you want a quick and dirty, small system with a very few endpoints, ngResource makes things easy.

Back to $http

So I've settled on writing close to the metal, using $http.

My standard pattern is ..
  1. Form url.
  2. Transform object (if posting) to dto.
  3. Wrap $http in a promise.
  4. Return the promise.
  5. Have $http success and failure functions where the promise is resolved or rejected.  The response is transformed from dto to my view-model in the success function, not the transformRequest parameter. (Why? -- see Comments)

Comments


  1. Some people like the way ngResource manages urls and query arguments .. and it is clean. This is a pattern for 100% control.
  2. This decouples us from the server-side object.
  3. Why do I  wrap the $http promise in another promise?  Again, control.  I can decide to absorb certain errors, and resolve successfully back to my calling function.  I use this technique for authentication.  The fact a request was bounced back because I am not authenticated is an error (from the server's POV), but just a message on the UI.
  4. The promise returned, and the contents are now all under our control.
  5. We resolve returned objects and transform from dto's to our view models.  Why not use transformResponse?  If you get an error, you're stuck in the transform function, and don't have access to the status code and headers.  I only want to transform if the server tells me the response is OK (200).
Simple.  Do you like it?

Friday, September 26, 2014

A Management View - Why AngularJS Should be Your UI Framework of Choice

A number of people have asked me to explain, from a management POV, the excitement around Angular. Is it something a few techies find intriguing ... or are there solid business reasons to "go Angular"?

What questions should managers consider when evaluating a development framework?

Management Wants

  1. Can we create a "complex" web application at a predictable cost? 
  2. How quickly can we on-board new members to the project team?
  3. How can I arrange work so I can have a reasonably sized team work on the same project at the same time?
  4. Can I have the same level of quality / test coverage as I expect on my java and .NET projects?
  5. Will the system reach a point where the next change will break it? I.E. Can I count on it being extended at a reasonable cost in the future?
  6. Can I count on the framework itself being supported and available 5 years from now?

Don't Consider Angular for Trivial UI features

Before we can start answering these questions, let's look at the scenario where we should even consider Angular.

The trends for web sites is that they have to look, feel and respond like an application. They have to work on a phone, tablet or a desktop application (preferably with 1 code base). This means writing code that will execute largely inside the user's browser.  (So if you have

browser-resident systems are a challenge. Browsers, which have to host the application, vary widely in their capabilities.  Over the past 10-15 years, we've seen 3 low-level standards emerge.  The programming language JavaScript has squeezed out almost everything else.  The objects on the web page (DOM) are governed by the HTML5 standard.  Styling and animation are dictated by CSS3.  But all these are low-level standards.  Think of them as the raw materials in building a house. They alone are not enough to make a complex structure that will meet your goals.

When we say "complex", we're talking a web application that is more than some animation on a web page, or a widget.  For that, use some JavaScript library.  Complex?  Let's look at a UI application with a number of views, that could cost hundreds of thousands, or millions; a system that is tied into a range of web services. Now, we're talking serious corporate money.  You need a framework.

Crying for a Framework 

The raw materials (HTML5, CSS3 and JavaScript) are like the raw materials to build an office building ... steel, wood, plaster, wiring, plumbing, HVAC. What is missing is structures that guide and organize our use of the raw materials, and the teams that work on the project.

Let's look at a series of options for a web application framework.

Option 1 : No framework. You can give these raw materials to your development team, and say "go at it". All well and good.  We don't have to worry too much about on-boarding ... all we need is people who know about the raw materials. Unfortunately, we will have no certainly on our other issues: team efficiency, quality and cost.  And what will we end up with?


Could you build significant office tower with nothing but raw materials?  With experienced people? Maybe.  Will it be efficient and effective?  Probably not.  Is it repeatable?  Doubtful. As seemingly absurd as this option is, many organizations take this approach!  Their techs argue "It is more efficient".  God bless!

Option 2: Toolkits  The late 2000's gave rise to a large amount of open source tools, libraries and widgets to organize the raw materials.  These toolkits extend the raw materials to make common tasks easier.  jQuery is the most popular library, but there are literally dozens, all appealing to various subsets of needs.

These libraries can simplify common tasks and dramatically shorten the time it takes to stand up applications.  Some, like Backbone and Knockout have gained popularity for specific purposes.

However, most of these kits focus the developer on the manipulation of the DOM (objects on the web page).  Testing is hampered, and as the web page changes, tests break or are abandoned.  The net: you can't have many people working on the same application, and your tests will rarely be extensive.

Option 3: The Application Frameworks: Aren't there JavaScript frameworks that will give us the design discipline of Java Spring or .NET MVC?  After all, the MVVM / MVC approaches have a lot of non-raw material practices that encourage SOLID systems.  Aren't there any that supports such an approach in JavaScript?

Angular is that framework.  While we're not making the definitive argument here for Angular over all others, Angular does satisfy management's wants:

  1. We can create a complex web application with some degree of predictability.
  2. With the right architectural approach (a strong MVC / Services architecture) , as we advocate, you can start newbies right away, with having to wait for them to grok the whole framework.  Like MVC & Spring, Angular has a significant learning curve.
  3. But with an intelligent separation of concerns in an MV* design, you can have many people working on the same project, on the same web view, at a time. And by dividing concerns, you can add a new person to the project in a "sandbox", where they can be productive in the 1st week.  We've done it!
  4. Testing is a first-class citizen in Angular, meaning you should be able to get 80%+ code coverage for your JavaScript code.  Compare that to any toolkit or to "raw materials" developers.  I think you'd be lucky to see and maintain a 25% test coverage.
  5. With the MV* discipline, the system will not exhibit a high degree of brittleness as it grows ... as a jQuery application is very likely to do.  The costs of adding a new extension will be significantly lower.  Why? Because Angular allows you to maintain a strong separation of concerns.
  6. It's supported by Google, and is the most popular JavaScript framework. True, Google could withdraw its support as the community expands. But, that is a stronger vote for longevity than some toolkits supported by 2 or 3 guys in a far-away land.

Caveat

So those are the arguments for a framework like Angular.  

However, most of the benefits you'll derive come from the discipline of the team in following an MV* pattern.  Few blogs, web-sites and API docs on Angular suggest this.  But that is the same for Spring or .NET MVC.  It's not the framework, it's the skill and experience of the team using the framework.

So, if you made the choice for Angular, and did not follow any patterns, you'd end up with a "pattern free" system, and far fewer of the benefits described.

The team who is experienced at good design will soar with Angular.

Should you "go Angular"?  If you have the talent, it's a resounding yes.

Monday, July 28, 2014

Code Coverage

I'll do a full post in a few days .. but I have been knee deep into analyzing a moderately-large sized SPA (14,000 file lines so far) using karma code coverage. See https://github.com/karma-runner/karma-coverage

My colleague Eric Nograles set it up and I have become obsessed and fascinated.  

I don't think you'd find it strange that bug reports (the system is still under development) come mainly from areas with poor unit testing.

TDD is possible, almost preferable with a  large Angular app.  I suggest you take and look, and stay tuned for my in-depth look.

Thursday, July 10, 2014

DTO - UI Models

I'm a big fan of UI view models. The only argument I get against is "it's too slow". No-one says they are too lazy to write the code that makes it better, easier to test, creates a separation of concerns, and makes SOLID code ... no no no .... they say it runs too slow.
OK - let's say that we won the argument with the above.  What's the best way to copy things?  I try 3 ways: 
  1.  lodash (faster and better than underscore) -- my preferred syntax.
  2.  The JS for loop. 
  3. Native Angular forEach.

See the results here: http://jsperf.com/dudeman
They are all fast!

Wednesday, July 2, 2014

Know MVC? It's Easy to Transition to AngularJS

It true that Angular has a huge learning curve.  So does every full-fledged development framework.

If the Enterprise is to adopt Angular, can it leverage existing skills?

Fortunately, the answer is YES!  If your firm has MVC architectural skills, and if you follow the patterns with some rigor, you can get productivity and results in no time .. if you keep the discipline!

Let's take a look at side by side code in .NET C# and AngularJS ... for the common patterns in an MVC project.  We won't justify each at this point.  We'll just show how easy the transition can be.

Name spacing

Name spaced modules in Angular allow us to ensure we inject the right code, and allow for easy mocking in tests.

C# 

AngularJS


If your code base is going to get large, you MUST namespace. Namespacing also allows us to do some very slick mocking. Just do it. Stop arguing!

Views, Partial Views

Angular and Razor bindings are very similar.  Angular has the advantage that event binding is part of the language.

.NET Razor

AngularJS


This should be a simple transition for the MVC HTML designer. Expressions in Angular, the moustache syntax, can get complex. Just don't do it and yoru code will be better.

Controllers

Controllers in Angular have to define their routing behavior. ui.routing states are used here.

.NET MVC

AngularJS


Ok, this doesn't translate very smoothly. MVC routes are defined by convention, with the pattern matching set in the config section. But, we like to keep our controllers very lean and simple, so the transition is simple.

UI Components

In ASP.NET forms, they are controls; in MVC, HTMLHelpers.  In Angular, they are directives.

.NET MVC

  And to use it, we have a clumsy syntax ....

AngularJS

  A far simpler, natural extension to HTML is the result ...
You have to admit that the natural looking "DOM" element >custom-text-box is far better than the scribbles in Razor!

Models

Most of your logic should be in models.  You should use models.  Don't make up excuses for not using them.  They contain your logic, local properties, etc.  Test 100% of the code and you will have high quality systems.  If you can write C# models, you can write and use Angular models ... so no excuses!!!

.NET MVC

AngularJS

OMG! Know C-sharp? You know Angular!

Services

Persist your models through Services.  These again look very similar.  Angular is async, so we have to wait for the action to complete (especially if it is an HTTP action).  Again -- almost identical.

.NET MVC

AngularJS


Almost identical again! Remember that JavaScript is asynchronous, so you'll have to get the devs to learn about promises. No big deal.

Dependency Injection (DI)

DI allows us to test each module independently.  If you designed .NET MVC code properly, you used it.  Angular expects it.

.NET MVC

AngularJS


In Angular, you inject by adding the dependency in the module definition. Like in MVC, this makes our service HIGHLY testable!

Code Documentation

IDEs can give you intellisense and nice little books that describe your code.  At the very least, you should tell future developers what the objects are they you consume and produce.  Angular uses jsdocs.

.NET MVC

AngularJS


I love code that is documented in this way. Describe types and make it understood to those who modify it later.

Summary

We'll go into each part of the pattern in future posts.  the bottom line -- if your Enterprise has MVC design skills, those architects can easily transition and build reliable, testable Angular apps .. and produce results at the same pace as an MVC project.