Создаём REST API сервер на Hapi часть 4: Swagger/OpenAPI

Swagger - это такая хреновина, которая позволяет автоматически генерировать OpenAPI документацию. Для hapi есть специальный модуль hapi-swagger.

Ставим модули:

npm i hapi-swagger inert vision

Открываем наш server.js немного его переделываем, нам нужно подключить hapi-swagger :

...
const HapiSwagger = require('hapi-swagger');
const Vision = require('vision');
const Inert = require('inert');
const Package = require('../package');

...
const swaggerOptions = {
  jsonPath: '/documentation.json', // Это дефолтное значение
  documentationPath: '/documentation', // и это тоже
  info: {
    title: Package.description,
    version: Package.version
  },
};

...
  await server.register([
    hapiBoomDecorators,
    Inert,
    Vision,
    {
      plugin: HapiSwagger,
      options: swaggerOptions
    },
    {
      plugin: require('hapi-sequelizejs'),
      options: [
        {
          name: config.db.database, 
          models: [__dirname + '/src/models/*.js'], // Путь к моделькам
          //ignoredModels: [__dirname + '/server/models/**/*.js'], // Можем некоторые модельки заигнорить
          sequelize: new Sequelize(config.db), // Инициализируем обычный секьюлайз и передаём его параметром
          sync: true, // Синхронизировать/нет модели с реальной бд
          forceSync: false, // Если тру, то таблицы будут дропнуты перед синхронизацией, остарожно
        },
      ],
    }
  ]);

...

После этого, по адресу http://localhost:3030/documentation

hapi swagger openapi

А по адресу http://localhost:3030/documentation.json будет доступна json версия документации, которую можно использовать для автогенерации api.

hapi swagger, json path

Теперь в каждом руте, который нужно включить в автогенерацию документации, нужно указывать тег 'api'

module.exports = {
  method: 'GET',
  path: '/',
  options: {
    handler: response,
    tags: ['api'], // Necessary tag for swagger
    validate: {
    }
  }
};

Если в роуте указана валидация параметров, то описание параметров автоматически включится в сваггер:

module.exports = {
  method: 'POST',
  path: '/messages',
  options: {
    handler: response,
    tags: ['api'], // Necessary tag for swagger
    validate: {
      payload: {
        user_id: Joi.number().integer().required().example(1),
        message: Joi.string().min(1).max(100).required().example('Lorem ipsum')
      }
    }
  }
};

Результат:

hapi swagger, enable route

Можно добавить пример ответа:

const messageSchema = Joi.object({
  id: Joi.number().integer().example(1),
  user_id: Joi.number().integer().example(2),
  message: Joi.string().example('Lorem ipsum')
});

const responseScheme = Joi.object({
  meta: Joi.object({
    total: Joi.number().integer().example(3)
  }),
  data: Joi.array().items(messageSchema)
});

module.exports = {
  method: 'POST',
  path: '/messages',
  options: {
    handler: response,
    tags: ['api'], // Necessary tag for swagger
    validate: {
      payload: {
        user_id: Joi.number().integer().required().example(1),
        message: Joi.string().min(1).max(100).required().example('Lorem ipsum')
      }
    },
    response: { schema: responseScheme } 
  }
};

Который сваггер будет показывать у себя в документации:

hapi swagger, response scheme

Как обычно весь код можно посмотреть на гитхабе: https://github.com/hololoev/api_hapi_example_4



Создаём REST API сервер на Hapi часть 3: Валидация запросов

Валидация реквестов нужна для того, чтобы наши доблестные пользователи не слали всякую херню, да и чтобы хацкерам было сложнее найти уязвимости.

Неформальный обзор Lenovo Thinkpad Yoga L380

Мой не совсем старенький Ideapad 510-15IKB, поехал вентилятором и стал гудеть как камаз, и это всего после 1.5 лет работы. Ну и ещё меня бесила его батарейка, на которой он кое-как 2 часа работал без серьёзной нагрузки, и вес в 2.5кг, и размер 15' меня задолбал, короче, срочно нужен был новый бук.


(0) Комментариев