- PVSM.RU - https://www.pvsm.ru -

Koajs 2.0: новое поколение фреймворка нового поколения

KoaJS logo«Next generation web framework for node.js» — так написано в документации к версии 1.0. Звучит неплохо, я к этому добавлю что 2 года назад после внедрения koa на одном из проектов у наших программистов появился термин “псевдо-синхронный код” (Это когда код выглядит как синхронный но на самом деле исполняется асинхронно). Что за бред Как это работает я расскажу под катом.

Что такое KoaJS

Чтоб не повторяться:

С помощью особенности работы генераторов и директивы yield мы можем асинхронно выполнить Promise или специально нами сконструированную thinkify-функцию и после выполнения промиса/функции вернуться в ту точку где вызывался yield вернуть результат и продолжить выполнение кода.

Пример такого кода:

//...
let userId = Number(this.request.userId);
let projects = yield users.getActiveProjectsByUserId(userId); // Например, обращаемся к БД

for (let project of projects) {
   project.owners = yield projects.getProjectOwnersById(project.id); // Тут тоже обращаемся к БД
}

this.body = yield this.render('userProjects', projects); // Тут асихронно рендерим ответ
//...

Зачем мне KoaJS?

Идея Koa идеально ложиться на парадигму микросервисов, которую я уже давно внедрил в нашей компании. Ядро фреймворка минималистично, код middleware для коа читается и понимается очень легко, что очень важно для командной разработки. Активное использоване фреймворком возможностей ES2015, минимальное травмирование психики программиста, который до этого писал на PHP (эти ребята колбеки не любят :) ).

Замечательно, чем удивит KoaJS 2.0?

То что было основой KoaJS, а именно библиотека co, построенная на генераторах теперь удалена из базовой реализации Koa 2.

Давайте посторим Hello world!

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa';
});

app.listen(3000);

Как видите тут генераторов нет, но тогда как же писать расхваленый мной “псевдо-синхронный код”. В самом простом случае можно обойтись нативным кодом:

app.use((ctx, next) => {
  const start = new Date();
  return next().then(() => {
    const ms = new Date() - start;
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
  });
});

next — является промисом, ctx — контекст запроса.

В таком виде без колбеков многие вещи реализовать нельзя, поэтому авторы предлагают использовать новый синкасис async/await, который еще не стал стандартом и нативно не поддерживается NodeJS но уже давно реализован в транспилере Babel. Выглядит это так

app.use(async (ctx, next) => {
  const start = new Date();
  await next();
  const ms = new Date() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});

Также предусмотрен вариант с дополнительным подключением библиотеки co и генераторами:

app.use(co.wrap(function *(ctx, next) {
  const start = new Date();
  yield next();
  const ms = new Date() - start;
  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
}));

Совместимость с Koa 1.x

Когда я говорил о “выпиленных” генераторах, то был не совсем точен. Для совместимости, если вы оформите middleware в стиле koa 1.0, koa 2.0 его подключит и исполнит он при этом в консоли будет “Koa deprecated Support for generators will been removed in v3…” Другими словами до версии 3.x все будет работать.

Вот пример:

// Koa will convert
app.use(function *(next) {
  const start = new Date();
  yield next;
  const ms = new Date() - start;
  console.log(`${this.method} ${this.url} - ${ms}ms`);
});

Также можно сконвертировать существующий middleware в формат 2.0 самостоятельно с помощью модуля koa-convert

const convert = require('koa-convert');

app.use(convert(function *(next) {
  const start = new Date();
  yield next;
  const ms = new Date() - start;
  console.log(`${this.method} ${this.url} - ${ms}ms`);
}));

В этом случае никаких предупреждений на консоль, поэтому я рекомендую использовать именно такой способ подключения legacy middleware.

Зачем переходить на 2.0

Конечно я не могу утверждать на 100%, но полгода стабильной работы одного из типовых сервисов дают мне уверенность в том что 2.0 достаточно стабилен.

Я хочу иметь право выбора каким способом реализовывать свой middleware. Koa 2.0 дает мне три пути: нативный, генераторы и async/await

Koa 2.0 уже поддерживают многие популярные middleware, а если не поддерживают, то работают через koa-convert

Если вы сейчас приглядываетесь к новым фреймворкам, попробуйте что-то небольшое закодить на Koa — уверен, Вы не пожалеете что потратите на это время.

Что посмотреть

Автор: apelsyn

Источник [10]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/node-js/121084

Ссылки в тексте:

[1] Знакомство с Koa или coroutine в nodejs: https://habrahabr.ru/post/238095/

[2] Генераторы в ES6 и асинхронный код по-новому: https://habrahabr.ru/post/277033/

[3] Документация по Koa 1.x: http://koajs.com/

[4] Примеры на Koa 2.x: https://github.com/koajs/koa/tree/v2.x

[5] Middleware для Koa: https://github.com/koajs/koa/wiki

[6] Примеры небольших приложений на Koa: https://github.com/koajs/examples

[7] Мой скелет REST-сервиса на Koa 2.0: https://github.com/ria-com/node-koajs-rest-skeleton/tree/v2.x

[8] Скелет приложения на Koa2: https://github.com/17koa/koa2-demo

[9] Шаблон для Koa2 c настроеным Babel: https://github.com/geekplux/koa2-boilerplate

[10] Источник: https://habrahabr.ru/post/301126/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best