5. RESTful Routes
RESTful Routes
GET
- Retrieve information
- Data is limited and sent via query string (visible)
POST
- Post data to the server
- Data can be any type (json) and is sent via request body (hidden)
<body>
<h2>GET</h2>
<form action="http://localhost:3000/tacos" method="GET">
<input type="text" name="meat">
<input type="number" name="qty">
<button>Submit</button>
</form>
<h2>POST</h2>
<form action="http://localhost:3000/tacos" method="POST">
<input type="text" name="meat">
<input type="number" name="qty">
<button>Submit</button>
</form>
</body>
const express = require('express')
const app = express()
app.use(express.urlencoded({extended: true}));
app.get('/tacos', (req, res) => {
res.send("GET /tacos response");
})
app.post('/tacos', (req, res) => {
const {meat, qty} = req.body;
console.log(`meat: ${meat}\nquantity: ${qty}`);
res.send("POST /tacos reponse")
})
app.listen(3000, ()=>{
console.log("listening on port 3000");
})
REST
- Set of guidlines for how server and client should commuincate.
- CRUD: create (post), read (get), update (patch), destroy (delete) NAME VERB PATH Index GET /comments list all comments New GET /comments/new form to create new comment Create POST /comments create a new comment Show GET /comments/:id get one comment Edit GET /comments/:id get one comment Update PATCH /comments/:id update one comment Destroy DELETE /comments/:id delete one comment
GET and POST
We need 2 routes becasue the form needs to send the data somwehere (as POST request)
- Route that displays the form
app.get('/comments/new', (req, res)=>{
res.render('comments/new');
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Comment</title>
</head>
<body>
<h1>Make a new comment</h1>
<form action="/comments" method="post">
<section>
<label for="username">Enter username:</label>
<input type="text" placeholder="username" name='username'>
</section>
<section>
<label for="comment">Comment Text</label>
<br>
<textarea name="comment" cols="30" rows="5"></textarea>
</section>
<button>Submit</button>
</form>
</body>
</html>
- Route that receive the form data
app.post('/comments',(req, res)=>{
console.log(req.body);
res.send("IT WORKS");
})
Use express.urlencoded() A method inbuilt in express to recognize the incoming Request Object as strings or arrays. This method is called as a middleware
app.use(express.urlencoded({extended: true}));
Extract the data from the body request
app.post('/comments',(req, res)=>{
const {username, comment} = req.body;
comments.push({username, comment});
res.send("IT WORKS");
})
- redirect the user to the comments view instead of res.send:
res.redirect('/commets')
SHOW route
Each resource should have an unique identifier i.e. /comments/:id
req.params
takes the values after :
app.get('/comments/me/:id&:tag', (req, res)=>{
console.log(req.params);
res.send("Done");
})
or
app.get('/comments/:id', (req, res)=>{
const {id} = req.params;
const comment = comments.find(c => c.id === parseInt(id));
res.render('comments/show', {comment})
})
Dynamic links
<% for (let comment of comments){ %>
<li><%= comment.comment %> - <b> <a href="\comments\<%= comment.id %>"><%= comment.username %></a></b></li>
<% } %>
UUID Unique Identifier
- Install
npm i uuid
- Load and rename from v4 to uuidv4
const {v4: uuidv4} = require('uuid');
- Give each item an unique id when submitted:
const id = uuidv4();
comments.push({id, username, comment});
UPDATE route (Patch)
app.patch('/comments/:id', (req, res)=>{
const {id} = req.params;
const newCommentText = req.body.comment;
const foundComment = comments.find(c => c.id === id);
foundComment.comment = newCommentText;
res.redirect('/comments');
})
- does not follow the immutability pattern
Express method override
- html form can only send GET and POST requests
- install method-override package
const methodOverride = require('method-override')
//specify query string
app.use(methodOverride('_method'));
Use a form to edit the comment
app.get('/comments/:id/edit', (req, res)=>{
const {id} = req.params;
const comment = comments.find(c => c.id === id);
res.render('comments/edit', {comment});
})
<body>
<h1>Edit</h1>
<form method="POST" action="/comments/<%= comment.id%>?_method=PATCH">
<textarea name="comment" id="" cols="30" rows="10">
<%= comment.comment %>
</textarea>
<button>Save</button>
</form>
<a href="/comments">Go back</a>
</body>
This will call app.patch created before
DELETE
app.delete('/comments/:id', (req, res)=>{
const {id} = req.params;
//better to create a new array than mutating an existing one
comments = comments.filter(c=>c.id !== id)
res.redirect('/comments');
})
<form method="POST" action="/comments/<=% comment.id %>/_method=DELETE">
<button>Delete</button>
</form>
Written on August 17, 2021