Wednesday, April 16, 2014

A (JSONP) REST service with your existing WCF service

I'm mainly doing javascript in my free time, but at work, it's still classic .NET. Yesterday, I had to quickly set up a REST service via WCF to test something. In the spirit of saving my keystrokes, and for my own later reference, I'm posting how to do it here, instead of emailing it.

I'm assuming you have an existing WCF service.

Just add the following to your ServiceContract (you'll need a reference to System.ServiceModel.Web):

[OperationContract]
[WebGet(UriTemplate = "{id}", ResponseFormat = WebMessageFormat.Json)]
Person GetPerson(string id);

For REST to work, your parameters will have to be a string and you will have to parse it in the implementation of your ServiceContract.

I want JSONP, so I've added the response format and need some extra stuff in my config:

The service:
<endpoint address="People" 
    binding="webHttpBinding"
    bindingConfiguration="Default" 
    behaviorConfiguration="jsonBehavior" 
    contract="My.Contracts.IPersonService" />

A behavior:
<endpointBehaviors>
  <behavior name="jsonBehavior">
    <webHttp />
  </behavior>
</endpointBehaviors>

Finally, the binding:
<webHttpBinding>
  <binding name="Default" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>

If you need other REST methods (POST for example), have a look at WebInvoke.

Now you can navigate to your url, for example: http://www.example.com/People/3, or use this url for AJAX calls.

Monday, April 14, 2014

Which javascript framework should I choose?

With all these javascript frameworks, which one should you choose? Which one is winning? The short answer: it's too soon to tell and it doesn't really matter. But there are some more or less safe bets.

A while ago, I was talking with a colleague over lunch about a presentation I'm preparing on Durandal (in Dutch), a javascript framework for single-page applications. I also mentioned Angular and he asked me which one is most popular, which one is winning.

If we broaden the discussion to any type of JS framework (not jut the ones for SPAs), it seems every other day a new JS tool or framework is born. Do you often get the feeling you can't keep up? Like you're in a room where everyone is shouting for your attention and you can't really understand anyone? Sometimes, it feels like the Wild West. Maybe it's better to just wait it out and see which technologies remain after the noise settles down.

That could be a rational choice. There's nothing wrong with it. I too often have doubts on whether the time I'm investing in learning something is worth it. I recently spent two weeks trying to get a Mimosa skeleton working on NodeJS in Azure. NodeJS and Azure are here to stay, but shouldn't I have looked into Yeoman and/or Grunt instead of Mimosa? Do they even do the same? I don't know!

On the other hand, this time isn't wasted, even if the technology you chose is discontinued in the future (unless you're going for commercial production-ready stuff in which case you should probably choose wisely).

First of all, the skills you will have learned are most likely to be useful in other areas. Your javascript skills will have improved, that's definitely nice. Maybe you now know how MVVM in javascript works. Or that dependency injection is actually possible. How to unit test javascript. Etcetera.

Second, chances are high you've more or less mastered your day-time job programming language (C# in my case). Sure, frameworks come and go, the language evolves, you might be switching from desktop to web,... But the time you need to learn this will be smaller because you already know the tools, the principles, the language constructs. Investing now in learning javascript and its libraries is new, exciting, interesting for the future of your career, and it won't make you forget that other language.

And finally, if you're still the careful type, some clear leaders are emerging. NodeJS is here to stay. Angular has gained enormous traction, this is no longer 'a small interesting experiment'. RequireJS is being used just about everywhere. Bower is very popular.

As I see it, we're heading towards more HTML and JS anyway… Dive into some of these technologies. Choose one and learn it. Even if your framework doesn't 'win', you'll feel more comfortable with javascript development and more easily switch to another.

All that being said, I have explored Durandal, but to be honest, I will now be taking a serious look at Angular. It seems to be getting more traction and has a larger community. Just don't think you have wasted your time if you learnt a framework that didn't really take off.

Update: on the same day that I posted this, Rob Eisenberg (of Durandal) published a post on the future of Durandal and Angular and how they will converge. Rob is working on the Angular team now, although Durandal will not be discontinued. This makes Angular even more attractive as a choice to me, but the central point of my post remains: don't be afraid of having made a wrong choice in getting to know javascript libraries or frameworks (unless maybe for critical production applications).

Monday, April 7, 2014

Using Google Analytics in a (Durandal) SPA

I've been playing around with Durandal lately, and was wondering how you get a Durandal SPA to work with Google Analytics. The problem is the visitor is staying on the same html page. Yet you want analytics for your different views (so everytime the hash in the browsers navigation bar changes).

It turns out this is fairly easy. I'm putting this here for my own and anyone else's reference. It probably works with other SPA frameworks too (Angular for example).

There are a number of composition lifecycle functions that a Durandal viewmodel can implement, but instead of putting Google Analytics code in every viewmodel, it's easier to just include it once. Durandal provides an event when navigation has completed. Hook into that event and you can add a Google Analytics entry each time your user navigates to a new view:

router.on('router:navigation:complete', function(instance, instruction) {
    ga('create', 'UA-XXXXXXXX-X', 'example.com');
    ga('send', 'pageview');
});

Put this in your main.js or shell.js file so it is hooked up early in your application's lifetime. In my case, I added it in the 'activate' method of the shell.js (you can see it in my GitHub repository). Last but not least, don't forget to include the usual Google Analytics code so the calls above actually work:
<script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
</script>

This is the newer code that works with 'Universal Analytics', but it works the same for the older code. You just have to split the code into the part that defines the function and the part that actually adds an entry on every navigation.

Monday, March 31, 2014

Getting a Mimosa (Durandal) app to work on NodeJS on Microsoft Azure

Mimosa is a build tool for Node.js apps. But it's more than just building. For a very nice introduction, check out the 'Tour of Mimosa' slideshow on their homepage.

In short, it will do almost anything you need to get from the source of your web app to something that you can deploy to the server: JS transpiling, CSS linting, JS hinting, minification, dependencies, etc.

But it also helps while developing, for example by allowing live reload so you see the changes you've made in your browser immediately.

Also, there are 'skeletons', which are a sort of project templates. These get you started quickly. And that's what Mimosa is about. Getting up to speed quickly, and not having to add a massive amount of configuration.

I had some trouble getting the Durandal skeleton to work on NodeJS on Microsoft Azure. I don't think my problem was Durandal related, so you might find this helpful for other Mimosa and NodeJS apps on Azure.

To get started, install Node.js. If, like me, you're on Windows, go to nodejs.org, download and run the installer. This will install Node.js, which now means you also have NPM. NPM is the Node Package Manager and allows you to easily install Node packages, either globally for all your Node stuff, or locally for your specific app.

Start the Node.js console and enter
npm install -g mimosa

The -g flag means it will install globally (so you can re-use it in other NodeJS apps).

If, like me, you want to create a Durandal app quickly, just run
mimosa skel:new durandal path/to/your/app

Not every dependency has been installed yet, so you still need to run
npm install

This will look at your package.json file and install all dependencies.

Now run
make start

and navigate to localhost:3000 in your browser. Presto!

And now comes the trouble: getting this to work in Microsoft Azure. I had set up Azure to pull in my GitHub repository and host it. That's actually very simple from the Azure management portal. However, I was getting an internal server error.

What's important to realize (and something I forgot) is that Azure is actually just pulling in the source of our app. Mimosa helps us in our development, but we still need to build everything. The documentation on Heroku and Jay Harris helped out a bit here.

In our mimosa-config file, we need to have the web-package as dependency and in our .gitignore file, we should have the /dist directory in comment (so it is checked in). If you used the Durandal skeleton like I did, this is already done. Web-package is responsible for packaging everything up. And the /dist folder is where the results of all the linting, minification, packaging, etc is placed. This is the folder that we want in Azure.

First, we need to build everything:
mimosa build -omp

The flags mean it wil optimize, minify and package our code. It's the packaging that's important. You should now have a /dist folder in the root of your project. Inside, there's all sorts of files, including app.js.

Now we want Azure to run this app.js file in our /dist directory. On Azure, there is a component called Kudu that is responsible for syncing with GitHub. It essentially just pulls in the contents of the repository and tries to host what it found. But we need to help it a little, because we've used Mimosa, and our stuff is in the /dist folder.

First, install the Azure Command Line tools if you haven't already. You can do this via NPM:
npm install azure-cli -g

Next, generate the default Kudu scripts:
azure site deploymentscript --node

This will add a .deployment and a deploy.cmd file. Have a look at both, but the interesting one is the deploy.cmd file. Scroll down to the deployment section. You will see that it does the following:

  • Kudu sync (pull in the changes from GitHub)
  • select node version
  • install node packages

In the first part, change "%DEPLOYMENT_SOURCE%" to "%DEPLOYMENT_SOURCE%/dist". Now, Kudu will not sync the entire repository, but only the dist folder. This means only our packaged, minified, linted,... code will be deployed.

Build everything again (with mimosa build -omp) so our deployment scripts for Kudu are in our /dist folder. Now add everything to your repository (if you haven't already). It is possible that you'll get an error because certain paths are too long for Git. You can avoid this by adding dist/node_modules to your .gitignore file. Because we're going to install the necessary node packages on the server via the deploy.cmd anyway, we don't actually need the contents of this folder.

Setting up an Azure website to pull in a Git repository is beyond the scope of this post. But after pushing all your commits, you should see the latest commit in the deployment tab of your website. However, surfing to your new URL will give you an error. The reason for this is that Azure will look for server.js as entry point to your NodeJS app, but Mimosa starts in app.js.

We can change this in the web.config file that Azure has generated for us. In the dashboard tab of you website, connect to the FTP address you see there (you may have to set up credentials) and download the web.config to the root of your repository. Open it up and change all references of server.js to app.js. Commit, build (mimosa build -omp), push and your Durandal skeleton for Mimosa should be up and running on Microsoft Azure!

Possible next steps could be to make a bat file that does the mimosa build, commit and push; or make Azure do this for you. This may be a long post, but when you follow the steps provided, this isn't actually a lot of work (it was to find though!). Check out the commit log of my GitHub repository to see the necessary steps.

Friday, February 28, 2014

Learning, speaking, and Durandal

At Tem4Talent we recently held an entire day of developer sessions. We regularly have someone give a session on an interesting topic, but always after work. This limits time somewhat. An entire day makes it possible to have multiple sessions and dive more deeply into the topics at hand.

I myself gave a session on using Durandal for single page applications. Some of my colleagues are very much pro-javascript (looking at you Tim!), while others are sceptical. I hope I could convince them at least that a lot is possible with javascript and that a "single page application" doesn't mean you have to put everything in one file. Single page doesn't mean single HTML-file.

There's no screencast of this, but if you're interested, here are my slides:


There are some useful comments in the notes of most slides. Also, you can have a look at the code I used for this on my GitHub (or see it live on GitHub pages).

If your company doesn't have much enthusiasm for letting you learn new things... well, they should. But that's an entirely different discussion. One that I'll summarize by this great conversation I will quote (I'm not sure about the original source, this is all over the internet):
CFO asks CEO: "What happens if we invest in developing our people and then they leave us?"
CEO: "What happens if we don't, and they stay?"
So if you're company isn't backing you, it's time to take matters in your own hands (or give me a call and join me at T4T :) Organize a late-night or weekend-afternoon moment of education. You won't regret it.

And if you're afraid of giving a presentation, it's normal, so was I. My (ex-)colleague Frederik provided us with a great site with tips on how to do a presentation. There's also this one (thanks Tim). Plus, doing it in front of a small group of colleagues is great to begin with, because it makes it more informal and less stressful.

A great added value of doing a presentation is that it forces you to invest some time into the topic. More so than you would when you just want to have a look at something. It makes you structurize your knowledge and thinking process, look into the small obscure problems, have a look at that difficult thing for the second or third time, etc. I used to watch screencasts and dabble with small projects that were one step above a 'Hello World' project. For actual learning, I've found these are highly inferior to either shipping something or presenting it to your pears. It's the difference between passive learning and active learning.

Don't worry if you're not a leading expert (I didn't have any experience with Durandal) and someone else in the group knows it too (or even better). Especially not if you're in front of colleagues you know well. Just give it a go, and while I'm sure speaking is not for everyone, I'm confident most people would be surprised at how positive the experience is.

Saturday, February 15, 2014

Remove your thinking-process-comments

Please don't do this:
// Create a new customer
var customer = new Customer();

// Assign the name
customer.Name = name;

// Send to server
this.customerService.CreateCustomer(customer);

Just don't.

Tuesday, January 14, 2014

Readlists: compose your own ebook from web pages

Readlists is a handy web app where you can create your own ebook based on web pages.

I needed the Durandal documentation offline (to take with me on the train) and the Durandal site doesn't offer the latest docs for download. Here's where Readlists comes in. You just give your ebook a title, a description and the necessary links. Readlists does the rest and creates an ebook for you that you can download, send to your Kindle,...

It's all very fast, which made me think my ebook would be incomplete, but I made an ebook with the Durandal docs in about 5 minutes. What's extra cool is that I can share it with anybody.

Here's the link to the Durandal ebook: http://readlists.com/dc7869d4/

And someone made one for the Knockout docs.

Very useful when you're going on a trip.