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