Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Another Node Experiment: AndKittens

DZone's Guide to

Another Node Experiment: AndKittens

· Java Zone
Free Resource

Make it happen: rapid app development on Kubernetes as a managed service.

So, I know I've said this before, but I like to build completely useless, but fun, toys. Frankly, if I let practicality be my guide I'd probably never build anything and I'm not sure how I'd learn. Please keep that in mind as you read the following. I built what follows as an excuse to practice my Node chops more, not to bring anything actually worthwhile into the Internets. Unless you like kittens. If so, this is epic.

About a week or so ago I saw a tweet from Christian Heilmann talking about a new site, SynthCats. As you can probably guess, this is a site filled with pictures of cats with keyboards and synthesizers. As an unapologetic child of the 80s and new wave, I could really get behind a site like this. It got me thinking, though; you could probably take any combination of cats and come up with a fun site.

From that sprouted the idea behind AndKittens. I imagined a site where you could simply enter a URL, like pugs.andkittens.us and see a collection of pictures of pugs with kittens.

Building this required a few different parts. The first was support for a wildcard domain and introspection of that domain from within Node. That was actually pretty trivial and I covered it in a quick blog post last week: Node.js Quickie: Checking the Current Domain Name.

Using that code as a stepping point, I simply introspect the subdomain and load one of two views:

function getSubdomain(h) {
  var parts = h.split(".");
	if(parts.length == 2) return "www";
	return parts[0];
}

exports.index = function(req, res) {
	var subdomain = getSubdomain(req.headers.host);
	if(subdomain === 'www') {
		res.render('index');
	} else {
		res.render('viewer',{title:subdomain + ' and Kittens'});
	}
};

The second aspect was supporting the dynamic image search. Google would be a natural fit for this, but they don't have an API for their search service. Instead I turned to Microsoft and their Bing Search API. They made it a bit difficult to sign up and their docs were a bit hard to parse (Word docs, really? I don't mind Word at all but I expect my API docs to be web pages!), but once I got past the initial setup it was pretty trivial to call from Node.

I wrote a quick wrapper library. Actually, I wouldn't really call this a library as it is focused on image search only, but it could be made more generalized if folks want to take it and run. Here is the code.

var https = require('https');
var qs = require('querystring');

BingSearch = function(key) {
  this.key = key;
}

BingSearch.prototype.search = function(s,cb) {
	
	var result = {success:false};
	console.log("Bing Search for "+s);
	var options = {
		hostname:"api.datamarket.azure.com",
		path:"/Bing/Search/Image?Query=%27" + qs.escape(s) + "%27&Adult=%27strict%27&$format=json",
		method:"GET",
		auth:":"+this.key,
		rejectUnauthorized:false
	}

	https.get(options, function(res) {
		console.log("Got response: " + res.statusCode);
		var body = "";
		
		res.on('data', function (chunk) {
			body += chunk;
		});
		
		res.on('end', function() {
			result.success = true;
			var data = JSON.parse(body);
			result.data = data.d.results;
			cb(result);
		});

	}).on('error', function(e) {
		console.log("Got error: " + e.message);
		cb(result);
	});

}

exports.BingSearch = BingSearch;

Two crucial things here. First, Node.js throws an error if you try to use an HTTPS site with a certificate it doesn't recognize. It didn't like the Microsoft certificate and, frankly, I don't know why. I trust Microsoft, though. (Really.) I used the rejectUnauthorized argument to tell Node.js to trust that I knew what I was doing and just hit the damn API. (I really wish ColdFusion would allow for this!) The second thing to remember is that Microsoft loves to use uppercase in their arguments. If you don't match the case precisely then you will get an error. What's odd is that they aren't consistent. Note the $format=json part at the end.

In my opinion, unless there is some crucial performance reason, it is silly to require a precise case match on arguments.

Anyway, you get the idea. That's the back end. The front end was done by my buddy Tai. Tai is a smart cookie I've known for many years, but oddly he doesn't have a blog or web site so he doesn't get a link from me here. He designed the "viewer" aspect of the site and did the nice transitions from one image to another. Right now there is a slight bug in that if an error fails to load, we don't immediately go to the next image (and dump it from the result set).

If you want to see the code, check out the GitHub repo here: https://github.com/cfjedimaster/AndKittens. Yes, I realize my Bing key is in there. I need to strip that out and I'll probably max out my free key usage by the end of the month. It happens.

That's it. Tomorrow I'm going to talk about the hosting service I used, Modulus.


Tutorial: WordPress as distributed microservices on Kubernetes.

Topics:

Published at DZone with permission of Raymond Camden, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}