В последней версии HAPI.js есть некоторые изменения, на которые стоит обратить внимание. В YLD мы хотим быть как можно ближе к последним изменениям, и в этом блоге мы хотим немного рассказать о новой версии HAPI.js. Есть некоторые критические изменения, которые были созданы в основном из-за принятия async/await.

Помните async/await (Асинхронные функции)?

Если бы нам пришлось резюмировать async/await в простом предложении, это было бы что-то вроде «Это делает все красивее, делая асинхронный код более читабельным». В следующем примере показана асинхронная функция, ожидающая выполнения обещания:

async function getById(id) {  
  try {
    const item = await db.getById(id);
    return item;
  } catch(err) {
    // deal with it (reject the promise)!
  }
}

Небольшие заметки:

  • await всегда ждет обещания (в этом случае db.getById будет разрешено);
  • await можно использовать только внутри async функции (отсюда объявление async function getById);
  • вы можете использовать try / catch для выполнения обработки ошибок или придерживаться then/catch, предоставляемого обещаниями (есть также хорошие альтернативные решения, такие как apr-intercept или await-to-js);
  • это не упоминается в этом примере, но вы должны быть осторожны при вызове двух функций с использованием await внутри одной и той же функции async. Если вы не справитесь с этим должным образом, вы можете получить серию кода, который можно запускать параллельно (подробности см. В Promise.all, или даже в утилите apr).

Но этот пост не о async/await, давайте вернемся к HAPI.js! Чтобы получить больше информации о async/await, ознакомьтесь с спецификацией ECMAScript или MDN.

Пока connections

Выполнять server.connection({ port: 3000 }) после создания сервера HAPI.js больше не требуется, чтобы быть в другой строке. Все методы из server.connection теперь находятся в server, и вы можете просто:

const Hapi = require('hapi');
const server = Hapi.server({  
  host: 'localhost',
  port: 3000
});

Используйте async/await для запуска вашего сервера

Забудьте о функции обратного вызова в server.start. Запустите его с помощью асинхронных функций:

async function start() {  
  try {
    await server.start();
  }
  catch (err) {
    console.error(err);
    process.exit(1);
  }
};
start();

Забудьте об reply интерфейсе

Вот и все, ответ был изменен на h, что означает хапи. Теперь вы можете просто вернуть клиенту то, что хотите получить, или, если ваш ответ немного сложнее, вы можете использовать h.response.

server.route({  
  method: 'GET',
  path:'/',
  handler: (request, h) => {
    return 'Hi, YLD!';
// ----> alternative:
    // const response = h.response('Hi, YLD!');
    // response.code(200);
    // response.header('Content-Type', 'text/plain');
    // return response;
  }
});

s/config/options

Быстрый, быстрый. Замените config на options в своих маршрутах. Все остальное работает, как и раньше (например, payload конфигурация и Joi проверка), как вы можете проследить в этом фрагменте кода:

server.route({  
  method: 'POST',
  path: '/users',
  handler: createUser,
  options: {
    payload: {
      allow: [ 'application/json' ]
    },
    validate: {
      payload: {
        name: Joi.string().required()
      }
    }
  }
});

Зарегистрируйте плагин

В подпись плагина HAPI.js внесены изменения. Теперь он обозначает объект со следующими свойствами: { register, name, version, multiple, dependencies, once, pkg }. Посмотрите здесь небольшой пример, где мы создаем простой yld-hapi-plugin.js.

// inside our plugin (`yld-hapi-plugin.js`)
const plugin = {  
  register: (server, options) => {
    server.route({
      method: 'GET',
      path:'/plugin',
      handler: (request, h) => {
        return 'Hi from a plugin';
      }
    });
  },
  name: 'yld-hapi-plugin',
  version: '1.0.0'
};
module.exports = plugin;

И, наконец, зарегистрируйте его в файле вашего сервера:

// inside my HAPI.js server
const YLDHapiPlugin = require('./plugins/yld-hapi-plugin.js');
/*...*/
await server.register(YLDHapiPlugin);

server.register теперь возвращает обещание, но по-прежнему будет получать массив подключаемых модулей в качестве аргумента, так что await server.register([Inert, Vision, YLDHapiPlugin]) является действительным.

Серверные методы по-прежнему будут работать должным образом

Серверные методы - одна из самых интересных функций HAPI.js, а также полезный и эффективный способ совместного использования функций путем их присоединения к объекту сервера, вместо того, чтобы требовать наличия общего модуля везде, где это необходимо. Здесь нет больших различий, в следующем примере мы просто вызываем метод сервера add, как и раньше, но с использованием нотации async/await, где обратный вызов не требуется в качестве последнего аргумента при создании метода!

server.method('add', (a, b) => {  
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(a + b);
    }, 300);
  });
}, {
  cache: {
    expiresIn: 60000,
    generateTimeout: 1000
  }
});
server.route({  
  method: 'POST',
  path: '/add',
  handler: async (request, h) => {
    try {
      const result = await server.methods.add(1, 2);
      return result;
    } catch (err) {
      throw err;
    }
  }
});

С async/await приходит отскок!

bounce - это модуль HAPI.js, который делает скрытые ошибки видимыми. Посмотрите следующий пример, в котором мы используем функцию Bounce.rethrow. В этом случае b.c.d может быть скрытой ошибкой (из-за try/catch & async/await), если bounce не используется. Bounce позволяет фильтровать по system и boom ошибкам.

server.method('add', (a, b) => {  
  return new Promise((resolve, reject) => {
    const a = b.c.d;
    reject('The line before should explode: ' + a);
  });
});
server.route({  
  method: 'POST',
  path: '/add',
  handler: async (request, h) => {
let result = null;
    try {
      result = await server.methods.add(1, 2);
      return result;
    } catch (err) {
      Bounce.rethrow(err, 'system');
    }
    return result;
  }
});

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

Опубликовано Даниэлой Матос де Карвалью (инженер-программист в YLD) в Инженерном блоге YLD