[et_pb_section bb_built=”1″ fullwidth=”on” specialty=”off” _builder_version=”3.0.64″ next_background_color=”#000000″][et_pb_fullwidth_post_title admin_label=”Blog Post Header” _builder_version=”3.17.2″ title=”off” meta=”off” categories=”off” comments=”off” featured_placement=”background” text_orientation=”center” module_class=”blog_post_header” title_font_size=”60px” background_blend=”saturation” title_font=”Raleway|on|||” title_text_color=”#274060″ title_letter_spacing=”2px” meta_font=”Raleway||||” meta_font_size=”20″ meta_text_color=”#274060″ meta_letter_spacing=”2px” background_color=”rgba(144,144,144,0.39)” /][/et_pb_section][et_pb_section bb_built=”1″ _builder_version=”3.0.63″ prev_background_color=”#000000″][et_pb_row _builder_version=”3.0.63″][et_pb_column type=”4_4″][et_pb_text admin_label=”Blog Post” _builder_version=”3.17.2″ module_alignment=”left” text_font=”||||” header_font=”||||” max_width_tablet=”50px”]
Originally published: IBM Systems Magazine on 5/13/15
Author Notes: Jade has been renamed to Pug.
One of the primary uses of Node.js is for creating Web applications.
When it comes to popular Web frameworks for Node.js, Expressjs.com is at the top of the list. In this article, I’ll show how to get up and running quickly with a simple app that displays a listing of customers and explain the various technologies involved along the way.
First things first: Create a directory named nodejs_expressjs
and cd
into it, as shown:
$ mkdir nodejs_expressjs && cd nodejs_expressjs
You’ll notice two &&
characters in the middle. This allows me to enter two commands and have them execute in succession. I point this out because you’ll find this in Node.js documentation and I wanted to explain what it does.
Next, we need to use npm, Node Package Manager, to install the express package (aka “module”). Notice it will also download and install all the dependencies of express. This is a big timesaving feature as was discussed in my previous article.
$ npm install express express@4.12.3 node_modules/express ├── merge-descriptors@1.0.0 ├── utils-merge@1.0.0 ├── cookie-signature@1.0.6 ├── methods@1.1.1 ├── range-parser@1.0.2 ├── fresh@0.2.4 ├── cookie@0.1.2 ├── escape-html@1.0.1 ├── content-type@1.0.1 ├── parseurl@1.3.0 ├── vary@1.0.0 ├── finalhandler@0.3.4 ├── serve-static@1.9.2 ├── content-disposition@0.5.0 ├── path-to-regexp@0.1.3 ├── depd@1.0.1 ├── on-finished@2.2.0 (ee-first@1.1.0) ├── qs@2.4.1 ├── debug@2.1.3 (ms@0.7.0) ├── etag@1.5.1 (crc@3.2.1) ├── send@0.12.2 (destroy@1.0.3, ms@0.7.0, mime@1.3.4) ├── proxy-addr@1.0.7 (forwarded@0.1.0, ipaddr.js@0.1.9) ├── type-is@1.6.1 (media-typer@0.3.0, mime-types@2.0.10) └── accepts@1.2.5 (negotiator@0.5.1, mime-types@2.0.10)
Now that ExpressJs is installed, we’re ready to start developing our Web application. Hello World is always a good place to start. Create a file named app.js
and insert the following code into it:
---app.js--- var express = require('express') var app = express() app.get('/', function (req, res) { res.send('Hello World') }) app.listen(8001)
The first line is bringing in the express framework and the second is gaining access to the app object (in the end what we need). Next, we see a call to app.get(...)
. This is saying “whenever an HTTP GET request is made for the site’s root, send the words ‘Hello World’ as the response.” The second parameter is an anonymous function that’s called upon to handle requests to the root of the site. The last line tells the application which port to listen on (in this case port 8001).
Now it’s time to start the application for the first time and see if it works.
You can start the app using the following syntax:
$ node app.js
You should see something like Figure 1 if it worked.
A next step of making this a legitimate application is to create a package.json
file, which will store things like module dependencies, author, version, etc.—much like what the express module uses its package.json
file for. To create a package.json
file, we use the npm init
command, as shown:
$ npm init
That command will prompt you for a number of values with an end goal of generating a package.json
file similar to the following. Notice how it recognized that express was installed already in the node_modules/
folder.
{ "name": "nodejs_expressjs", "version": "0.0.0", "description": "", "main": "app.js", "dependencies": { "express": "^4.12.3" }, "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
Introducing Jade
Next, we want to further develop our application by implementing a template engine to make creating dynamic HTML pages simpler. We’ll select the Jade template engine due to its popularity and flexibility. To install Jade, we will again go to the npm install
command, except this time we’ll add a –save option at the end to declare we’d like this to be retained in the package.json
file.
$ npm install jade --save jade@1.9.2 node_modules/jade ├── character-parser@1.2.1 ├── commander@2.6.0 ├── void-elements@2.0.1 ├── mkdirp@0.5.0 (minimist@0.0.8) ├── with@4.0.3 (acorn-globals@1.0.4, acorn@1.0.3) ├── constantinople@3.0.1 (acorn-globals@1.0.4) └── transformers@2.1.0 (promise@2.0.0, css@1.0.8, uglify-js@2.2.5)
Following we see the modified package.json
file with reference to the Jade module.
{ "name": "nodejs_expressjs", "version": "0.0.0", "description": "", "main": "app.js", "dependencies": { "express": "^4.12.3", "jade": "^1.9.2" }, "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
Next, we need to create a folder to hold our new template engine files so we can keep them separate and organized from the rest of the application. Run the following mkdir
command to create a directory named views
:
$ mkdir views
Within the views directory, create a file named index.jade
and populate it with the following text, making sure to retain the leading spaces. What you see is Jade syntax that aims to make HTML composition significantly less “noisy” (i.e., more whitespace). Indentation in Jade allows us to declare when closing tags should be assumptively inserted. For example, the head
tag will close when the body
tag is encountered because they’re at the same indentation depth.
When you see an equal sign (=), or exclamation plus equal sign (!=), it means the content on the right is a variable made available to the view from the controller. There are many more aspects you can learn about in the Jade reference.
html head title!= title body h1!= message
Following are the necessary Jade additions for views to work in app.js
. First, we use app.set()
to declare the folder where views are stored and then set the view engine to ‘jade’. Once the view engine is set, we can alter the contents of app.get()
to invoke res.render()
, passing the name of the view (index
) and set named variables we want to pass to the view—namely title and message.
app.set('views', __dirname + '/views') app.set('view engine', 'jade') . . . app.get('/', function (req, res) { res.render('index', { title: 'Hey', message: 'Hello there!'}) }) . . .
At this point, we’re ready to start the application again, with the following command. If your application is still running from last time, you’ll need to first end it (i.e., Ctrl + C) and start it again. Doing this will pick up the latest changes in app.js
.
$ node app.js
More Dynamic
Now that we know how to pass variables to the view layer, let’s make it a bit more dynamic by retrieving database rows to display a list of customers from table QIWS.QCUSTCDT
. This table ships with IBM i. To accomplish this, we’re first going to create a new file named customers.jade
in the views directory and populate it with the following content.
Here we learn about Jade’s ability to iterate over a result set using the each keyword. The results variable was provided by the controller (app.js
) and the row variable is occupied with an SQL row at each iteration. LSTNAM
and CUSNUM
are columns in DB2 table QCUSTCDT
.
h1=title table thead tr th Last Name th Customer Number tbody - each row in results tr td=row.LSTNAM td=row.CUSNUM
Next, we need to make changes to app.js
that query DB2 to provide the results variable to the customers.jade
view, as shown. Note, only additions are being shown.
var db = require('/QOpenSys/QIBM/ProdData/Node/os400/db2i/lib/db2') db.init() db.conn("*LOCAL") . . . app.get('/customers', function (req, res) { db.exec("SELECT LSTNAM, CUSNUM FROM QIWS.QCUSTCDT", function(results) { res.render('customers', { title: 'Customers', results: results}) }) })
Next, let’s introduce a feature of displaying more information about a customer when it’s clicked. We can do that by modifying the td tag holding the CUSNUM
value to have a dynamically generated link to that specific customer, as shown. The #{...}
syntax is string interpolation and makes referencing variables in strings significantly easier. Also note the indentation needs to be correct number of spaces.
td: a(href='/customer/#{row.CUSNUM}')=row.CUSNUM
Now we need to add code to app.js
to process requests for specific customers, as shown.
app.get('/customer/:id', function (req, res) { var sql = "SELECT * FROM QIWS.QCUSTCDT WHERE CUSNUM=" + req.params.id db.exec(sql, function(result) { res.render('customer', { title: 'Customer', result: result[0]}) }) })
Note the :id reference in the first parameter of app.get()
. This says that whatever is specified on the URL after /customer/
should be placed into a variable named id
within the req.params
array. We can then access it with the syntax req.params.id
and concat it into the SQL statement. Then we use result[0]
to set the result view variable.
NOTE: This SQL statement is open to injection attacks. I did this on purpose to generate dialogue in the comments section about how to address it with DB2 on i + Node.js. Let the conversation begin!
Restarting your application and navigating to /customers
should reveal the results shown in Figure 2.
Next, we need to create a customer.jade
file in the views directory to facilitate the previous res.render('customer', ...)
, as shown. Note that this view was singular and the other one was plural (customer.jade
vs. customers.jade
) as that’s a common convention.
h1=title table tr td: b Customer Number td=result.CUSNUM tr td: b Last Name td=result.LSTNAM tr td: b Initial td=result.INIT tr td: b Street td=result.STREET tr td: b City State, Zip td= result.CITY + " " + result.STATE + ", " + result.ZIPCOD a(href='/customers') Back
Restart the application, go to the /customers
page and click on a customer. You should see a page similar to Figure 3.
More Insight
I hope you’ve gained insight as to how the ExpressJs framework operates with Node.js to create a simple Web application. As you might guess, we’ve only touched the tip of the iceberg and there are many more features to work through in future articles (e.g., ExpressJs “middleware” is an important topic). I’ve included the entire source for this app in the Litmis Bitbucket Node.js repo for reference.
[/et_pb_text][/et_pb_column][/et_pb_row][/et_pb_section]
One Response