This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the eleventh post in the node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin, the seventh was about ntwitter - twitter api for node, the eighth was about socket.io that makes websockets and realtime possible in all browsers, the ninth was about redis - the best redis client API library for node, the tenth was on express - an insanely small and fast web framework for node.

Today I'll introduce you to a module called semver. Semver is the semantic versioner. Semver is written by Isaac Z. Schlueter, the author of npm. Semver is used in npm to handle all the node.js module versioning problems.

Here is an example of what it does:

semver.valid('1.2.3') // true
semver.valid('a.b.c') // false
semver.clean('  =v1.2.3   ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // true
semver.gt('1.2.3', '9.8.7')  // false
semver.lt('1.2.3', '9.8.7')  // true

The ordering of versions is done using the following algorithm - given two versions and asked to find the greater of the two:

  • If the majors are numerically different, then take the one with a bigger major number. For example, 2.3.4 > 1.3.4.
  • If the minors are numerically different, then take the one with the bigger minor number. For example, 2.3.4 > 2.2.4.
  • If the patches are numerically different, then take the one with the bigger patch number. For example, 2.3.4 > 2.3.3.
  • If only one of them has a build number, then take the one with the build number. For example, 2.3.4-0 > 2.3.4.
  • If they both have build numbers, and the build numbers are numerically different, then take the one with the bigger build number. For example, 2.3.4-10 > 2.3.4-9.
  • If only one of them has a tag, then take the one without the tag. For example, 2.3.4 > 2.3.4-beta.
  • If they both have tags, then take the one with the lexicographically larger tag. For example, 2.3.4-beta > 2.3.4-alpha.
  • At this point, they're equal.

Semver supports the following ranges and styles:

  • >1.2.3 means greater than a specific version.
  • <1.2.3 means less than a specific version.
  • 1.2.3 - 2.3.4 means >=1.2.3 <=2.3.4.
  • ~1.2.3 means >=1.2.3 <1.3.0.
  • ~1.2 means >=1.2.0 <2.0.0.
  • ~1 means >=1.0.0 <2.0.0.
  • 1.2.x means >=1.2.0 <1.3.0.
  • 1.x means >=1.0.0 <2.0.0.

Ranges can be joined with either a space (which implies "and") or a || (which implies "or").

Semver supports the following functions:

  • valid(v) - return the parsed version, or null if it's not valid.
  • inc(v, release) - return the version incremented by the release type (major, minor, patch, or build), or null if it's not valid.

Semver supports the following comparisons:

  • gt(v1, v2) - v1 > v2.
  • gte(v1, v2) - v1 >= v2.
  • lt(v1, v2) - v1 < v2.
  • lte(v1, v2) - v1 <= v2.
  • eq(v1, v2) - v1 == v2.
  • neq(v1, v2) - v1 != v2.
  • cmp(v1, comparator, v2) - pass in a comparison string, and it'll call the corresponding function above. "===" and "!==" do simple string comparison, but are included for completeness. Throws if an invalid comparison string is provided.
  • compare(v1, v2) - return 0 if v1 == v2, or 1 if v1 is greater, or -1 if v2 is greater. Sorts in ascending order if passed to Array.sort().
  • rcompare(v1, v2) - the reverse of compare. Sorts an array of versions in descending order when passed to Array.sort().

Semver supports the following range functions:

  • validRange(range) - Return the valid range or null if it's not valid.
  • satisfies(version, range) - return true if the version satisfies the range.
  • maxSatisfying(versions, range) - return the highest version in the list that satisfies the range, or null if none of them do.

You can install semver through npm as always:

npm install semver

Semver on GitHub: https://github.com/isaacs/node-semver.

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!

This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the tenth post in my new node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin, the seventh was about ntwitter - twitter api for node, the eighth was about socket.io that makes websockets and realtime possible in all browsers, the ninth was about redis - the best redis client API library for node.

Today I'm going to introduce you to express - an insanely fast and small server-side web development framework built on connect. Express is written by TJ Holowaychuk. TJ has written 85 node.js modules so far so expect many more of his modules in this series!

Check this out:

var express = require('express');

var app = express.createServer();

app.get('/', function(req, res){
    res.send('Hello World');
});

app.listen(3000);

This creates a web server that listens on port 3000 and handles the requests to /, returning Hello World string as a response.

Express has really powerful routing system. See this:

app.get('/user/:id', function(req, res){
    res.send('user ' + req.params.id);
});

This handles requests to /user/foo and automatically sets req.params.id to foo. You can also use regular expressions to handle routes.

If you want to handle POST requests, you have to make your app use bodyParser middleware. That can be done through app.use(express.bodyParser()). BodyParser basically parses the application/x-www-form-urlencoded and application/json request bodies and sets up req.body for you. For example:

app.use(express.bodyParser());

app.get('/', function(req, res){
    console.log(req.body.foo);
    res.send('ok');
});

This echos the body variables to console and sends back ok.

There are a bunch of different middlewares that you can use with express, such as:

app.use(express.logger(...));
app.use(express.cookieParser(...));
app.use(express.session(...));
app.use(express.static(...));
app.use(express.errorHandler(...));

The logger middleware handles logging of HTTP requests, cookieParser handles cookies, session handles HTTP sessions, static for static content, such as images, css and scripts, and errorHandler for handling exceptions and errors.

See the express documentation to learn more about middlewares.

Express also integrates with various templating engines. For example, my favorite templating language is jade (also written by TJ) and here is how you'd render a jade template with express:

app.get('/', function(req, res){
    res.render('index.jade', { title: 'My Site' });
});

Template filenames take the form <name>.<engine>, where <engine> is the name of the module that will be required. For example the template layout.ejs will tell express's view system to require('ejs'). The module being loaded must export the method exports.compile(str, options), and return a Function to comply with express.

Express features:

  • Robust routing.
  • Redirection helpers.
  • Dynamic view helpers.
  • Content negotiation.
  • Focus on high performance.
  • View rendering and partials support.
  • Environment based configuration.
  • Session based flash notifications.
  • High test coverage.
  • Executable for generating applications quickly.
  • Application level view options.

As well as:

  • Session support.
  • Cache API.
  • Mime helpers.
  • ETag support.
  • Persistent flash notifications.
  • Cookie support.
  • JSON-RPC.
  • Logging.

Also see this screencast on express by TJ:

For more examples see the examples directory in express source tree. Express also has awesome documentation.

You can install express through npm as always:

npm install express

Express on GitHub: https://github.com/visionmedia/express.

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!

This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the ninth post in my new node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin, the seventh was about ntwitter - twitter api for node, the eighth was about socket.io that makes websockets and realtime possible in all browsers.

Today I'm going to introduce you to node_redis - the best node.js Redis client API library. Redis node.js module is written by Matt Ranney.

This library is a complete Redis client for node.js. It supports all Redis commands, including many recently added commands like EVAL from experimental Redis server branches.

Here is an example of using redis library:

var redis = require("redis");
var client = redis.createClient();

client.on("error", function (err) {
    console.log("Error " + err);
});

client.set("string key", "string val", redis.print);
client.hset("hash key", "hashtest 1", "some value", redis.print);
client.hset(["hash key", "hashtest 2", "some other value"], redis.print);
client.hkeys("hash key", function (err, replies) {
    console.log(replies.length + " replies:");
    replies.forEach(function (reply, i) {
        console.log("    " + i + ": " + reply);
    });
    client.quit();
});

Here is the output when you run this example:

mjr:~/work/node_redis (master)$ node example.js
Reply: OK
Reply: 0
Reply: 0
2 replies:
    0: hashtest 1
    1: hashtest 2
mjr:~/work/node_redis (master)$ 

Each Redis command is exposed as a function on the client object. All functions take either an args Array plus optional callback Function or a variable number of individual arguments followed by an optional callback.

Here is an example of passing an array of arguments and a callback:

client.mset(["key 1", "val 1"], function (err, res) {});

Here is that same call in the second style:

client.mset("key 1", "val 1", function (err, res) {});

Note that in either form the callback is optional:

client.set("some key", "some val");
client.set(["some other key", "some val"]);

For a list of Redis commands, see Redis Command Reference.

The commands can be specified in uppercase or lowercase for convenience - client.get() is the same as client.GET().

You can install redis through npm as always:

npm install redis

Redis on GitHub: https://github.com/mranney/node_redis.

Pieter Noordhuis has written a binding to the official hiredis C library, which is non-blocking and fast. It's called hiredis-node. To use hiredis, do:

npm install hiredis redis

If hiredis is installed, node_redis will use it by default. Otherwise, a pure JavaScript parser will be used.

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!

This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the eighth post in my new node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin, the seventh was about ntwitter - twitter api for node.

This time I'll introduce you to socket.io. I bet that most all of you already know socket.io, however I had several people message me to do an article on socket.io, so here it is.

Socket.io makes websockets and realtime possible in all browsers. It also enhances websockets by providing built-in multiplexing, horizontal scalability, and automatic JSON encoding/decoding. Socket.io is written by Guillermo Rauch, who's the co-founder of LearnBoost.

Socket.io always chooses the best realtime communication method possible. Here is the list of all the communication methods it supports:

  • WebSocket
  • Adobe┬« Flash┬« Socket
  • AJAX long polling
  • AJAX multipart streaming
  • Forever Iframe
  • JSONP Polling

For example, if you're using Chrome, then socket.io will use websockets. If your browser doesn't support websockets, it will try to use flash sockets, then it will try long polling, etc.

Now let's look at a very basic socket.io example:

var io = require('socket.io');
var express = require('express');

var app = express.createServer()
var io = io.listen(app);

app.listen(80);

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
  socket.on('disconnect', function () {
    console.log('user disconnected');
  });
});

This example uses the awesome express node web framework (I'll blog about it soon) to setup a web server on port 80, and attaches socket.io to it.

Socket.io then listens for new connections and when a new connection from the browser is created, it emits news event that sends the { hello: 'world' } hash back to the browser.

It also setups a listener for my other event and it listens for disconnects. When the web application emits this event, socket.io calls the function (data) { console.log(data); } callback, that just prints the data to console. When the client disconnects, it logs this event to console also.

Here is the client side (in the web browser):

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost');
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });
</script>

First we include the socket.io.js script, and then we create a socket.io connection to http://localhost. Here socket.io chooses the best communication method that the browser supports. If it's Chrome then it will be websockets, then if you have flash, then it will try flash sockets, then long polling, then multipart streaming, then forever iframe method, and finally jsonp polling. Then we listen on news event and when we receive it, we emit my other event.

This way you can build all kinds of awesome realtime applications, such as web chat servers and web irc clients.

There are many other features that socket.io supports, such as namespaces, volatile messages, message confirmations and message broadcasting. See the documentation to learn all about this awesomeness!

You can install socket.io through npm as always:

npm install socket.io

Socket.io on GitHub: https://github.com/LearnBoost/socket.io.

Also take a look at dnode that allows to call functions over socket.io!

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!

This article is part of the article series "Node.JS Modules You Should Know About."
<- previous article next article ->

node logoHello everyone! This is the seventh post in my new node.js modules you should know about article series.

The first post was about dnode - the freestyle rpc library for node, the second was about optimist - the lightweight options parser for node, the third was about lazy - lazy lists for node, the fourth was about request - the swiss army knife of HTTP streaming, the fifth was about hashish - hash combinators library, the sixth was about read - easy reading from stdin.

This time I'll introduce you to ntwitter - asynchronous Twitter REST, streaming and searching client API. This module is maintained by Charlie McConnell, aka AvianFlu. Ntwitter was actually created by technoweenie, but since then maintainers have changed several times.

To use it, you'll need to get the API keys. That can easily be done at dev.twitter.com. Just register a new App, and you'll get the keys.

Here is an example ntwitter app that tweets:

var twitter = require('ntwitter');

var twit = new twitter({
  consumer_key: 'Twitter',
  consumer_secret: 'API',
  access_token_key: 'keys',
  access_token_secret: 'go here'
});

twit
  .verifyCredentials(function (err, data) {
    if (err) {
      console.log("Error verifying credentials: " + err);
      process.exit(1);
    }
  })
  .updateStatus('Test tweet from ntwitter/' + twitter.VERSION,
    function (err, data) {
      if (err) console.log('Tweeting failed: ' + err);
      else console.log('Success!')
    }
  );

Here is how to search through ntwitter API:

var twitter = require('ntwitter');

var twit = new twitter({
  consumer_key: 'Twitter',
  consumer_secret: 'API',
  access_token_key: 'keys',
  access_token_secret: 'go here'
});

twit.search('nodejs OR #node', function(err, data) {
  if (err) {
    console.log('Twitter search failed!');
  }
  else {
    console.log('Search results:');
    console.dir(data);
  }
});

You can also use Twitter's streaming API:

var twitter = require('ntwitter');

var twit = new twitter({
  consumer_key: 'Twitter',
  consumer_secret: 'API',
  access_token_key: 'keys',
  access_token_secret: 'go here'
});

twit.stream('statuses/sample', function(stream) {
  stream.on('data', function (data) {
    console.log(data);
  });
});

Here is a list of all the possible statuses/* that you can stream from.

Note how you don't need to login into twitter to do searching and streaming.

You can stream someone's tweets this way:

var twitter = require('ntwitter');

var twit = new twitter({
  consumer_key: 'Twitter',
  consumer_secret: 'API',
  access_token_key: 'keys',
  access_token_secret: 'go here'
});

twit.stream('user', {track:'nodejs'}, function(stream) {
  stream.on('data', function (data) {
    console.dir(data);
  });
  stream.on('end', function (response) {
    // Handle a disconnection
  });
  stream.on('destroy', function (response) {
    // Handle a 'silent' disconnection from Twitter, no end/error event fired
  });
});

Finally, you can stream tweets from certain locations, defined by bounding boxes:

var twitter = require('ntwitter');

var twit = new twitter({
  consumer_key: 'Twitter',
  consumer_secret: 'API',
  access_token_key: 'keys',
  access_token_secret: 'go here'
});

twit.stream('statuses/filter', {'locations':'-122.75,36.8,-121.75,37.8,-74,40,-73,41'},
function(stream) {
  stream.on('data', function (data) {
    console.log(data);
  });
});

You can use Cole Gillespie's node-finden module to get the geographical coordinates for bounding boxes. Here is how Cole's software looks:

That's it. Super easy way to do all things twitter with ntwitter.

You can install ntwitter through npm as always:

npm install ntwitter

Ntwitter on GitHub: https://github.com/AvianFlu/ntwitter.

Sponsor this blog series!

Doing a node.js company and want your ad to appear in the series? The ad will go out to 14,000 rss subscribers, 7,000 email subscribers, and it will get viewed by thousands of my blog visitors! Email me and we'll set it up!

Enjoy!

If you love these articles, subscribe to my blog for more, follow me on Twitter to find about my adventures, and watch me produce code on GitHub!