Node.js App Basics - Part 4

23 Nov 2013

Feel free to review the other posts in this series:

==

Alright, let’s finish this basic application up.

We’ve been using “connect” as the basis for our middleware so far. In many cases, you’ll want to be able to set up handling for specific routes using specific REST verbs, as well as read request parameters and easily pipe non-html data to the client. “express” is a package that extends “connect”, and is essentially the “gold-standard” from which to build HTTP applications in Node.js

Install express now:

	$ npm install express --save

We will use express in place of connect for the remainder of this tutorial.

As I have mentioned before, npm has a huge number of packages, and finding something that works the way you want can be a little bit daunting.

We’re working on a simple UI that can take a query from the user, and locate entries from Wikipedia that make sense.

I have located a package that can take care of the actual query to wikipedia ‘wikijs’, so let’s install that in our project now.

	$ npm install wikijs --save

Next, we want to provide a basic GET endpoint to our connect server that accepts a query, and returns some JSON answers. Update your “server.js” file as folllows:

//We're switching to "express", instead of "connect", 
//because it _extends connect_ with some useful middleware/http 
//request handling.
var express = require('express');

var Wiki = require("wikijs");

//we're still using Node's built in HTTP server, so let's pull it in.
var http = require('http');

//create our middleware stack (just send a basic message for now):
var app = express()
	//add logging to all requests
	.use(express.logger())
	 //serve "static files from the public directory"
	 .use(express.static(__dirname + '/public'))
	 
	 // adding a new search to wikipedia, limiting to 25 entries, for now.
	 // notice that we are now using ".get" instead of ".use", Express
	 // adds .get()/.post()/.put()/.delete()/.all() methods to allow the creation of 
	 // RESTful HTTP endpoints
	 .get('/search', function(req, res, next){

	 	//Express also makes it easy to read GET/POST params from the 
	 	//request using .param()
	 	var query = req.param('q');
	 	Wiki.search(query, 25, function(err, results){
	 		if(err){
	 			next(err);
	 		}else{
	 			//Express also allows us to write non-html responses
	 			//easily, like JSON.
	 			res.json(results);
	 		}
	 	})
	 })
	//do the original request handling added in part 1.
	.use(function(request, response){
		response.write('Hello from connect!');
		response.end();
	});

//start a server on port 3000, any request that comes in should call
//the "app" function that is our middleware stack from above.
http.createServer(app).listen(3000);

Go ahead and fire up “supervisor server.js” and navigate to http://localhost:3000/search?q=node

If everything is working, this should produce an array of json results, now all we have to do is wire up the interface to take advantage of this new method.

<!DOCTYPE html>
<html>
<head>
	<style>
*{
	font-family: arial;
	padding: 0px;
	margin: 0px;
}
html{
	width: 100%;
	background: #cfcfcf;
}
body{
	text-align: center;
	width: 80%;
	margin: 20px auto;
	padding: 10px;
	background: white;
	border-radius: 5px;
	box-shadow: 0px 0px 5px 0px;
}
input{
	width:50%;
	font-size: 20px;
	padding: 5px;
}
#results{
	min-height: 200px;
	padding: 10px;
}
	</style>
</head>
<body>
	<input type="text" id="query" placeholder="Search Wikipedia">
	<div id="results">You can query wikipedia by typing a search above.</div>
	<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
	<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
	<script>
		$(function(){
			// this is a pretty sloppy way of doing the this, but it's done here for 
			// demo purposes. Client-side scripting is a topic for another blog. :-)
			var results = $('#results');
			$('#query').keyup(_.debounce(function(){

				var query = $(this).val();
				if(query !== ''){
					results.empty().append('<i>Searching...</i>');
					$.get('/search',{q : query}).success(function(data){
						results.empty();
						_.each(data, function(element){
							results.append('<a target="_blank" href="https://en.Wikipedia.org/wiki/' + element + '">' + element + '</a><br/>');
						});
					}).error(function(){
						results.empty().append('Oops, something bad happened, we couldn\'t get any Wikipedia results' );
					});
				}
				else{
					results.empty().append('You can search wikipedia by typing a query above.');
				}
			}, 250))
		})
	</script>
</body>
</html>

Now, navigate to http://localhost:3000, if everything went well, you should now be able to type a query and get links to wikipedia articles.

Obviously, this is a pretty silly, because wikipedia actually provides this functionality, but it hopefully shows how to create a basic node web-application, from end to end.

In future posts, I’ll go into some of the other aspects of building production-ready node.js applications, and some other “gotchas” that I’ve been learning about along the way.