1) Что такое функции промежуточного слоя(middleware) в Express.js?

Middleware - это функция, которая выполняет некоторое подготовительное или часто используемое действие перед передачей запроса основному обработчику. Например, вам нужно проверять сесию пользователя при каждом  запросе, для этого вы пишете функцию промежуточной обработки, которая его проверяют, чтоповзоляет не дублировать эту проверку во всех контроллерах.

import * as express from 'express';const app = express();app.use(function(req,res,next) {
  const token=req.headers['token'] || req.cookies.token;
  let result=tokenService.verifyToken(token);
  if(result.error){
    return NotAuthorized(req,res);
  }
  req.user=result;
  return next(null,req,res);});

2) Как сделать перенаправление на определенный URL?

Для перенаправления на определенный URL используйте метод обьекта response 'redirect ([status,] path)'. Он принимает один или два параметра: URL и код статуса редиректа или просто URL.

res.redirect(301, 'https://domain.com');res.redirect('https://domain.com');

3) Как получить параметры запроса (query params)?

Вы можете получить параметры запроса в объекте req.params.

router.get('/api/user/:userId', async function (req, res, next) {
  const userId=req.params.userId;});

4) Что такое шаблонизаторы и как их использовать?

Шаблонизаторы  позволяют использовать статические файлы шаблонов в приложении для отображения динамических HTML-ответов. Чтобы использовать шаблон двигателя использовать приложение.метод SET.

app.set('view engine', 'hbs')

5) Как запустить Express.js-сервер в production режиме?

Для запуска Express server в production режиме необходимо установить переменную среды NODE_ENV в 'production'. По умолчанию сервер работает в режиме разработки.

$ NODE_ENV=production node bin/www

6) Как автоматически перенаправить HTTP-трафик на HTTPS?

Есть несколько способов сделать это. Во-первых, использовать res.метод перенаправления, второй использовать Nginx или HAProxy в качестве reverse proxy.

const http = express.createServer();http.get('*', function(req, res) {  
    res.redirect('https://' + req.headers.host + req.url); 
});
http.listen(80);

Для Ngnix:

location / {
    proxy_pass http://localhost:8080;
}

7) Как запустить Express.js app в режиме кластера?
.
Это хорошо известный факт, этот Node.JS однопоточен, поэтому вы не можете полностью использовать мощности многоядерной системы, работающие в однопоточном режиме. Для запуска нескольких экземпляров Express следует использовать встроенный модуль 'cluster' .

const cluster = require('cluster');if (cluster.isMaster) {
  const cpuCount = require('os').cpus().length;
  for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
    }} else {
    const express = require('express');
    const app = express();
    app.get('/', function (req, res) {
        res.end('Rendered in cluster mode.!');
    });
    app.listen(8080);
}

8) Как обрабатывать загрузку файлов?

Express не предоставляет API для загрузки файлов, но вы можете использовать одно из различных промежуточных ПО, доступных в NPM. В следующем примере мы используем пакет 'multer'.

import * as express from 'express'
const router = express.Router();
import * as multer from "multer"
const fs = require('fs');
const appRoot = require('app-root-path').path;
const upload = multer({ dest: appRoot+'/uploads' });
router.post('/api/v1/upload/image',upload.single('image'), function(req:any, res, next) {
  const sanitize = require("sanitize-filename");
  if(!req.file){
    return res.json({error:'No image provided'});
  }
  const newFileName=`${req.file.path}_${sanitize(req.file.originalname)}`;
  fs.rename(req.file.path, newFileName, function(err) {
    if ( err ) console.log('ERROR: ' + err);
  });
  res.send({status:"OK"});});
export {router};

9) Как структурировать приложение ExpressJS?

Нет никаких официальных рекомендаций о том, как структурировать Express.js приложение, поэтому создание архитектуры лежит на плечах разработчика. Есть некоторые рекомендации по структуре каталогов.

├── app.js   // file where express server started
├── config   // Configuration files
├── models   // Data models for Sequlize or Mongoose
├── public   // Directory for static assets
├── routes   // The routes in you application, with controller functions
├── services // Any other service utils your application using
└── views    // Template engine views (HBS,JADE,EJS)

10) Как перезапустить приложение Node.js, когда происходит необработаное исключение?

Когда приложение работает в production среде, время безотказной работы должно быть как можно больше, поэтому существует потребность в службе, которая перезапустит сервер после критической ошибки. Существует несколько утилит командной строки, которые могут это сделать: forever,pm2,nodedemon. Основное различие заключается в том,что вы запускаете приложение через эту утилиту, вы не запускаете его с помощью команды "node" напрямую. Также пакеты сохраняют логи приложения, предоставляют информацию об использовании памяти и текущем времени безотказной работы.

pm2 start app.js

11) Поддерживает ли Express.js базовою авторизацию (basic auth)?

Нет, express не поддерживает его из коробки, но есть библиотека express-basic-auth, которая помогает добавить эту функцию в приложение.

12) Что делает функция res.end ()?

Функция «res.end» завершает процесс ответа. Его можно использовать для быстрой отправки ответа без каких-либо данных или когда вы укажете, что вы пишете последний chunk буферизованных данных.

app.use(function(req, res) {
res.status(404).end();
})

13) Как отправить ответ в формате JSON?

Самый простой способ отправить ответ JSON - использовать метод res.json (data). Он автоматически добавит правильный тип содержимого в заголовки ответов и преобразует переданный объект в JSON. Однако вы можете это сделать самостоятельно, используя res.send () и настройки заголовков.

router.get('/api/image-dimensions',upload.single('image'), function(req, res, next) {const json=getImageDimension();res.header('Content-Type', 'application/json');res.send( json );        
})

14) Что делает функция res.type(type)?

Функция res.type (type) изменяет заголовок HTTP Content-Type на тип MIME, полученный с помощью mime.lookup () для указанного типа.

res.type('html');// => 'text/html'

15) Опишите основные различия между Express.js и Sails.js?


  • Sails.js более мощный, имеет собственную ORM, может автоматически генерировать REST API, встроенную поддержку WebSocket, определенную структуру приложения. Express.js не может делать ничего подобного без дополнительных библиотек и промежуточных обработчиков.
  • Express.js более гибкок, чем Sails.js, вы можете создать свое приложение как конструктор. Sails.js сильно ограничивает способность разработчика изменять структуру приложения.
  • Express.js легче изучить, что отлично подходит для начинающих программистов.
  • Sails.js имеет мощную CLI утилиту 

16) Что такое  'express-generator'?

'express-generator' утилита которая используется для создания Express.js приложений . Перед созданием проекта вы можете настроить движок шаблонов, механизм стилей, файл .gitignore.

$ npm install -g express-generator
$ express --view=hbs /tmp/foo && cd /tmp/foo


17) Что такое router?

A router object is an isolated instance of middleware and routes. Router is a basic class to implement REST api and Website pages. router.METHOD(path, [callback, ...] callback) method is used to add route.
Объект router представляет собой изолированный экземпляр промежуточного программного обеспечения и маршрутов. Маршрутизатор является базовым классом для реализации страниц REST api и веб-сайта. router.METHOD(path, [callback, ...] callback) используется для добавления маршрута.

18) Может ли функция обработчика запроса быть асинхронной?

Да, в функциях контроллерах запросов Express.js можно использовать async/await.

19) Как отправить файл с использованием потоков Node.js
?

Потоки Node.js позволяют считывать и записывать буферизованные данные. Например, это очень полезно, когда файл не помещается в RAM, поэтому вы не читаете файл полностью, просто обрабатываете его по частям

router.get('/api/v1/image-proxy/:name', function(req, res) {
  return require('request').get('some url'+req.params.name).pipe(res); })

20) Почему важно различать операционные и программные ошибки?


Операционные ошибки не являются ошибками, а проблемами с системой, такие как упавшая база данных или заполненый жесткий диск, ошибка программиста - это ошибка, которая приводит к неправильному поведению приложения. Хорошая практика - быть готовой к любой эксплуатационной ошибке и обрабатывать их изящно и без сбоев.