I’ve gotten more than a few questions over the last year on how to use the ASP.NET MVC framework and the Web API framework together. Do they work together? Should they work together? When should you use one or the other?
Here’s some general rules of thumb I use.
1. If the bulk of the application is generating HTML on the server, then there is no need to use the Web API. Even if I have the occasional call from JavaScript to get JSON data for templates or an autocomplete widget, using regular MVC controllers will suffice.
One thing to keep in mind is that the Web API is a separate framework with its own dependency resolver, action filters, routing rules, model binding, and model serialization settings. Bringing in a 2nd set of all these components just to satisfy a few JSON requests from script is an increase in complexity.
2. If an application is loaded with JavaScripts and JSON flows back and forth to the server frequently, or if I have to support more clients than just the script in the pages from my site (some of whom might want XML or other formats), then it is a good time to create HTTP service endpoints and a more formal service API. These scenarios are just what Web API is made for and both MVC controllers and Web API controllers will happily coexist in the same project.
Although the Web API does add some complexity, it is also easier to build a proper service with the Web API. I can use the verb based routing and content negotiation features to build services oriented around resources, and the OData support and automatic help page generation of the Web API framework can come in handy.
3. I’m not a big fan of services for services sake. In the previous two figures, the MVC UI and Web API pieces are drawn to suggest how they are only facades on top of a core application. Most of the interesting things are defined in the application and not in the UI and Web API layers. When someone suggests that the MVC controllers should talk over HTTP to Web API controllers in the same application, all I can think about is putting a façade over a façade, which seems silly.
There are some valid reasons to go with such an architecture (see #4), but be cautious when creating new tiers.
4. It is more than reasonable to integrate multiple applications or large pieces of functionality using services and the Web API. This is a scenario where having web service calls inside or behind the MVC controllers of an application is almost required.
The above type of scenario usually involves large applications and multiple teams. Using a service layer allows for more flexibility and scale compared to sharing binaries, or integrating at the database level (shudder with fear).
There is no quick and easy answer to the questions in this space. If you are looking for guidance, hopefully I’ve provided some rules of thumb you can use to start thinking about the answer for your specific scenario. While thinking, remember these lines from the Zen of Python:
Simple is better than complex
Complex is better than complicated
I can’t say enough good things about The Norwegian Developers Conference.
This year there were a couple talks on AngularJS.
First there was Tom Dale, Peter Cooper, and Rob Conery in an EmberJS versus AngularJS cage match. We also interviewed Tom and Rob on Herding Code after the match was over and Tom gave us some great insights on the future direction of Ember.
Tom Dale, Peter Cooper and Rob Conery; Cage Match - EmberJS vs. Angular from NDCOslo on Vimeo.
I also did a long and rambling live coding session with AngularJS. Hopefully someone can make sense of it all.
Scott Allen: The Abstractions of AngularJS from NDCOslo on Vimeo.
The Windows 8.1 preview includes a preview of Internet Explorer 11, which includes a new version of the F12 Developer Tools for inspecting, profiling, and debugging web sites.
The developer tools are now metrofied with flat buttons and an emphasis on content over window chrome. Although there are still a considerable number of icons and commands to press, it does seem easier to read and work with the information presented. All the important features are still here, though a few things seem to be missing (the ruler tool and link report as two examples), and they still behave the same and present the same information.
Update - yes, the DOM explorer tracks changes in real time now. Huge improvement!
The emphasis is on performance with new “UI Responsiveness”, “Profiler”, and “Memory” sections.
The Memory tab is looking very useful for today’s apps and the heap snapshots are easier to use compared to the tools in other browsers. Likewise the code profiler is easy to work with and similar to the profiling tools for managed code in VS Ultimate.
The “UI Responsiveness” tab is visually appealing and highly interactive but contains an enormous amount of information and will require some guidance and practice to use properly.
To get a full picture of what is happening on any given page, the IE dev tools will need to give us the ability to inspect local storage, session storage, IndexDB, and Application Cache. I didn’t find any of these in the current release.
Most worrisome is how there doesn’t appear to be any extensibility story for the tools. Framework oriented plugins for Knockout and Angular are popular in other browsers because they allow developers to work at a level above the code to see what is happening on a page. The ability to use simple HTML and JavaScript to create these types of plugins is what makes the other tools so popular. The IE dev tools will need a better extensibility story to keep web developers happy.
There are many ways to automate Microsoft Office programs, but Python might be the prettiest:
import sys import os import glob import win32com.client def convert(files, formatType = 32): powerpoint = win32com.client.Dispatch("Powerpoint.Application") powerpoint.Visible = 1 for filename in files: newname = os.path.splitext(filename)[0] + ".pdf" deck = powerpoint.Presentations.Open(filename) deck.SaveAs(newname, formatType) deck.Close() powerpoint.Quit() files = glob.glob(os.path.join(sys.argv[1],"*.ppt?")) convert(files)
This script is using Python for Windows extensions.
Last week we looked at using ngOptions in AngularJS to build a select list. Since the selections are mutually exclusive, we could have done something similar using radio buttons. There is no directive dedicated to radio buttons, but here’s a couple examples to show how easy they are to work with.
We’ll use the same controller as last time, but add a project attribute to the engineer.
var EngineeringController = function($scope) { $scope.engineer = { name: "Dani", currentActivity: "Testing code", project: "App A" }; $scope.activities = [ "Writing code", "Testing code", "Fixing bugs", "Dancing" ]; };
If we want to assign a project using hard coded inputs in the view, those inputs are easy to create and bind using ng-model.
<div data-ng-controller="EngineeringController"> {{engineer.name }} is currently {{ engineer.currentActivity }} for {{ engineer.project }} <label> <input type="radio" name="project" value="App A" ng-model="engineer.project" /> App A </label> <label> <input type="radio" name="project" value="App B" ng-model="engineer.project" /> App B </label> ... </div>
A more interesting challenge is dynamically building a series of radio buttons using the activities array in the model. Here’s one approach using ng-repeat:
Choose a new activity: <label data-ng-repeat="act in activities"> <input name="currentActivity" type="radio" value="{{act}}" ng-model="engineer.currentActivity" /> {{act}} </label>
The above works because all the inputs have the same name, bind to the same model property, and have distinct activity values. But, there’s one other feature of the model that makes the sample work, and that’s how we are binding to a nested property on the model (engineer.currentActivity).
Remember that an ng-repeat directive creates a child scope for each item, and the child scope inherits from the controller’s $scope object. Thus, the two way binding established with ng-model might not be setting a value in the $scope object of the controller, but in a child scope created by the repeater. In the code above, the binding works because the binding first needs to read the engineer property which is prototypically inherited from the $scope of the model, and then writes to the currentActivity property of that engineer object.
If the controller was flat like the following:
var EngineeringController = function ($scope) { $scope.currentActivity = "Testing code"; $scope.activities = [ "Writing code", "Testing code", "Fixing bugs", "Dancing" ]; };
Then the following markup would never write into $scope.currentActivity, but instead into a child scope, so this approach is probably not what you want.
<label data-ng-repeat="act in activities"> <input name="currentActivity" type="radio" value="{{act}}" ng-model="currentActivity" /> {{act}} </label>
One way to fix the problem is to go back to using a more complex model (engineer.currentActivity would work), or to explicitly bind to the parent scope of the repeat item using $parent.
<input name="currentActivity" type="radio" value="{{act}}" ng-model="$parent.currentActivity" />
The default styles for the Developer Tools in Chrome are a bit uninspiring.
Fortunately, devthemes.com maintains a comprehensive list of themes for the Dev Tools as well as Sublime Text 2 and others.
My current favorite for Chrome is ZeroDarkMatrix.
Installation is as easy as downloading the theme’s custom.css file and replacing the existing file used by Chrome in ‘C:\%LOCALAPPDATA%\Google\Chrome\User Data\Default\User StyleSheets’ on Windows machines.
If you want to tweak styles yourself it can be helpful to look at the markup for the dev tools. You can inspect the markup by opening the dev tools on any web site (F12), then opening dev tools on the dev tools window (Shift+Ctrl+I). In the screen shot above, you can see the dev tools UI is built with HTML inside a <body> with an id of “-webkit-web-inspector”, which most themes will use as a prefix in the selectors for all the classes in a theme.
Nassim Taleb’s book Antifragile: Things That Gain from Disorder is a celebration of volatility and the systems that not only survive stressful conditions but thrive and become better when faced with irregularities. The book spans economics, medicine, politics and more, but it’s easy to read the book and see how the concepts apply to software applications and software development.
The Netflix chaos monkey is one example of how volatility can improve software. Failure recovery becomes “easier, faster, and eventually automatic” when the monkey is terminating random services in a complex distributed system and exposing weaknesses.
Some of Taleb’s points include:
An example is the software architect who makes decisions without writing code or dogfooding their own decisions. As Jeremy Miller once said: “designs get better faster when the designer has to feel the pain from clunky designs and adapts to alleviate that pain."
Those who follow principles like KISS and SRP know that small, focused abstractions are easy to read, write, and maintain. But “small is beautiful” is also applicable to systems themselves and is a core tenet in the UNIX Philosophy. Users also value simplicity in software applications. Witness the success of Dropbox over more “fully featured” file sharing applications.
The software industry tends to visualize schedules using precise Gnatt charts, work in progress items fall into swim lanes and ordered backlogs, classes can be neatly arranged into architecture diagrams, and someone generally creates an aesthetically pleasing network diagram for every distributed system. We tend to think of people, processes, and software as things that act logically and are easy to categorize, however all three are organic and can replicate the inexplicable behavior of a cat. The last decade or so has shown that thinking in a way that embraces uncertainty and change will generally lead to happier teams, happier users, and better software.