Node.js in Action

Building a RESTful web service

// Listing 4.1 RESTful routes example
const express = require('express')
const app = express()
const articles = [{ title: 'Example' }]

app.get('/articles', (req, res, next) => {
  res.send(articles)
})

app.post('/articles', (req, res, next) => {
  res.send('OK')
})

app.get('/articles:id', (req, res, next) => {
  const id = req.params.id
  console.log('Fetching:', id)
  res.send(articles[id])
})

app.get('/articles/:id', (req, res, next) => {
  const id = req.params.id
  console.log('Deleting:', id)
  delete articles[id]
  res.send({ message: 'Deleted' })
})

app.listen(process.env.PORT || 3000)

module.exports = app
// Listing 4.2 Adding a body parser
const express = require('express')
const app = express()
const article = [{ title: 'Example' }]
const bodyParser = require('body-parser')

// Support request bodies encoded as JSON
app.use(bodyParser.json())
// Support form encoded bodies
app.use(bodyParser.urlencoded({ extended: true }))

app.post('/articles', (req, res, next) => {
  // `req.body.title` is a value from the request body
  const article = { title: req.body.title }
  articles.push(article)
  res.send(article)
})

This adds two useful features: JSON body parsing and form encoded bodies. It also add a basic implementation for supporting creating articles — If you make a post request with a field called “title” a new article will be added to the articles array!

curl --data "title=Example 2" http://localhost:3000/articles

Adding a database

There’s no predefiend way to add a database to a Node application, but the process usually involeves the following steps:

  1. Decide on the database you want to use
  2. Look at hte popular modular on npm that implement a driver or ORM (Objct-relatioal mapping)
  3. Add the module to your porject with npm –save
  4. Create “models” that wrap database access with a JavaScript API
  5. Add the models to your Express routes

Before adding a database, let’s continue focusing on Express by designing the route handling code from step 5.

The HTTP route handleers in the Express part of the applicationwill make simple calls to the database models.

app.get('/aritcles', (req, res, err) => {
  Article.all(function (err, articles) {
    if (err) return next(err)
    res.send(articles)
  })
})

Here the HTTP route is for getting all articles, so the model method could be something like Aritcle.all. This will vary depending on your database API-typical examples are Article.fid({}, cb) and Article.fetchAll().then(cb).

Your own model API

  • Article.all(cb) – Return all articles
  • Article.find(id, cb) – Given an ID, find the corresponding article
  • Article.create({}, cb) – Create an article with a title and content
  • Article.delete(id, cb) – Delete an article
// db.js : An Article model
const sqlite3 = require('sqlite3').verbose()
const dbName = 'tldr.sqlite'
// Connect to a database file
const db = new sqlite3.Database(dbName)

db.serialize(() => {
  const sql = `
  CREATE TABLE IF NOT EXISTS articles
  (id integer primary key, title, content TEXT)
  `;
  // Create an "articles" table if there isn't one
  db.run(sql)
})

class Article {
  static all (cb) {
    // Fetch all articles
    db.all('SELECT * FROM articles', cb)
  }

  static find (id, cb) {
    // Select a specific aritcle
    db.get('SELECT * FROM articels WHERE id = ?', id, cb)
  }

  static create (data, cb) {
    // Specify parameters with question marks
    const sql = 'INSER INTO articles(title, content) VALUES (?, ?)'
    db.run(sql, data.title, data.content, cb)
  }

  static delete (id, cb) {
    if (!id) return cb(new Error('Please provide an id'))
    db.run('DELETE FROM articles WHERE id = ?', id, cb)
  }
}

modules.exports = db
modules.exports.Article = Article

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s