What is REST and why is it matters? REST, stands for Respresentational State Transfer, is a pattern that defines our routes
A route is a mapping between HTTP routes and CRUD (Create, Read, Update, Destroy)
There are 7 RESTful routes: Index, New, Create, Show, Edit, Update, Destroy
npm init
npm install express, mongoose, body-parser, ejs --save
touch app.js
mkdir views
var mongoose = require("mongoose"),
mongoose.connect("mongodb://localhost/restful_blog_app", {useMongoClient: true});
//Setup Schema
var blogSchema = new mongoose.Schema({
title: String,
image: String,
body: String,
//set a default value
created: {type:Date,default: Date.now}
});
//Compile into a Model
var Blog = mongoose.model("Blog", blogSchema);
mkdir views/partials
touch views/header.ejs views/footer.ejs
<% include ./partials/header %>
<% include ./partials/footer %>
mkdir public
mkdir public/stylesheets
touch public/stylesheets/app.css
`Javascript
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css">
A table of all 7 RESTful routes
// Syntax
app.get(path, callback [, callback ...])`
app.get("/", function(req, res){
res.redirect("/blogs");
});
app.get("/blogs", function(req, res){
Blog.find({},function(err, blogs){
if (err){
console.log("Error!");
} else {
res.render("index", {blogs:blogs});
}
});
});
app.get("/blogs/new", function(req, res){
res.render("new");
});
If the verb is a POST and you are using bodyParser, then you should be able to get the form body in you function with req.body
. That will be the parsed JS version of the POSTed form.
app.post("/blogs", function(req, res){
console.log("Before sanitize: " + req.body.blog.body);
//sanitize create: form input
req.body.blog.body = req.sanitize(req.body.blog.body);
console.log("=====================");
console.log("After sanitize: " + req.body.blog.body);
//create blog
Blog.create(req.body.blog, function(err, newBlog){
if (err) {
res.render("new");
} else {
//redirect
res.redirect("/blogs");
}
});
});
Express function req.params
will return parameters in the matched route. If your route is /users/:id and you make a request to /user/5 - req.params
would yield {id: "5"}
app.get("/blogs/:id", function(req, res){
Blog.findById(req.params.id, function(err, foundBlog){
if (err){
res.redirect("/blogs");
} else {
res.render("show", {blog:foundBlog});
}
});
});
app.get("/blogs/:id/edit", function(req, res){
Blog.findById(req.params.id, function(err, foundBlog){
if (err){
res.render("/blogs");
} else {
res.render("edit", {blog:foundBlog});
}
});
});
app.put("/blogs/:id", function(req, res){
//sanitize form update
req.body.blog.body = req.sanitize(req.body.blog.body);
Blog.findByIdAndUpdate(req.params.id, req.body.blog, function(err, updatedBlog){
if (err){
res.redirect("/blogs");
} else {
res.redirect("/blogs/" + req.params.id);
}
});
});
As HTML form can only handle GET & POST requests, when you send a PUT request during EDIT and UPDATE, it will default as a GET request
Rather than defining another route for POST request, you can achieve this by using package method-override in Express
To install package "method-override" in express:
npm install method-override --save
Then, put the code ?_method=PUT
in the form:
<form class="ui form" action="/blogs/<%= blog._id %>?_method=PUT" method="POST">
app.delete("/blogs/:id", function(req, res){
//destroy blog
Blog.findByIdAndRemove(req.params.id, function(err){
if (err) {
res.redirect("/blogs");
} else {
//redirect somewhere
res.redirect("/blogs");
}
});
});
To filter out all <script> tags in the blog body, you can either:
express-sanitizer
which will * sanitize 2 times in routes "Create" and "Update" or
npm install express-sanitizer