forked from cwbuecheler/node-tutorial-for-frontend-devs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode_tutorial.html
More file actions
1284 lines (1083 loc) · 45.2 KB
/
Copy pathnode_tutorial.html
File metadata and controls
1284 lines (1083 loc) · 45.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<style type="text/css">
body {
width:700px;
line-height:1.8;
font-size:1.1em;
font-family:Calibri;
background:#F5F5FF;
color:#444;
padding:30px;
}
h1,h2,h3,h4,h5 { color:#0066FF; }
h1.title {
font-size:1.75rem;
line-height:1.2;
text-align:center;
}
h2.subtitle {
font-size:1.25rem;
font-style:italic;
color:#666;
font-weight:300;
text-align:center;
}
h5 {
color:#000;
margin:0; padding:2px 5px;
background:rgba(0,0,0,0.1);
border:1px solid #888;
border-bottom:0px;
}
p.byline {
text-align:center;
}
p.indent {
padding-left:3em;
}
p.browsershot img {
width:698px;
border:1px solid #444;
}
h3 {
color:#000;
border-bottom:1px dashed #AAA;
margin:0 0 1em 0;
padding:1em 0 2px 0;
}
pre {
display:block;
clear:both;
padding:15px !important;
margin:0 0 1em 0;
font-family:'Courier New';
font-size:.75rem !important;
margin:0; padding:0;
line-height:1.2;
overflow:auto;
background:#FFF;
border:1px solid #CCC;
}
a:link, a:visited {
color:#22BB44;
background:rgba(255,255,255,0.4);
text-decoration:none;
border-bottom:1px dashed #DDD;
}
a:hover {
color:#33DD66;
background:rgba(255,255,255,0.8);
border-bottom:1px solid #DDD;
}
ul li {
line-height:1.3;
margin-bottom:.5em;
}
</style>
</head>
<body>
<h1 class="title">
The Dead-Simple Step-by-Step Guide for
Front-End Developers to Getting Up and Running with
Node.JS, Express, Jade, and MongoDB
</h1>
<h2 class="subtitle">
Set up the full stack and have a webpage running in 30 minutes.<br />
Make it talk to your DB in another 30.
</h2>
<p class="byline">By <a href="http://cwbuecheler.com" title="Visit Christopher Buecheler's Website" target="_blank">Christopher Buecheler</a></p>
<h3>Introduction</h3>
<p>
There are approximately one hundred million tutorials on the web for
getting a "Hello, World!" app running with Node.js. This is great! It's
especially great if your goal is to greet the world and then give up on
your web career and go spend the rest of your life as, like, a jockey or
something. That doesn't really describe most of us, so we go looking for
more tutorials.
</p>
<p>
In my experience, the "next level" tutorials out there seem about 30
levels further along. We go from "Hello, World!" to building out an entire
blogging system with comments. Which is also great, but a lot of times
those tutorials assume the reader has done a whole bunch of intermediate
fiddling, and they often drop a bunch of big functions on you all at once.
I tend to learn best by making lots of smaller, intermediate steps, and I
don't think I'm the only one.
</p>
<p>
I'm not the only one, right?
</p>
<p>
Well, <a href="http://www.youtube.com/watch?v=1D1cap6yETA" title="GOOD NEWS, EVERYONE!" target="blank">good news, everyone!</a>
I've done the fiddling and read a bunch of tutorials and shouted at my
command prompt until things finally worked. I have a web project up and
running which uses Node.JS, the Express framework, the Jade HTML
pre-processor, and MongoDB for data. I can read to and write from the DB.
From there, the sky's the limit.
</p>
<p>
Here's the deal: I'm going to show you how to get all of this stuff set
up. I'll be assuming that you're a front-end developer who knows
HTML5/CSS3/JavaScript well enough that I don't have to explain those. If
that's you, then this should be a solid primer.
</p>
<p>
Your app will look pretty, it will connect to a DB, it'll get some
results, and it'll do stuff with those results. Then for kicks we'll also
make it save data to the DB. Through it all, I will explain what the code
does, and how to write it, instead of just giving you massive functions to
stare at. We'll go from nothing even installed, to a DB-driven web app
written in a language you fully understand, and the foundation necessary to
build additional functionality into your app. And we'll do it in about 60
minutes of installation and coding time. Is that awesome? I submit that it
is.
</p>
<p>
Let's go.
</p>
<h3>Part I – 15 minutes of installing</h3>
<p>
If you're really starting from scratch, then getting everything up and
running takes a little bit of time. None of it is difficult. I run Windows
8 on my main machine, so it'll be slightly different for those on a Mac or
Ubuntu or other *nix system, but it's principally the same thing in all
cases.
</p>
<h4>Step 1 – Install Node.js</h4>
<p>
This is really easy. Hit the
<a href="http://nodejs.org" title="Node.js Website" target="_blank">Node.js
website</a> and click the big green Install button. It'll detect your OS
and give you the appropriate installer (if for some reason it doesn't,
click the downloads button and grab the one you need). Run the installer.
That's it, you have installed Node.js and, equally important, NPM –
Node Package Manager – which lets you add all kinds of great stuff to
Node quickly and easily.
</p>
<ul>
<li><strong>Open a command prompt</strong></li>
<li>
<strong>cd to the directory in which you wish to keep your test
apps</strong><br />(for the purposes of this tutorial, C:\node).
</li>
</ul>
<h4>Step 2 – Install Express</h4>
<p>
Now that we have Node running, we need the rest of the stuff we're going
to actually use to create a working website. To do that we're going to
install Express, which is a framework that takes Node from a barebones
application and turns it into something that behaves more like the web
servers we're all used to working with (and actually quite a bit more than
that). We need to start with Express, because we're going to use its
scaffolding to get the rest of what we need (more on that in a second). So
let's type this:
</p>
<h5>Command C:\node></h5>
<pre class="prettyprint">
C:\node>npm install -g express
</pre>
<p>
This installs some core Express functionality right into our Node
installation, making it available globally so we can use it anywhere we want.
That's handy. You'll see a bunch of text in your command prompt, mostly a lot
of http 304's and GETs. That's fine. Express is now installed and available.
</p>
<h4>Step 3 – Create an Express Project</h4>
<p>
We're going to use Express and Jade, but not the Stylus CSS preprocessor
(which people often use in this stack). We're just going to use straight CSS
for right now. We have to use Jade or another templating engine to gain access
to our Node/Express-based data. Jade's not hard to learn if you already know
HTML. Just remember that you really have to pay attention to indentation or
things will go badly wrong.
</p>
<p>
Anyway, still in c:\node or wherever you're storing your node apps, type this:
</p>
<h5>Command C:\node></h5>
<pre class="prettyprint">
C:\node>express --sessions nodetest1
</pre>
<p>
Hit enter and watch it go. You'll see something like this:
</p>
<h5>Command C:\node></h5>
<pre class="prettyprint">
C:\node>express --sessions nodetest1
create : nodetest1
create : nodetest1/package.json
create : nodetest1/app.js
create : nodetest1/routes
create : nodetest1/routes/index.js
create : nodetest1/routes/user.js
create : nodetest1/views
create : nodetest1/views/layout.jade
create : nodetest1/views/index.jade
create : nodetest1/public/images
create : nodetest1/public/javascripts
create : nodetest1/public
create : nodetest1/public/stylesheets
create : nodetest1/public/stylesheets/style.css
install dependencies:
$ cd nodetest1 && npm install
run the app:
$ node app
</pre>
<h4>Step 4 – Edit Dependencies</h4>
<p>
OK, now we have some basic structure in there, but we're not quite done.
You'll note that the express installation routine created a file called
package.json in your nodetest1 directory. Open this up in a text editor
and it'll look like this:
</p>
<h5>C:\node\nodetest1\package.json</h5>
<pre class="prettyprint">
{
"name": "application-name",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.4.4",
"jade": "*"
}
}
</pre>
<p>
This is a basic JSON file describing our app and its dependencies. We need
to add a few things to it. Specifically, calls for MongoDB and Monk. Let's
make our dependencies object look like this:
</p>
<pre class="prettyprint">
"dependencies": {
"express": "3.4.4",
"jade": "*",
"mongodb": "*",
"monk": "*"
}
</pre>
<h4>Step 5 – Install Dependencies</h4>
<p>
Now we've defined our dependencies and we're ready to go. Note that the
asterisks tell NPM "just get the latest version" when you run the install,
which we're about to do.
</p>
<p>
Return to your command prompt, cd to your nodetest1 directory, and type this:
</p>
<h5>Command C:\node\nodetest1></h5>
<pre class="prettyprint">
C:\node\nodetest1>npm install
</pre>
<p>
It's going to print out a ton of stuff. That's because it's reading the
JSON file we just edited and installing all the stuff listed in the
dependencies object (yes, including Express – we installed the top
level stuff using the –g flag, but we still have to install some
necessary code for this particular project). Once NPM has run its course,
you should have a node_modules directory which contains all of our
dependencies for this tutorial.
</p>
<p>
You now have a fully-functioning app ready and waiting to run. Let's test
it out! <strong>Change to your nodetest1 dir,</strong> and type:
</p>
<h5>Command C:\node\nodtest1></h5>
<pre class="prettyprint">
C:\node\nodetest1>node app.js
</pre>
<p>
Hit enter. You'll get this:
</p>
<h5>Node Console</h5>
<pre class="prettyprint">
Express server listening on port 3000
</pre>
<p>
Awesome! Open a browser and head for
<strong><a href="http://localhost:3000" title="Localhost" target="_blank">http://localhost:3000</a></strong>
where you will see a welcome to Express page.
</p>
<p class="browsershot"><img src="browsershot1.png" alt="Welcome to Express Page" /></p>
<p>
You are now running your own Node JS webserver, with the Express engine and
Jade HTML preprocessor installed. Not so tough, huh?
</p>
<h3>Part 2 – OK, Fine, let's do "Hello, World!"</h3>
<p>
Fire up your favorite text editor or IDE. I like
<a href="http://www.sublimetext.com/" title="Sublime Text Home" target="_blank">Sublime Text</a>
a lot. Point it at your nodetest1 directory and open app.js. This is kind
of the heart of your, well, app. Not a big surprise there. Here's a
breakdown of what you're going to see:
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
</pre>
<p>
This creates a bunch of basic JavaScript variables and ties them to
certain packages, dependencies, node functionality, and routes. Routes are
kind of like a combination of models and controllers in this setup –
they direct traffic and also contain some programming logic (you can
establish a more traditional MVC architecture with Express if you like.
That's outside of the scope of this article). Back when we set up this
project, Express created all of this stuff for us. We're going to totally
ignore the user route for now and just work in the top level route
(controlled by c:\node\nodetest1\routes\index.js).
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
var app = express();
</pre>
<p>
This one's important. It instantiates Express and assigns our app variable
to it. The next section uses this variable to configure a bunch of Express
stuff.
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
</pre>
<p>
This sets the port, tells the app were to find its views, what engine to
use to render those views (Jade), and calls a few methods to get things up
and running. Note also that the final line is telling Express to serve
static objects from the /public/ dir, but to make them actually seem like
they're coming from the top level. For example, the images directory is
c:\node\nodetest1\public\images … but it is accessed at
<a href="http://localhost:3000/images" title="Localhost Images directory" target="_blank">http://localhost:3000/images</a>
</p>
<p><strong>NOTE:</strong> you will need to change this line:
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
app.use(express.bodyParser());
</pre>
<p>
to:
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
app.use(express.urlencoded());
</pre>
<p>
In order to avoid some warnings in your Node console when you run your
app. This is due to some upcoming changes in Express and its plugins. If
you don't make this change, your app will still run, but you'll see text
about upcoming deprications every time you run it.
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
</pre>
<p>
This lets you do some error-checking during development. It's important
but for the purposes of this tutorial we're not going to do anything with
it.
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
app.get('/', routes.index);
app.get('/users', user.list);
</pre>
<p>
This is telling the app which routes to use when a particular URI is hit.
Note that the "user" variable was declared above, and is mapped to
/routes/user.js – we're calling the list function defined in that
file. Or we would be if we were visiting the users page, but we're
ignoring it, remember?
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
</pre>
<p>
Last but not least, this creates our http server and launches it. Good
times!
</p>
<p>
Now then, let's make stuff. We're not going to just stick "Hello, World!"
on our index page. Instead we're going to use this as an opportunity to
learn a bit more about routes and to take a look at how Jade works for
putting pages together. First, let's add a line to handle a new URI. At the
bottom of the app.get() section of app.js, add this line:
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
app.get('/helloworld', routes.helloworld);
</pre>
<p>
If you were to hit ctrl-c to kill app.js in your command prompt, then
restart it, and then go to
<a href="http://localhost:3000/helloworld" title="Hello World on Localhost" target="_blank">http://localhost:3000/helloworld</a>
you would get a very exciting node error and a crash back to the command
prompt. That's because we haven't modified our route yet to handle that
request. Let's do that! In your text editor, open up your routes folder,
find index.js, and open it. It will look like this:
</p>
<h5>C:\node\nodetest1\routes\index.js</h5>
<pre class="prettyprint">
/*
* GET home page.
*/
exports.index = function(req, res){
res.render('index', { title: 'Express' });
};
</pre>
<p>
Pretty sparse, right? Let's add that new page. My preferred approach is to
add a new route file per top-level directory, but we're not creating a
whole new helloworld directory under /views, so we're just using the index
route. At the bottom of the file, add this code:
</p>
<h5>C:\node\nodetest1\routes\index.js</h5>
<pre class="prettyprint">
exports.helloworld = function(req, res){
res.render('helloworld', { title: 'Hello, World!' });
};
</pre>
<p>
That's all it takes to handle routing the URI, but we don't have any
actual page for res.render to … render. That's where Jade comes in.
Open up your views folder, and then go ahead and open index.jade. Before
you do anything else, <strong>save it as helloworld.jade</strong>.
</p>
<p>
Now take a look at the code:
</p>
<h5>C:\node\nodetest1\views\helloworld.jade</h5>
<pre class="prettyprint">
extends layout
block content
h1= title
p Welcome to #{title}
</pre>
<p>
This is pretty straightforward. It uses ("extends") the file layout.jade
as a template, and then within the content block defined in the layout
file, it sticks a header and a paragraph. Note the use of the "title"
variable which we set above, in our index.js route. This means we don't
even have to change the text at all in order for it to show different
stuff from the home page. But let's change it anyway to:
</p>
<pre class="prettyprint">
p Hello, World! Welcome to #{title}
</pre>
<p>
Save the file, go to your command prompt, ctrl-c to kill app.js if it's
already running, and then type:
</p>
<h5>Command C:\node\nodetest1></h5>
<pre class="prettyprint">
node app.js
</pre>
<p>
In order to restart the server. By the way, this seems a good time to
mention: changes to Jade templates do not require a server restart, but
basically whenever you change a js file, such as app.js or the route
files, you'll need to restart to see changes.
</p>
<p>
SO … with the server restarted, navigate to
<a href="http://localhost:3000/helloworld" title="Hello World on Localhost" target="_blank">http://localhost:3000/helloworld</a>
and enjoy the completely asinine text that gets displayed:
</p>
<p class="browsershot"><img src="browsershot2.png" alt="Hello World Page" /></p>
<p>
OK! So now we've got our router routing us to our view, which we are viewing.
Let's do some modeling. I'll give you a moment if you need to fix your hair or
makeup.
</p>
<h3>Part 3 – Create our DB and read stuff from it</h3>
<h4>Step 1 – Install MongoDB</h4>
<p>
We're leaving our text editor for a bit and going back to our command
prompt. Well, first we're going to our web browser, pointing it to
<a href="http://mongodb.org" title="MongoDB Home" target="_blank">http://mongodb.org/</a>
and downloading Mongo. Click the downloads link in the main menu and snag
the production release that fits your system. For Windows 8 on a 64-bit
processor, we want "64-bit *2008R2+". This will give you a zip file, which
you should unzip to a temp directory. Then you should make a directory
where you want to forever after store Mongo. You could use c:\mongo or
c:\program files\mongo or any other crazy thing you want. It doesn't really
matter – Mongo itself is quite small, and we'll be storing our
database in our nodetest1 directory.
</p>
<p>
Anyway, copy the files in the bin folder within your temp directory to
wherever you want Mongo to live, and you're done. You've installed Mongo. Now
let's make it do stuff.
</p>
<h4>Step 2 – Run mongod and mongo</h4>
<p>
In your nodetest1 directory, create a subdir called "data". Then navigate
to the directory in which you placed your MongoDB files (let's say
C:\mongodb for now). From that directory, type the following:
</p>
<h5>Command C:\mongo\</h5>
<pre class="prettyprint">
mongod --dbpath c:\node\nodetest1\data
</pre>
<p>
You'll see the Mongo server start up. This is going to take a while if it's
the first time, because it has to do some preallocating of space and a few
other housekeeping tasks. Once it says "[initandlisten] waiting for
connections on port 27017", you're good. There's nothing more to do here;
the server is running. Now you need to <strong>open a second command
prompt.</strong> Navigate again to your Mongo installation directory, and
type:
</p>
<h5>Command C:\mongo\</h5>
<pre class="prettyprint">
mongo
</pre>
<p>
You'll see something like the following:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
c:\mongo>mongo
MongoDB shell version: 2.4.5
connecting to: test
</pre>
<p>
Additionally, if you're paying attention to your mongod instance, you'll
see it mention that a connection has been established. All right, you've
got MongoDB up and running, and you've connected to it with the client.
We'll use this client to manually work on our database, for a bit, but it's
not necessary for running the website. Only the server daemon (mongod) is
needed for that.
</p>
<h4>Step 3 – Create a Database</h4>
<p>
Don't worry about "connecting to: test" … that's just the default
database Mongo decides to use if you don't specify one on the command
line, which we didn't because it's not important right now. It doesn't
actually even create the "test" database unless you add a record. It'd
be totally fine to just work in that database for right now, but let's
make one of our own. In your Mongo console, type the following:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
use nodetest1
</pre>
<p>
Now we're using the database "nodetest1." Like with "test", nothing
actually exists yet. To make the database exist, we have to add some
data. We're going to start off by doing that right inside of the Mongo
client.
</p>
<h4>Step 4 – Add some Data</h4>
<p>
My favorite thing about MongoDB is that it uses JSON for its structure,
which means it was instantly familiar for me. If you're not familiar with
JSON, you'll need to do some reading, as I'm afraid that's outside the
scope of this tutorial.
</p>
<p>
Let's add a record to our collection. For the purposes of this tutorial,
we're just going to have a simple database of usernames and email
addresses. Our data format will thus look like this:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
{
"_id" : 1234,
"username" : "cwbuecheler",
"email" : "cwbuecheler@nospam.com"
}
</pre>
<p>
You can create your own _id assignment if you really want, but I find it's
best to let Mongo just do its thing. It will provide a unique identifier
for every single top-level collection entry. Let's add one and see how it
works. In your Mongo client, type this:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
db.usercollection.insert({ "username" : "testuser1", "email" : "testuser1@testdomain.com" })
</pre>
<p>
Something important to note here: that "db" stands for our database, which
as mentioned above we've defined as "nodetest1". The "usercollection" part
is our collection. Note that there wasn't a step where we created the
"usercollection" collection. That's because the first time we add to it,
it's going to be auto-created. Handy. OK, Hit enter. Assuming everything
went right, you should see … nothing. That's not very exciting, so
type this:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
db.usercollection.find().pretty()
</pre>
<p>
In case you're curious, the .pretty() method gives us linebreaks. It will return:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
{
"_id" : ObjectId("5202b481d2184d390cbf6eca"),
"username" : "testuser1",
"email" : "testuser1@testdomain.com"
}
</pre>
<p>
Except, of course, your ObjectID will be different, since as mentioned,
Mongo is automatically generating those. That's all there is to writing
to MongoDB from the client app, and if you've ever worked with JSON
services before, you are probably going "oh, wow, that's going to be easy
to implement on the web." … you're right!
</p>
<p>
A quick note on DB structure: obviously in the long run you're unlikely
to be storing everything at the top level. There are a ton of resources
on the internet for schema design in MongoDB. Google is your friend!
</p>
<p>
Now that we've got one record, let's add a a couple more. In your Mongo
console, type the following:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
newstuff = [{ "username" : "testuser2", "email" : "testuser2@testdomain.com" }, { "username" : "testuser3", "email" : "testuser3@testdomain.com" }]
db.usercollection.insert(newstuff);
</pre>
<p>
Note that, yes, we can pass an array with multiple objects to our
collection. Handy! Another use of db.usercollection.find().pretty() will
show all three records:
</p>
<h5>Mongo Console</h5>
<pre class="prettyprint">
{
"_id" : ObjectId("5202b481d2184d390cbf6eca"),
"username" : "testuser1",
"email" : "testuser1@testdomain.com"
}
{
"_id" : ObjectId("5202b49ad2184d390cbf6ecb"),
"username" : "testuser2",
"email" : "testuser2@testdomain.com"
}
{
"_id" : ObjectId("5202b49ad2184d390cbf6ecc"),
"username" : "testuser3",
"email" : "testuser3@testdomain.com"
}
</pre>
<p>
Now we're going to start actually interacting with the web server and site
that we set up earlier.
</p>
<h4>Step 5 – Hook Mongo up to Node</h4>
<p>
This is where the rubber meets the road. Let's start by building a page
that just spits out our DB entries in a mildly pretty form. Here's the
HTML we're shooting to generate:
</p>
<pre class="prettyprint">
<ul>
<li><a href="mailto:testuser1@testdomain.com">testuser1</a></li>
<li><a href="mailto:testuser2@testdomain.com">testuser2</a></li>
<li><a href="mailto:testuser3@testdomain.com">testuser3</a></li>
</ul>
</pre>
<p>
I know this isn't rocket science, but that's the point. We're just doing
a simple DB read-and-write in this tutorial, not trying to build a whole
website. First things first, we need to add a few lines to our main
app.js file – the heart and soul of our app – in order to
actually connect to our MongoDB instance. Open C:\node\nodetest1\app.js and
at the top you'll see:
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
</pre>
<p>
Now add these three lines:
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');
// New Code
var mongo = require('mongodb');
var monk = require('monk');
var db = monk('localhost:27017/nodetest1');
</pre>
<p>
These lines tell our app we want to talk to MongoDB, we're going to use
Monk to do it, and our database is located at localhost:27017/nodetest1.
Note that 27017 is the default port your MongoDB instance should be
running on. If for some reason you've changed it, obviously use that port
instead. Now look at the bottom of the file, where you have this:
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
app.get('/', routes.index);
app.get('/users', user.list);
app.get('/helloworld', routes.helloworld);
</pre>
<p>
Add the following line at the bottom:
</p>
<h5>C:\node\nodetest1\app.js</h5>
<pre class="prettyprint">
app.get('/userlist', routes.userlist(db));
</pre>
<p>
This line says that when a user navigates to /userlist, we should pass
the "db" variable (our database object) to the userlist route. But we
don't HAVE a userlist route yet, so it's time to create one.
</p>
<h4>Step 6 – Pull your data from Mongo and display it</h4>
<p>
Open up C:\node\nodetest1\routes\index.js in your editor. It's still got
the index route, and the goofy /helloworld route. Let's add a third:
</p>
<h5>C:\node\nodetest1\routes\index.js</h5>
<pre class="prettyprint">
exports.userlist = function(db) {
return function(req, res) {
var collection = db.get('usercollection');
collection.find({},{},function(e,docs){
res.render('userlist', {
"userlist" : docs
});
});
};
};
</pre>
<p>
OK … that's getting fairly complicated. All it's really doing,
though, is running a wrapper function to which we pass our db variable,
and then doing a page render just like the other two "exports" in this
route file. We then tell it which collection we want to use
('usercollection') and do a find, then return the results as the variable
"docs". Once we have those documents, we then do a render of userlist
(which will need a corresponding Jade template), giving it the userlist
variable to work with, and passing our database documents to that
variable.
</p>
<p>
Next let's set up our Jade template. Navigate to C:\node\nodetest1\views\
and open index.jade. Once again, <strong>immediately save it as
userlist.jade</strong>. Then edit the HTML so it looks like this:
</p>
<h5>C:\node\nodetest1\view\userlist.jade</h5>
<pre class="prettyprint">
extends layout
block content
h1.
User List
ul
each user, i in userlist
li
a(href="mailto:#{user.email}")= user.username
</pre>
<p>
This is saying that we're going to pull in the set of documents we just
called userlist over in the route file, and then for each entry (named
'user' during the loop), get the email and username values from the object
and put them into our html. We've also got the count – i –
handy in case we need it, though in this instance we don't.
</p>
<p>
We're all set. Save that file, and let's restart our node server. Remember
how to do that? Go to your command prompt, head for C:\node\nodetest1\ and
ctrl-c to kill app.js if it's still running from way back before. Then
type:
</p>
<h5>Command C:\node\nodetest1\</h5>
<pre class="prettyprint">
C:\node\nodetest1>node app.js
</pre>
<p>
Now open your browser and head to
<a href="http://localhost:3000/userlist" title="Localhost DB Output Page" target="_blank">http://localhost:3000/userlist</a>
and marvel in the results.
</p>
<p class="browsershot"><img src="browsershot3.png" alt="DB Ouput Page - Default Data" /></p>
<p>
You're now pulling data from the DB and spitting it out onto a web page. Nice!
</p>
<p>
There one more thing I badly wanted to cover in this tutorial, but because
it's already about as long as the Bible, I'm going to breeze through it
here. You could very easily change your userlist view from an
Express-driven web page complete with Jade template to a plain old JSON
response. You could then access this with AJAX and manipulate it on the
client-side, with jQuery for example, instead of on the server side. I
won't object if that's the way you want to go, but I can't cover it here,
so I'll just point you to
<a href="http://expressjs.com/api.html#res.json" title="res.json at Express Documentation" target="_blank">res.json</a>
and say "go for it, it's not too hard."
</p>
<p>
Let's finish this up.
</p>