Express Flashcards

1
Q

What is express?

A

Express is a node.js framework, that provides higher level of abstraction and makes the development faster

It contains set of features:

  • complex routing
  • easier handling of requests and responses
  • middleware,
  • server-side rendering
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Setting up express.

A
  1. It is a convention, to have all the express configuration files in app.js file.
  2. const express = require(‘express’);
    // Setting up he app
  3. const app = express();
  4. app.listen(port, callback);
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Routing in express

A
When you set up your const app = express(), you can define basic routing, by app.get('/', (req, res) => {
  res.status(200).send('Hello');
})

However, for more complex application it is better to use Router object that is part of express.

In express, a router object is an isolated instance of middleware and routes. You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.

  • router.METHOD(path, [callback, …] callback),
    where METHOD is one of the http methods such as get, put, post
  • router.all(path, [callback, …] callback),
    This method is just like the router.METHOD() methods, except that it matches all HTTP methods (verbs).
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

How do you setup a router object in express?

A

In express we can deal with routers in the following way:

  1. const express = require(‘express’);
  2. const router = express.Router(); // we grab the router off of exrpess.
  3. define all the routes.

To define routes,
1. we use
router.get(‘/’,(req, res, next) => {})
2. and provide a callback function that will run, whenever somebody visits that specific url.
req - object full of information that is coming in
res - object full of methods of saving data back to the user.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

What are the differences between res.send(), res.json() and res.end() methods?

A

All of those methods are used to send responses using Express.

  • res.send() and res.json() are almost identical. The difference is that res.json() will convert non objects to json.

res. json() has two additional options:
app. set(‘json replacer’, replacer); // property transformation rules
app. set(‘json spaces’, 2); // number of spaces for indentation

  • we use res.end() if we want to end the response without providing any data. This could be useful for a 404 page.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

How can you access request variables that are specified in the route in express?

A

To make endpoint that uses variables in a rout, we need to add a colon to the URL.
router.get(‘/reverse/:name’, (req, res) => {
res.send(req.params.name);
})

then the variable will be accessible in the req.params.name obj.

If the parameter is optional then we need to add a question mark to the parameter, like:
/api/v1/tours/:id/:y?

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

What is the order of the middleware functions in express?

A

IN express “everything is middleware” (even routers - which just are invoked when some conditions appear).

Middleware functions are the functions that happen inbetween the Request and Response (See The Request-Response Cycle).

The middleware functions that we use are in order that they are defined in the code.
app.use(func);

All the middleware that we use in our express app, are called the middleware stack.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is mounting?

A

Mounting is a concept used in express to register middleware functions on a specific path. You can bind application-level middleware to an instance of the app object by using the app.use() and app.METHOD() functions.
However for most cases, you want to send responses based on the type of resource that has been requested.

This example shows a middleware function mounted on the /user/:id path. The function is executed for any type of HTTP request on the /user/:id path.
app.use(‘/user/:id’, function (req, res, next) {
console.log(‘Request Type:’, req.method)
next()
})

You can also define Router-level middleware
with const router = express.Router().(use/METHOD)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

How do you define Error handling middleware?

A

You define Error handling middleware, just as usual middleware, but they always take four arguments. You must provide four arguments to identify it as an error-handling middleware function. Even if you don’t need to use the next object, you must specify it to maintain the signature. Otherwise, the next object will be interpreted as regular middleware and will fail to handle errors.

app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(500).send(‘Something broke!’)
})

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What is Param middleware?

A

Param middle ware is a middleware that only runs for certain parameters.

Param middleware has access to a 4th argument (value that the param returns).

router.param(‘id’, (req, res, next, val) => {
console.log(Tour id is: ${val});
next();
})

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

How do you add middlewares to specific METHOD handler stack?

A

In order, to add a middleware to handler stack for a specific METHOD, we just need to provide it as another argument. Like:
router.route(‘/’)
.get(tourController.getAlTours)
.post(middlewareFunc, tourController.createTour);

With this method, we can add multiple handlers to a stack.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How do you serve static files in express?

A

In order to serve static sites, we need to use a built in middleware and pass a folder location that is supposed to serve as a root
app.use(express.static(${\_\_dirname}/public));

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

How do you handle unhandled routes in express?

A

Routers are mounted on specific routes.
Those routers are middlewares in an express app.
So if specific route does not match any mounted route, the express app will go to the next middleware defined by app.use.

Because the order of the middlewares determines the invokations order, if we add a handler for all the unhandled routes for .all requests as the last middleware in our express configuration, we will handle these routes. (If it matched a specific route, that we are handling in our api, we would exit the stack earlier)

app.all(‘*’, (req, res, next) => {
res.status(404).json({
status: ‘fail’,
message: Can't find ${req.originalUrl}
})
})

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How do we handle errors in express?

A

Express comes with error handling out of the box.
We need to write an error handling middleware, which will catch errors coming from all over the application (no matter where its from).

app. use((err, req, res, next) => {
err. statusCode = err.statusCode || 500;
err. status = err.status || ‘error’;

res.status(err.statusCode).json({
status: err.status,
message: err.message,
});
});

In the middleware that produces an error, we can call next(err) with an err argument. Then express will assume, that whatever we passed is an error, and it will skip to our error handling middleware.

app.all('*', (req, res, next) => {
  const err = new Error(`Can't find ${req.originalUrl}`)
  err.status = 'fail';
  err.statusCode = 404;

next(err)
});

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

How can you handle unhandled promise rejection in express app?

A

Each time that there is an unhandledRejection, the process object will emit an object called unhandledRejection.
We can subscribe to that event

process.on(‘unhandledRejection’ (err) => {
console.log(err.name,err.message);
server.close(()=>process.exit(1));
})

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

What are uncaught exceptions and how can you handle them in express app?

A

All errors/bugs that occur in synchronous code, that are not handled anywhere, are called uncaught exceptions.
While with unhandledRejection, crashing our application was optional, when it comes to uncaughtExceptions, we really need to crash our application, because the entire node process is then in “unclean state”.

process.on(‘uncaughtException’,err=>{
console.log(err.name, err.message);
process.exit(1);
});

When it comes to our app, we should not rely solely on unhandledRejections and uncaughtExceptions, but handle errors right, where they occur, for example when we try to connect to the database, we should add a catch there.

17
Q

How do you send cookies in express?

A

In order to send the cookie in express we need to attach it to the response object (for instance in createSendToken function, which is a function that we use to send JWT tokens).

res.cookie(‘jwt’, token, {
expires: new Date(
Date.now() + process.env.JWT_COOKIE_EXPIRES_IN * 24 * 60 * 60 * 1000
),
secure: true,
httpOnly: true
});
cookie name, data, options object

expires: (The client will delete the cookie after it was expired (similar to JWT_EXPIRES_IN )
secure: (The cookie will only be sent on an encrypted connection (https))
httpOnly: the cookie cannot be accessed or modified in anyway (prevents XSS attacks)

18
Q

What does mergeParams do?

A

Merge params is an option that can be put on the router
router = express.Router({mergeParams: true});
by default, all routers only have access to the parameters of their specific routes.

When we mount a router on a route that belongs to another router, if we want to use the params, we might be forced to put this property.

19
Q

How do you protect a route in express?

A

The common solution is to protect a route by issuing JWT. So we need sendToken function that is attached to middleware for login and signup.

In order to protect the route, we need to create a protect function.

In this function we need to
1) Get the token if it’s there
// check if req.headers.authorization && req.headers.authorization.startsWith(‘Bearer’)
2) Verify the token
const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET);

promisify is a util function available in node in util module..
3) Check if user still exists

4) Check if user changed pw after the token was issued

check if decoded.iat (issued at ) is smaller than password last modified at field.
Then grant access
req.user = freshUser 
// (attach user object to middleware chain, so we may use it in other middlewares.)
20
Q

What is the purpose of adding middleware inside of routers?

A

Every module, like router in express is like a separate application. When routes are declared, they are similarly to app.js declared in order. So we can attach middleware functions in the middle of the router file, and it will run for all routes that come after that.

// Protect all routes after this middleware
router.use(authController.protect)
21
Q

How do you set up templating engines in express?

A

Express supports most common template engines out of the box. In order to tell express, which templating engine is going to be used we need to declare it by:

app.set(‘view engine’, ‘pug’);

22
Q

What is another way of implementing authentication functionalities in the express app?

A

Instead of validation via JWT, we can use sessions to authenticate our users in. In order to do that, we need
passport library.

  1. In the app.js file, we should
    passport.initialize();
    and
    passport.session();
  2. We should configure passport to select a strategy, that we want (usually ‘local’)
3. On the user model, we should use a pluigin called
const passportLocalMongoose = require('passport-local-mongoose');

userSchema.plugin(passportLocalMongoose, {usernameField: ‘email’});

  1. Then we will have access to some methods on the userSchema, so we can try to authenticate
exports.register = async (req, res, next) => {
  const user = new User({ email: req.body.email, name: req.body.name });
  const register = promisify(User.register, User);
  await register(user, req.body.password);
  next();
};
  1. Logging in users makes use of
    passport.authenticate(‘local’, {failureRedirect: …,
    successedirect: …,
    failureFlash: …,
    successFlash: …}