Getting Started with Node.js

Running Node.js on your Joyent SmartOS instances

In this tutorial you will create a basic Node.js HTTP echo application with the node-restify (aka just "restify") framework. If you’ve spent some time developing for the web, you’ve probably spent time learning JavaScript, perhaps coding client-side applications. Node.js brings the flexibility of JavaScript to the server side, allowing you to use your JavaScript knowledge to code event-driven applications. Joyent, as the steward of Node, provides software that makes it easy for you to design, deploy, and debug your Node applications.

As a start, Joyent virtual machine images have Node.js and npm pre-installed, and they allow root ssh access to the server. Of course you can add other modules you might need.

What you need

  • An account on joyent.com
  • An SSH Key
  • Some familiarity with JavaScript

Setting up your Joyent SmartOS virtual machine

If you haven’t yet provisioned a machine, you have the opportunity to make your life easier by provisioning one with useful software already installed. One such option is called “nodejs” which is specifically configured for Node development.

SmartOS on Joyent has been specially tuned for performance and operational management well and works particularly well with Node.js. It is a open sourced Unix variant, branched off of the family tree closer to BSD Unix. Joyent uses SmartOS to optimize Node.js capabilities internally. Its package manager is pkgsrc. You can learn more about SmartOS here.

instance

If you have a machine already, but aren’t sure if you have node installed, connect as root and type node -v at the command line.

If you have node installed, it will return with the version number:

[root@437dc27a- ~]# node -v
v0.10.21
[root@437dc27a- ~]#

If you don’t have node installed, it will return with an error message:

[root@ba707556- ~]# node -v
-bash: node: command not found
[root@ba707556- ~]#

Installing node

Almost all of the most common and most useful SmartOS images come with node pre-installed. If your machine was set up from an image without node, or if you want to update to the latest version[link: http://nodejs.org], you will need to install it yourself. You can do so with “pkgin install nodejs”. Further information can be found on the SmartOS wiki.

Hello Node!

Use your favorite editor to create a file called hello.js and type this command:

console.log("Hello World");

Save the file and then run it at the command prompt with node hello.js

[root@437dc27a- ~]# node hello.js
Hello World
[root@437dc27a- ~]#

But that’s not even demonstrating any of the features that make node.js such an attractive environment for web-facing applications. It is extremely easy to build small programs to do things that can be complicated in other languages.

Use your favorite editor to create a file called server.js and type (or cut and paste) the following:

var http = require (“http”);
http.createServer(function(request, response) {
response.writeHead(200, {“Content-Type”: “text/plain”});
    response.write(“Hello World!”);
    response.end();
}).listen(8080);
console.log(“Server is listening on port 8080”);

Save the file and then run it at the command prompt with node server.js

[root@437dc27a- ~]# node server.js
Server is listening on port 8080

Point your browser to the IP address of your machine on port 8080, and you get:

browser

What does this all mean?

The first line of this code uses require to include the HTTP module into the program and assigns the functionality of a HTTP library to the http object.

Next, you’ll need a HTTP server. Unlike other languages which require you to interface with a server such as Apache, Node itself runs as the web server. This means you’ll need to create the web server. So the second to the sixth lines of code call a method from the HTTP module that creates new HTTP servers. The new HTTP server is listening on port 8080.

createServer has an anonymous function as its argument. This function is attached to the event listener for the request event. Whenever there is a new request to the web server, it will callback the function passed to deal with the request.

Inside the function created for the callback, we call a couple of methods on the response object. These calls modify the response to the client when the server is called.

The server can’t send anything without the HTTP response header. Here the response.writeHead method does this. It assigns a value of 200 (for the HTTP status code “200 OK”) and passes a list of HTTP headers. In this case, the only header passed is Content-type.

The HTTP body is passed to the client after the HTTP header. In this simple example a single line of code is used to write the body of our web page before the connection is closed. response.write sends a string to the client and response.end method closes the HTTP connection.

Finally, the last line of the Hello World example uses the console.log. This prints a string to stdout.

Hello restify!

restify is a Node.js package that allows you to build API services. It is a framework like express.js, but is for building strict API services that are easily maintainable and observable. restify comes with DTrace support for all your handlers, if you're running on a platform that supports DTrace, including MacOS as well as SmartOS.

To get started with restify here is a very simple echo server. Use your favorite editor to make a file called hello_restify.js and add the following lines of code:

var restify = require('restify');
function respond(req, res, next) {
    res.send('hello ' + req.params.name);
}
var server = restify.createServer();
server.get('/hello/:name', respond);
server.head('/hello/:name', respond);
server.listen(8080, function() {
    console.log('%s listening at %s', server.name, server.url);
});

Save the file and run it at the command prompt with node hello_restify.js.

[root@437dc27a- ~]# node hello_restify.js
restify listening at http://0.0.0.0:8080

Open a new terminal window and try talking to your echo server using curl.

[root@437dc27a- ~]#
[root@437dc27a- ~]# curl 0.0.0.0:8080
("code":"ResourceNotFound","message":"/ does not exist")[root@437dc27a- ~]#

What’s going on here? Try using -i to get the header information.

[root@437dc27a- ~]# curl -i http://0.0.0.0:8080
HTTP/1.1 404 Not Found
Content-Type: application/json
Content-Length: 56
Date: Fri, 20 Dec 2013 10:53:11 GMT
Connection: keep-alive

("code":"ResourceNotFound","message":"/ does not exist")[root@437dc27a- ~]#

The server isn’t returning anything to the curl request, it’s returning a 404 error code. If you look at hello_restify.js, you see that the ‘get’ route is ‘/hello/:name’ which means that the domain root is only looking at http://0.0.0.0:8080/hello/someName for a request to be made in order to return a response.

Now you can try a few other curl commands:

curl -i http://0.0.0.0:8080/hello/World works. It returns the headers with a 200 OK, lets you know the content type and length and greets you with “hello World”

[root@437dc27a- ~]#
[root@437dc27a- ~]# curl -i http://0.0.0.0:8080/hello/World
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 13
Date: Fri, 20 Dec 2013 11:00:10 GMT
Connection: keep-alive

"hello World"[root@437dc27a- ~]#

curl -i http://0.0.0.0:8080/hello/World -H 'accept: text/plain' works. It returns the headers again, different this time because of the extra parameters passed to curl and greets you without the quotation marks.

[root@437dc27a- ~]#
[root@437dc27a- ~]# curl -i http://0.0.0.0:8080/hello/World -H 'accept: text/plain'
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 11
Date: Fri, 20 Dec 2013 11:15:20 GMT
Connection: keep-alive

hello World[root@437dc27a- ~]#

curl uses Connection: keep-alive by default. In order to make this method return right away, you'll need to pass Connection: close.

[root@437dc27a- ~]#
[root@437dc27a- ~]# curl -iH 'connection: close" http://0.0.0.0:8080/hello/World
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 13
Date: Fri, 20 Dec 2013 11:17:48 GMT
Connection: Close

*hello World*[root@437dc27a- ~]#

Since curl is often used to test your code, note that restify provides a plugin (in lib/pre/user_agent.js) to address this idiosyncrasy in curl. The plugin checks whether the user agent is curl. If it is, it sets the Connection header to "close" and removes the "Content-Length" header. More about plugins here.

So there you go: A basic echo server built in restify and Node. It's simple and provides a good base for building your own APIs in restify.

If you're designing your application's infrastructure, consider using Joyent's Bunyan logging package. It is a Node lightweight logger that has some dynamic run-time enablement and filtering features. This means that by using Bunyan as a logging library, it is possible to go from minimal level logging to debug logging (and back) on a production server without restarting it. This allows you to catch production bugs that would normally be disruptive to your end clients.

Speaking of debugging, when you're debugging an application Joyent’s Cloud Analytics allow you to look in depth at the current condition of your server and the applications running on it. Cloud Analytics is built on DTrace. DTrace is a powerful analytic tool that allows you to trace all the way from the kernel to your application’s code - even in production.

Finally, since January 2014 Joyent has been offering Node.js support if you need priority access to Joyent’s engineers and support team. You can access support for your severity one issues during US business hours with a Node.js Core Support agreement.

:

Sign up Now for Instant Cloud Access

Get Started

View PricingSee Benchmarks