POST & Middleware in Node
Q&A
Optional talks (~1 hour) led by our TAs on topics outside of core class curriculum
First one is coming up next week, will be led by Tal talking about creating browser extensions.
Each seminar will offer a (minimal) amount of extra credit for participating.
If you really want to hear about something, let us know!
Add your questions, vote on what questions you want answered, and we'll tackle them towards the latter half of lecture.
Either on your phone or computer, go to PollEv.com/robcse
We've seen how to handle GET requests with app.get
But what about POST requests that we send with FormData
?
Consider a Cafe site with three pages - index.html, admin.html, and contact.html
The backend might support a few GET endpoints: /menu
, /menu/:category/
, /categories
, /images
What are examples of POST requests we might want to add?
/contact
POST endpointLet's implement an a POST endpoint to process a contact message sent from the contact page form.
To add a POST endpoint, use app.post
instead of app.get
app.post("/contact", (req, res) => {
...
});
JS
With GET endpoints, we've used req.params
and req.query
to get endpoint parameters passed
in the request URL.
But remember that POST requests send parameters in the Request body, not in the URL.
app.post("/contact", (req, res) => {
let name = req.params.name; // this doesn't work!
...
});
JS
What is a disadvantage of sending parameters in a URL?
So, how can we get POST parameters sent by a client?
POST requests can be sent with different data types:
application/x-www-form-urlencoded
application/json
multipart/form-data
In Express, we have to use middleware to extract the POST parameters from the req.body
. For the first two, there is built-in middleware - we don't need middleware for text/plain.
With forms and fetch, we use the FormData
object to send POST parameters, which is always
sent as multipart/form-data
.
There is no built-in middleware to access the req.body
params for multipart content.
Another module!
multer
ModuleA module for extracting POST parameter values sent through multipart POST requests like those sent with FormData
Has a lot of functionality to support file uploading, but we will just use it to access
the body of a POST request sent through FormData, which we can't get with just
req.body
.
To use, we'll need to set an option to ignore upload features with multer().none()
const multer = require("multer");
app.use(multer().none());
JS
Remember to run npm install multer
in any project that uses it.
We often don't want to make assumptions about what method a client uses to POST data. It's best to support all three with the appropriate middleware.
// other required modules ...
const multer = require("multer");
// for application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true })) // built-in middleware
// for application/json
app.use(express.json()); // built-in middleware
// for multipart/form-data (required with FormData)
app.use(multer().none()); // requires the "multer" module
...
app.post("/contact", (req, res) => {
let name = req.body.name;
let email = req.body.email;
let message = req.body.message;
let timestamp = new Date.toUTCString();
// validate parameters, then update message.json file with new data
...
});
JS
app.post
instead of app.get
req.body.paramname
instead of req.params.paramname
/req.query.paramname
multer
(non-core) module with the rest of your modulesfetch
and FormData
in client-side JS (similar to HW3) - remember you can't test POST requests in the URL!
Use 400 (Invalid Requests) for client-specific errors.
Use 500 (Server error) status codes for errors that are independent of any client input.
Especially if you're watching a recording, write your question on PollEverywhere and I'll answer them at the start of next lecture.
Either on your phone or computer, go to PollEv.com/robcse