Using the OMDB (IMDB) API to Create an Application Using Node.js

In this post I’m going to build a Node.js app that allows that user to search through the movie database and then build a page of results. It’s not going to be pretty, it’s just (as all my posts are) a reference for my future self who has forgotten all this stuff.

Exploring the Open Movie Database API

Before getting started creating the app. Let’s take a look at the API we’re going to be working with to populate our pages. The IMDB (Internet Movie Database) doesn’t have a working API that we can use so someone, I would say reverse engineered it to create the OMDB API (Open Movie Database).

This means we can retrieve information off of IMDB without having to have a developers account with them. You can visit OMDb API by clicking the link (opens in new window) but I’m going to go through it here anyway.

The first thing to talk about would be usage. For example, we would send our API and data requests through the following URL’s.

Data requests:

http://www.omdbapi.com/?apikey=[yourkey]&

Poster API requests:

http://img.omdbapi.com/?apikey=[yourkey]&

There are two main ways we can access this API, either by ID or Title, or by search.

If you know the specific ID of a movie then you can access it via the API and get all of the information you need about that one specific movie and that is what you get when you access the API via the ID or Title route. If however you want to search and get 10 results then you would opt for the Search route.

From the parameters list above, we can see that the only thing that is required to perform a Search API request is to include the letter “s” (and that is required for the method). By visiting the following URL (after attaining an API key)…

http://www.omdbapi.com/?s=star&apikey= put your own API key here

The following json file was returned in the browser…

Seeing as I put the word star in the URL, the data that was returned was the 10 most relevant results based on that word. If I wanted to search star wars for example I would use…

http://www.omdbapi.com/?s=star+wars&apikey= put your own API key here

…and that would give me a more refined and “star wars” specific set of results (as opposed to having some star trek movies in there as we can see in the above picture).

I am going to build a really basic app that will allow a user to search a movie title and be returned the results. I’m not really interested in making it pretty; probably won’t even use CSS. I’m more focused on functionality and illustrating the process of using an API.

Creating the project

The first thing to do is create a new project folder and initialise node package manager to prepare the project folder for the app (create package.json file etc).

npm init

Once done, install the packages we’re likely to use ensuring we save them as dependencies to the newly created package.json file.

npm install express ejs request body-parser --save

When we check the package.json file we see that the dependencies were added to the project.

// Using the –save syntax on the command line (see above) is what creates these entries.

Creating the folder structure:

For this project we’re going to need the following in our server starting from the project folder:

  • Folder: appname

    // Root folder

    mkdir appname
    • File: index.js

      // The JavaScript file for our app.

      touch index.js

      // The above works in goorm IDE.

    • Folder: lib

      // To store the CSS styling (guess I am styling a bit).

      mkdir lib
      • File: style.css

        // The style sheet

        touch lib/style.css
    • Folder: views

      // This is the folder that is made public to the ejs package

      mkdir views
      • File: page.ejs

        // This is the html or “embedded JavaScript” file that we’ll show to the user

        touch views/page.ejs
      • File: error.ejs

        // The error page

        touch views/error.ejs
      • File: results.ejs

        // Where we’re going to render the results.

        touch views/results.ejs
      • Folder: templates

        // This is where we’ll store the template files

        mkdir views/templates
        • File: header.ejs

          // File for header HTML content

          touch views/templates/header.ejs
        • File: footer.ejs

          // File for footer HTML content

          touch views/templates/footer.ejs

Once all that is in place we can get on to importing all of the various packages that we created (we may not use all of them I just wrote all of the ones on this page as those are the once I usually use in the projects – at the moment).

Configuring Packages

The first thing that needs to happen is we need to tell our program that we want to use all of the packages that we installed.

express

var express = require("express");
var app = express();
// Need to tell ejs about the library volder
app.use(express.static("lib"));

Add the above code to your index.js file. Line 1 is telling the program that we need to include the express library (that we have installed) so that we can use it. Line creates a new variable called app and sets it to express (kind of like a wrapper so we can easily refer to it later on) and then the third line notifies our program that there is another folder that it needs to look in aside from just views (which it has access to by default) – allowing our program to find our styling sheet. That’s what is needed for express.

ejs

app.set("view engine", "ejs");

This line will stop us from having to tell our program that our files are .ejs files (hence we can write “page-name” instead of “pagename.ejs” everytime we refer to a file).

// Once you’ve told express about the “lib” directory it will look for a matching file in one of thos directories.

body-parser

var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended: true}));

To configure body-parser we create a new variable called “bodyParser” and then copy and paste the second line (because I’m not going to learn it – out of the scope of this post).

request

var request = require("request");

Add this line to implement the request package into our app and we’re good to go!

Getting our app to “listen” for activity

Now we need to get our server to listen for get and post requests by adding the following code to the JavaScript file

app.listen(3000, function() { 
  console.log('Server listening on port 3000'); 
});

When we connect to the server correctly we’ll be given the message “Server listening on port 3000” so we know we’re good.

Sorting out the routes that we need

Now we can sort out the routes that we want to direct our users to the places they want to go. In this instance we’re just going to build the whole app from the home page. We already created a file called “page.ejs” inside of our views folder so we can just refer to that.

// To reiterate: ejs will automatically look in “views” folder by default and in this instance it will also look in the “lib” folder.

To do this we write a “get” request as shown in the code below (we don’t need to write “index.ejs” we just leave it as “index”).

app.get("/", function(request, response){
    response.render("page");
});

We can also setup a new get request that displays an error to the user (in the console) by using the following:

app.get("*", function(request, response){
    response.render("error");
});

// Be sure that this is the last route on the page because it will catch anything that hasn’t got a route; rather than executing for any route (including ones declared below).

HTML Template & Style.css Files

Lastly, open up the “page.ejs” and “results.ejs” file in the “views” folder and add the HTML boilerplate to it and save it.

<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="/style.css">
	<title>Node API Project</title>
</head>
<body>
    <h1>Test Title</h1>
    <p>Demo Text</p>
</body>
</html>

Also, add some nasty styling to the style.css sheet to make sure it’s working.

That should be enough to, once you save everything and run the program from the console (I used nodemon to do that, it’s awesome, you should check it out) and visit the server and we should see some nasty creation.

Now we’re setup with a bare bones project file, we could do the same to our page in the views folder called “error.ejs”. Copy over the HTML boilerplate and adjust the text.

Then when we visit any page on the website other then the root we’re shown an error message.

Now that that is all setup. The last thing that we can do is to create some template files (create a header and footer for our ejs files so we don’t need to write it out every time). Everything from the code below was cut from page.ejs and pasted into header.ejs and saved.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="/style.css">
    <title>Node API Project</title>
</head>
<body>

The closing “body” and html “tags” were cut and paste to footer.ejs and a line (to simulate footer text was added – for fun).

Once this was done, the page.ejs and error.ejs files were adjusted respectively:

// New HTML for page.ejs
<%- include("templates/header"); %>
    <h1>Test Title</h1>
    <p>Demo Text</p>
<%- include("templates/footer"); %>
// New HTML for error.ejs
<%- include("templates/header"); %>
    <h1>ERROR, This page does not exist</h1>
    <p>OOOOOPs!!</p>
<%- include("templates/footer"); %>

Working with the OMDB API

OK. Now we’re at the point where we can begin retrieving information form IMDB and displaying it on our site. To do this we’re going to setup a new route (in our index.js file above the “*” route) and this time we’re going to setup a “get” request route as the “/result” directory in our app.

This is the code for the results routes:

app.get("/results", function(req, res){	
  request("https://www.omdbapi.com/?s=star+wars&apikey=key", 
    function(error, response, body){
      // Setup an if statement to catch any errors
      // which is optional but good practice 
      if(!error && response.statusCode == 200){
        // For now just print the body of the returned JSON
        res.send(body);	
      }
  });
});

When we visit our app URL/results (in Goorm under Project > Running And URL Port) we’ll now see the 10 most relevant results based on our keyword (in this instance “star wars” was used – I won’t include an image because its massive).

Full index.js file to this point

var express = require("express");
var request = require("request");
var app = express();
// Need to tell ejs about the library volder
app.use(express.static("lib"));

	
app.set("view engine", "ejs");

var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended: true}));

app.listen(3000, function() { 
  console.log('Server listening on port 3000'); 
});

app.get("/", function(request, response){
    response.render("page");
});

app.get("/results", function(req, res){	
  request("https://www.omdbapi.com/?s=star+wars&apikey=key", 
    function(error, response, body){
      // Setup an if statement to catch any errors
      // which is optional but good practice 
      if(!error && response.statusCode == 200){
        // For now just print the body of the returned JSON
        res.send(body);	
      }
  });
});

app.get("*", function(request, response){
    response.render("error");
});

OK, now that’s working it’s time to extract some data from this page we’ve just created. To do that we’re going to take a look at the returned data.

The returned page contains the following: “Search” (which contains our array of movies), “totalResults” and the “Response”. The information we’re interested in is in search.

We can see from above that the movies are inside “Search:” which is an array (denoted by the first “[“) of objects (movies) each of which having their own properties (title, year, imdbID, type and a movie poster). We can access any of these elements for any of the movie objects (we have 10) in our list and that’s the next thing we’re going to do.

At the moment, we can’t simply access nth element of each item in the array because the “body” that is being returned to us is currently in the form of a string, and in order for us to be able to use this data, we need to convert it into an object.

To do this we need to parse the data (utilising the body-parser package we previously installed) by populating a new variable with the parsed string (I’ll add the surrounding code for context).

app.get("/results", function(req, res){	
	request("https://www.omdbapi.com/?s=sting&apikey=thewdb", 
		function(error, response, body){
			if(!error && response.statusCode == 200){
				// res.send(body); < what we had before
				var data = JSON.parse(body);
				res.render("results", {data: data});
			}
	});
});

Now when we start up our app and visit our “/results” route; we see one single object (the 0th object in our array).

Happy days, now we can loop through the results and retrieve whatever information we need from our array. If we just want the title we can say:

res.send(data["Search"][0]["Title"]);

And that will return a string of text (the title of the movie – which we can now put into our web page.)

Displaying the results on our results page

We have access to the following information through the API for each of the 10 titles returned to us “Title”, “Year”, “imdbID”, “Type”, “Poster”. I’m going to Create a 5 column page and display 2 rows of films and include the Title, the year and the poster.

The last thing we did was tell our “/results” route that we wanted it to render the results.ejs page and we parsed the data through to that page. Now we need to go to our results page and add that information to the page.The last thing we did was tell our “/results” route that we wanted it to render the results.ejs page and we parsed the data through to that page. Now we need to go to our results page and add that information to the page.

<%- include("templates/header"); %>
    <h1>Results Page</h1>
    <% data["Search"].forEach(function(movie){ %>
        <p>	
            <img src="<%- movie["Title"]; %>">
        </p>
    <% }) %>
<%- include("templates/footer"); %>

For now I just printed all of the posters out in <p> tags by using the forEach syntax as shown above.


I’m going to leave this post here. It’s real long and I’m only half way through. The next step is to create a template for the page and populate the page with the returned data each time a user makes a request and for now I’m happy that I covered both setting up a project (getting all of the nitty gritty things I’ve learned recently into copy and paste format) as a bonus and the objective of the post which was how to use an API.

Thanks for reading.

Leave a Comment

Your email address will not be published. Required fields are marked *