π Express.js π
Express can be used to create websites or APIs.
$ cd xxx # go to your project folder
$ npx --yes --package express-generator express --force --no-view
$ npm install
$ npm audit fix --force
β‘οΈ Don't forget to add a .gitignore, and maybe a linter too.
Understand your generated project
- β¨ Your server file is created inside
/bin/www
. You will most likely never have to edit this file. - πΉ It will load the application "routes" from
/app.js
. You will add "routes" and "middlewares" here. - π₯ The associated routes files are stored inside
/routes
. - π Your publicly URL accessible files are stored inside
/public
.
If you are not familiar with routes, HTTP methods/response codes... Then you should learn that first. Refer to the HTTP protocol.
Middlewares
In app.js you should see a lot of app.use(xxx)
. These are called middleware. A middleware is a function that will prepare the request (req) or the response (res) for usage in routes later.
app.use(function (req, res, next) {
// ... do something ...
next()
});
β‘οΈ It's useful to know if there is some code you want to execute for every or only some requests.
- β¨ Example: cookie parser
For instance, app.use(cookieParser())
is a middleware that will parse cookies in the request, and store them in req.cookies
.
- β¨ Example: adding headers
CORS headers
See also Express.js/cors middleware.
const cors = require('cors');
app.use(
cors({
origin: 'http://localhost', // ex: allow localhost
methods: ["GET", "POST", "PATCH", "PUT", "OPTIONS", "HEAD"],
allowedHeaders: ['X-Requested-With', 'content-type']
})
);
Allowing browsers to fetch cookies
methods: [...],
+ credentials: true,
If you want to use origin: '*'
(any) with credentials
- origin: '*',
+ origin: [ /.*/ ],
...
credentials: true,
Allowing multiple origins (you can use regexes...)
- origin: 'URL',
+ origin: ['http://localhost', 'http://127.0.0.1' ],
Custom headers
app.use(function (req, res, next) {
res.setHeader('Access-Control-Expose-Headers', 'Custom-header');
res.setHeader('Custom-header', 'value');
next()
});
Routers
In app.js, you will also define routes. To make things cleaner, we are moving routes to "local" routers in ./routes
. In app.js, we are importing (require) local routers, and associating them with an API endpoint.
const usersRouter = require('./routes/users');
app.use('/users', usersRouter);
In the scenario above, any requests to the endpoint /users
will be handled by usersRouter
.
β οΈIt's important to note that inside a "local" router, routes will be declared relatively to this endpoint. For instance, /
would be /users/
.
Routing should be done AFTER every calling every middleware.
A "local" router is something like this.
// ./routes/users
const express = require('express');
const router = express.Router();
// router.get => GET
// / => /users/
// req => the request
// res => the response
router.get('/', (req, res) => {
// ... code ...
// send a response
});
// add more routes
module.exports = router;
Routing
You can use every HTTP method
router.get('/', (req, res) => {});
router.post('/', (req, res) => {});
router.put('/', (req, res) => {});
router.patch('/', (req, res) => {});
router.delete('/', (req, res) => {});
You can also declare "dynamic" routes. For instance, a route /:id
will take any value after the /
and store it inside id
.
router.delete('/:id', (req, res) => {
const id = req.params.id
// ...
})
// extracting params
router.delete('/:x1/:x2', (req, res) => {
const {x1, x2} = req.params;
// or use req.params.x1 / req.params.x2
})
You can use regexes inside your dynamic routes! See Route Paths.
Useful methods on req.
// get headers
req.get('header-name')
req.headers['header-name']
// get GET/POST params
req.query.key // GET param named "key"
req.body.key // POST param named "key"
Useful methods on res.
// send something to the requester
res.send(something); // HTML, JSON, XML...
res.status(404).send(something); // ex: 404 HTTP code
res.render('index', { title: 'Title' }); // public/index.html
// redirect
res.redirect('URL');
Express handle login
You may want to use cookies to store some data, such as the logged user. We use a special cookie called session for this purpose. A session is a file on the server in which we can store data.
The client will store and return us in every request the session-id, which will allow us to load the matching session data.
$ npm i express-session
const session = require('express-session');
/* ... */
app.use(session({
resave: false,
saveUninitialized: false,
secret: 'something-random-and-secret'
}));
- Create a session
await req.session.regenerate(() => {}); // generate session
- Store data inside the session
req.session.key = 'value'; // store a value
- Read data inside the session
const value = req.session.key
- Delete a session
await req.session.destroy(() => {}) // destroy session
π» To-do π»
Stuff that I found, but never read/used yet.
- Express
- Stripe
- Express for Websites
res.json()
res.end()
- typescript+express