Разрабатывайте RESTful API с помощью Hapi

Node.js внешний интерфейс API

Искал отечественные статьи и использовалHapiразвиватьRESTful APIИх очень мало, некоторые части, представленные сообществом, больше не применимы в новой версии, и в новой версии много изменений.

чтоRESTful API

RESTful API: REST -- передача репрезентативного состояния, дословный перевод с английского означает «передача репрезентативного состояния».

Вы можете обратиться к следующему пониманию:

Hapi

Hapi — это веб-фреймворк для Node.js, фреймворк для создания многофункциональных приложений и сервисов. В настоящее время Hapi v17 поддерживает только узел версии 8.9.0 и выше.

Особенности Хапи

  • Аутентификация и авторизация: встроенные схемы аутентификации и авторизации
  • Кэш: обеспечивает кэширование на стороне клиента и на стороне сервера,catbox
  • Маршрутизация: встроенная маршрутизация
  • Аутентификация: использование Joi
  • Файлы cookie: предоставляет параметры конфигурации для обработки файлов cookie.
  • log: встроенное ведение журнала
  • Обработка ошибок:boom
  • Мониторинг процессов: плагин hapigood

Предпосылки для использования Hapi

  • Установите Node.js версии 8.9.0 и выше.
  • Установить MongoDB
  • Знакомство с концепциями баз данных и практические знания JavaScript

Что нового в Hapi v17

  • Метод server.connection удален, теперь используйте

    const server = new Hapi.Server({
        host: 'localhost',
        port: 3000
    })
    
  • Открытие и закрытие метода службы полностью асинхронно, без обратного вызова

    try {
        await server.start()
    }
    catch (err) {
        console.log(err)
    }
      
    try {
        await server.stop()
    }
    catch (err) {
        console.log(err)
    }
    
  • метод обратного вызова answer() удален, методы response.hold() и response.resume() больше не доступны

    // 以前
    const handler = function (request, reply) {
      return reply('ok');
    };
    
    // 现在
    
    const handler = function (request, h) {
      return 'ok';
    };
    

    Другие примеры использования h:

    const handler = (request, h) => {
      // return a string
      return 'ok'
    
      // return an object and hapi creates JSON out of it
      return { name: 'Authentication Library', library: true }
    
      // redirect to 404
      return h.redirect('/404')
    
      // return a view
      return h.view('index', { name: 'Authentication Library' })
    
      // use the "h" response toolkit to create a response
      return h
       .response(thisHTML)
        .type('text/html')
        .header('X-Custom', 'my-value')
        .code(201)
    }
    
  • Три типа событий запроса request, request-interval, request-error объединены в одно событие запроса

  • Триггерные методы, такие как server.on, request.on, response.on, заменены, вместо них используйте server.events.on(), request.events.on(), response.events.on().

  • Новое расширение запроса:

    server.ext('onPreAuth', (request, h) => { … })
    server.ext('onCredentials', (request, h) => { … })
    server.ext('onPostAuth', (request, h) => { … }) ]
    
  • Замените конфигурацию параметрами при определении маршрутов.

    server.route({
      method: 'POST',
      path: '/',
      options: { … }
    })
    
  • плагин В настоящее время используется

    exports.plugin = { register, name, version, multiple, dependencies, once, pkg }
    

Дополнительные изменения см.Полный журнал изменений GitHub

Вопрос: Создайте простой API с помощью HAPI

Операции CURD, представленные в этом примере

  • Get all demos - GET /demos
  • Get one demo - GET /demo/11
  • Create a demo - POST /demos
  • Edit a demo - PUT /demos/11
  • Delete a demo - DELETE /demos/11

Демо имеет следующие свойства:

  • name
  • age

1 Создайте демонстрационный каталог проекта, окончательная структура которого выглядит следующим образом:

demo
├── package.json
├── server.js 
├── .gitignore (可选)
└── src
    ├
    ├── controller
    |   └── test.js
    └─── models
        └── test.js
   

2 Напишите модель

src/models/test.js
'use strict';

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const demoModel = new Schema({
  name: { type: String, required: true, index: { unique: true } },
  age: { type: Number, required: true }
});

module.exports = mongoose.model('Demo', demoModel, 'demos'); 

писать контроллеры

src/controllers/test.js

var Demo =  require('../models/test');

/**
 * List Demos
 */
exports.list = (req, h) => {
  return Demo.find({}).exec().then((demo) => {

    return { demos: demo };

  }).catch((err) => {

    return { err: err };

  });
}

/**
 * Get Demo by ID
 */
exports.get = (req, h) => {

  return Demo.findById(req.params.id).exec().then((demo) => {

    if(!demo) return { message: 'Demo not Found' };

    return { demos: demo };

  }).catch((err) => {

    return { err: err };

  });
}


/**
 * POST a Demo
 */
exports.create = (req, h) => {

  const demoData = {
    name: req.payload.name,
    age: req.payload.age
  };

  return Demo.create(demoData).then((demo) => {

     return { message: "Demo created successfully", demo: demo };

  }).catch((err) => {

    return { err: err };

  });
}

/**
 * PUT | Update Demo by ID
 */
exports.update = (req, h) => {

  return Demo.findById(req.params.id).exec().then((demo) => {

    if (!demo) return { err: 'Demo not found' };

    demo.name = req.payload.name;
    demo.breed = req.payload.breed;
    demo.age = req.payload.age;
    demo.image = req.payload.image;

    demo.save(dogData);

  }).then((data) => {

      return { message: "Demo data updated successfully" };

  }).catch((err) => {

      return { err: err };

  });
}

/**
 * Delete Demo by ID
 */
exports.remove = (req, h) => {

  return Demo.findById(req.params.id).exec(function (err, demo) {

    if (err) return { dberror: err };
    if (!demo) return { message: 'Demo not found' };

    demo.remove(function (err) {
      if (err) return { dberror: err };

      return { success: true };
    });
  });
}

написать server.js

'use strict';

const Hapi = require('hapi');
const mongoose = require('mongoose');
const DemoController =  require('./src/controllers/test');
const MongoDBUrl = 'mongodb://localhost:27017/demoapi';

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

server.route({
  method: 'GET',
  path: '/demos',
  handler: DemoController.list
});

server.route({
  method: 'GET',
  path: '/demos/{id}',
  handler: DemoController.get
});
server.route({
  method: 'POST',
  path: '/demos',
  handler: DemoController.create
});

server.route({
  method: 'PUT',
  path: '/demos/{id}',
  handler: DemoController.update
});

server.route({
  method: 'DELETE',
  path: '/demos/{id}',
  handler: DemoController.remove
});

(async () => {
  try {  
    await server.start();
    // Once started, connect to Mongo through Mongoose
    mongoose.connect(MongoDBUrl, {}).then(() => { console.log(`Connected to Mongo server`) }, err => { console.log(err) });
    console.log(`Server running at: ${server.info.uri}`);
  }
  catch (err) {  
    console.log(err)
  }
})();

Проверить API

Тест с почтальономhttp://localhost:3000/demos

Добавить проверку авторизации

В настоящее время предстоит много шагов, и вам все еще нужно зарегистрировать платформу, поэтому я не буду пока подробно объяснять.

Ссылаться на

Только для обучения по обмену