Express JS
Тестирование Supertest — это библиотека, созданная исключительно с целью проводить функциональное тестирование http интерфейса.
// __tests__/app.test.js
import request from 'supertest';
import app from '../src/app.js';
test('request', async () => {
const res = await request(app).get('/');
if (res.error) {
throw error;
}
expect(res.status).toBe(200);
});
В основе библиотeки supertest лежит другая библиотека - superagent. Именно она позволяет формировать произвольные запросы к серверу.
import request from 'superagent';
const res = await request
.post('/api/pet')
.type('form')
.send({ name: 'Manny', species: 'cat' })
.set('X-API-Key', 'foobar')
.set('Accept', 'application/json');
https://github.com/visionmedia/superagent https://github.com/visionmedia/supertest
Логирование Правильная отладка — это хорошо настроенное логирование.
В javascript особой популярностью пользуется библиотека morgan.
import Express from 'express';
import morgan from 'morgan';
const app = new Express();
const logger = morgan('combined');
app.use(logger);
https://github.com/expressjs/morgan
Так сложилось, что 99% самых популярных библиотек на js уже поставляются со встроенным логированием через debug. По сути, нам не очень-то и оставили выбор. На картинке выше как раз видно кусок лога express. https://github.com/visionmedia/debug#readme
Интеграция pug с express:
// npm install pug
app.set('view engine', 'pug');
app.get('/', (req, res) => {
const data = { title: 'Hey', message: 'Hello there!' };
res.render('index', data);
})
// index.pug
html
head
title= title
body
h1= message
Шаблоны и чистота
-
Ни в коем случае шаблон не должен порождать побочных эффектов. В шаблоне нельзя писать в базу, изменять данные на диске и вообще любым способом пытаться влиять на окружающую среду. Шаблон это исключительно чтение.
-
Шаблоны должны быть декларативны, никакого изменения состояний, другими словами, если вы начинаете внутри шаблона вводить переменные и изменять их, то, по сути, шаблон превращается в полноценный скрипт, который вы программируете. Не допускайте этого.
-
Использовать логику, влияющую на вывод внутри шаблона — это нормально. Если у вас, с точки зрения ui, блок показывается по определённому условию, то вы не сможете этого избежать, единственное о чем нужно помнить, это создавать вовремя правильные абстракции (функции) для избежания дублирования, а так же для выделения бизнес-правил.
Технологии
REST
Требование REST:
Единообразие интерфейса
Кэширование
Отсутствие состояния
Клиент-серверная архитектура
Слои
Код по требованию (необязательное ограничение)
Дейстие в REST определяется глаголом (GET, POST, DELETE …)
JSONAPI
Middleware
connect - ядро микрофреймворка express.
Connect представляет из себя механизм, который расширяется функциями, называемыми middleware. Каждый раз, когда мы используем use, очередная middleware добавляется в общую очередь. В конечном счёте получается объект, наполненный мидлварами. Каждый запрос, отправляемый на обработку в connect, проходит через цепочку этих middleware пока не наткнётся на терминальную мидлвару.
В свою очередь каждая мидлвара принимает на вход три параметра: request, response и next. Она может поменять их и в конце должна вызвать next для передачи управления следующей по списку мидлваре. В этом и заключается вся мощь микрофреймворков. Удачный дизайн позволяет легко разбивать систему на модули-мидлвары и расширять за счёт мидлвар, которые, в большом количестве, пишут сторонние разработчики.
app.use((req, res, next) => {
req.newProperty = 'hello from my middleware';
next();
});
// вызов methodOverride возвращает функцию вида (req, res, next) => ...
app.use(methodOverride('_method'));
В Connect нет ничего кроме метода use добавляющего очередную мидлвару в стек.
Mount middleware
Самое интересное в Connect, что обработчики конкретных маршрутов — это тоже, всего навсего, мидлвары. Их особенностью является привязка к конкретному маршруту, в отличие от мидлвар, которые выполняются для всех запросов.
app.use('/foo', (req, res, next) => {
// req.url starts with "/foo"
next();
});
app.use('/bar', (req, res, next) => {
// req.url starts with "/bar"
next();
});
Такие мидлвары позволяют реализовывать базовый роутинг без привязки к конкретному глаголу http и без поддержки динамических маршрутов. В Express роутинг реализован без привязки к Mount Middlewares.