Monday, August 29, 2011

Hosting express node.js applications in IIS using iisnode

In my last two posts I introduced the iisnode project which allows hosting node.js applications in IIS on Windows, as well as shown how it integrates with the URL rewrite module. In this post I demonstrate how to run node.js applications that use the popular express framework in IIS.

Installing express on Windows

Node.js modules, including express, are typically installed using NPM. The bad news is that as of this writing NPM is not yet supported on Windows. The good news is that for simple cases one can use the ryppi.py script. Assuming you have Python installed, you can call:

ryppi.py install express

which will create the node_modules folder with the downloaded express library. You can check out the resulting layout here.

The code

A simple express application we will host in IIS looks like this:

   1: var express = require('express');
   2:  
   3: var app = express.createServer();
   4:  
   5: app.get('/node/express/hello/foo', function (req, res) {
   6:     res.send('Hello from foo! [express sample]');
   7: });
   8:  
   9: app.get('/node/express/hello/bar', function (req, res) {
  10:     res.send('Hello from bar! [express sample]');
  11: });
  12:  
  13: app.listen(process.env.PORT);

Two key aspects to call out that may be different from your bread & butter express app are:

  1. The path specified in app.get calls must be the full path of the request (lines 5 and 9). When your app is hosted in IIS, depending on the configuration you may not necessarily own the entire namespace over port 80. Like in the example above, your IIS hosted express application may reside in the ‘express’ folder of  the ‘node’ virtual directory, and only own the subordinate URL namespace.
  2. Similarly to a non-express node.js app hosted in iisnode, the listen port is provided by IIS through the PORT environment variable. When you start your listener (line 13), this is the port you should specify.

The web.config

I talked about using the URL rewrite module for regular node.js applications before, and URL rewriting is perhaps even more relevant in case of URL-conscious express apps. The web.config below allows the express application saved in hello.js to receive HTTP requests directed at all URL paths subordinate to the ‘hello’ path component, as configured in lines 20-27:

   1: <configuration>
   2:   <system.webServer>
   3:  
   4:     <!-- indicates that the hello.js file is a node.js application 
   5:     to be handled by the iisnode module -->
   6:  
   7:     <handlers>
   8:       <add name="iisnode" path="hello.js" verb="*" modules="iisnode" />
   9:     </handlers>
  10:  
  11:     <!-- use URL rewriting to redirect the entire branch of the URL namespace
  12:     to hello.js node.js application; for example, the following URLs will 
  13:     all be handled by hello.js:
  14:     
  15:         http://localhost/node/express/hello/foo
  16:         http://localhost/node/express/hello/bar
  17:         
  18:     -->
  19:  
  20:     <rewrite>
  21:       <rules>
  22:         <rule name="hello">
  23:           <match url="hello/*" />
  24:           <action type="Rewrite" url="hello.js" />
  25:         </rule>
  26:       </rules>
  27:     </rewrite>
  28:  
  29:     <!-- exclude node_modules directory and subdirectories from serving
  30:     by IIS since these are implementation details of node.js applications -->
  31:     
  32:     <security>
  33:       <requestFiltering>
  34:         <hiddenSegments>
  35:           <add segment="node_modules" />
  36:         </hiddenSegments>
  37:       </requestFiltering>
  38:     </security>    
  39:     
  40:   </system.webServer>
  41: </configuration>

One other aspect worth pointing out is request filtering. Remember the express application relies on the express library installed in the node_modules directory? You probably don’t want the contents of this directory to be served by IIS in any shape or form, and you can express (sic!) that desire by adding it to hidden segments list (lines 32-38).

Voila!

Your IIS-hosted express node.js application behaves like expected:

image

image

So where can I get iisnode again?

Everything you need to get started is at https://github.com/tjanczuk/iisnode. Make sure to check out the express sample. Feedback welcome!

2 comments:

  1. i have created a port of ryppi to c# which can be found at https://github.com/prabirshrestha/nji

    you can now type
    nji install express

    ReplyDelete
  2. Any idea what could be my problem here: http://stackoverflow.com/questions/9904897/iisnode-iis7-5-405-method-not-allowed-when-performing-put-request
    Thx

    ReplyDelete

About Me

My Photo
I am helping to develop and ship software for Microsoft. My current focus is node.js, JavaScript, and Azure. Before that I worked on .NET Framework and Silverlight, in particular web service technologies: Windows Communication Foundation (WCF), SOAP, WS-*, REST, AJAX.

Search This Blog

Loading...

Blog Archive