Я немного занимаюсь разработкой для Node.js и хотел попробовать свои силы в написании фреймворка. Вероятно, это обряд посвящения, хотя на самом деле это не первый мой обряд.

Выпуская его сегодня, я хочу посмотреть, стоит ли тратить на это время в будущем или мне следует сосредоточить свою энергию на другом.

Проект называется Curveball, и его отличительные особенности:

Цели проекта

Я большой поклонник микро-фреймворков. Express был великолепен, когда вышел, но теперь он кажется немного устаревшим. Коа написала команда Express. Koa имеет больше смысла в кодовых базах, которые ориентированы на Promise, а не на обратный вызов, и это не единственное улучшение. Команда ждала выпуска стабильной версии, пока Node.js не выпустил стабильную _1 _ / _ 2_ поддержку.

Всем рекомендую это проверить. Сомневаюсь, что вы захотите вернуться в Express после того, как немного поработали Koa.

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

  1. Curveball очень минималистичен, как Koa.
  2. Он во многом соответствует архитектуре Koa и дизайну API с некоторыми незначительными изменениями. Промежуточное ПО будет выглядеть очень знакомо.
  3. Он полностью написан на машинописном тексте.
  4. Он включает в себя современные функции HTTP, он имеет встроенную поддержку HTTP / 2 Push и 103 Early Hints и интегрирует их таким образом, что кажется, что они являются неотъемлемой частью инфраструктуры.
  5. Внутри фреймворка легко выполнять «имитацию» HTTP-запросов без необходимости проходить через настоящий HTTP-стек.

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

Некоторые примеры:

Привет, мир

import { Application, Context } from '@curveball/core';
const app = new Application();
app.use((ctx: Context) => {
  ctx.response.body = 'Hello world! You used the following HTTP method: '  + ctx.request.method;
});
app.listen(4000);

Роутер

import { Application } from '@curveball/core';
import router from '@curveball/router';
app.use(router('/contact', ctx => {
  ctx.response.body = 'Contact us!';
});
app.listen(4000);

HTTP / 2 Push

Если у вас есть доступ к объекту Context, вы также можете нажать. Push будет проигнорирован для соединений HTTP / 1.

app.use(ctx => async {
  ctx.response.body = 'Hello world!'
  await ctx.response.push( pushCtx => {
    // This function is not called unless the client indicated 
    // they support push.
    // You get a special Context object that has a request and
    // response.
    pushCtx.request.path = '/assets/foo.css';
    pushCtx.response.type = 'text/css';
    pushCtx.response.body =  'body { background: blue; }';
  });
})

Приведенный выше пример позволяет вам программно генерировать push-уведомления, что позволяет выполнять определенные оптимизации, которые сложно сделать с реализациями push-уведомлений HTTP / 2, основанными на перехвате заголовка Link:.

Однако, если вы хотите протолкнуть запрос и ответ, которые проходят через весь стек промежуточного программного обеспечения, вы можете сделать это с помощью подзапроса:

app.use(ctx => async {
  ctx.response.body = 'Hello world!'
  await ctx.response.push( pushCtx => {
    pushCtx.request.path = '/assets/foo.css';
    // Handle does an internal sub request and calls every 
    // middleware.
    return app.handle(pushCtx);
  });
});

Отправка ответа 103 Early Hints

app.use(ctx => async {
  ctx.response.body = 'Hello world!'
  ctx.response.sendInformational(103, {
    'Link' : [
      '</style.css> rel="prefetch" as="style"',
      '</script.js> rel="prefetch" as="script"',
    ]
  });
});

Обновления промежуточного программного обеспечения

Если вы переходите из Express, вы также получаете все преимущества, которые вам дал бы Koa. Так что это не просто аргумент в пользу Curveball.

Попробуйте написать следующее промежуточное ПО с помощью express:

app.use( async (ctx, next) => {
  // Let the entire middleware stack run
  await next();
  
  // HTML encode JSON responses if the client was a browser.
  if (ctx.accepts('text/html') 
    && ctx.response.type ==== 'application/json') {
      ctx.response.type = 'text/html';
      ctx.response.body = '<h1>JSON source</h1><pre>' +  
        JSON.stringify(ctx.response.body) + '</pre>';
  }
});

Где взять Curveball

Вы можете найти его на странице проекта Github.

Что я могу сделать?

Если я единственный пользователь, проект мертв в воде, и я, вероятно, перестану над ним работать и конвертирую свои проекты обратно в Koa.

Если вы думаете, что это стоит поддерживать, я хотел бы знать. Напишите мне в твиттере или напишите мне письмо по электронной почте!

Если вы хотите помочь, вам предстоит многое сделать. Я бы не хотел быть единственной точкой отказа.

Спасибо, что добрались до конца!