Pull to refresh

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

Reading time3 min
Views53K
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 — уверен, Вы не пожалеете что потратите на это время.

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


Tags:
Hubs:
Total votes 23: ↑16 and ↓7+9
Comments16

Articles