Building a RESTful web service
[code lang=”javascript”]
// 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
[/code]
[code lang=”javascript”]
// 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)
})
[/code]
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!
[code lang=”shell”]
curl –data "title=Example 2" http://localhost:3000/articles
[/code]
Adding a database
There’s no predefiend way to add a database to a Node application, but the process usually involeves the following steps:
- Decide on the database you want to use
- Look at hte popular modular on npm that implement a driver or ORM (Objct-relatioal mapping)
- Add the module to your porject with npm –save
- Create “models” that wrap database access with a JavaScript API
- 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.
[code lang=”javascript”]
app.get(‘/aritcles’, (req, res, err) => {
Article.all(function (err, articles) {
if (err) return next(err)
res.send(articles)
})
})
[/code]
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 articlesArticle.find(id, cb)
– Given an ID, find the corresponding articleArticle.create({}, cb)
– Create an article with a title and contentArticle.delete(id, cb)
– Delete an article
[code lang=”javascript”]
// 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
[/code]