用hapi自动生成一个RESTful的CRUD接口文档测试界面

1,037 阅读2分钟

前后端分离需要RESTful接口来交换数据,接口文档是连接前后端的桥梁。编写标准的接口文档、并随着项目需求的变更不断变更,这是后端开发的一个痛点。hapi-swagger模块的引入,帮我们解决了这个难题。只要在项目代码中同步进行配置,hapi-swagger插件就可以自动生成标准的API接口文档,hapi-swagger插件提供了一个UI界面,通过浏览器进行访问,非常便于测试API接口。

本文在作者上篇文章《五分钟用hapi和mongoDB构建一个RESTful的CRUD接口API》的基础上,介绍如何引入配置hapi-swagger插件,根据代码自动生成API接口文档的测试界面。

安装hapi-swagger插件

hapi-swagger插件需要和@hapi/inert@hapi/vision@hapi/joipackage插件配合在一起使用。

Joi 是一种验证模块,验证数据结构与数值的合规性。

通过以下命令安装上述插件:

npm i api-swagger @hapi/inert @hapi/vision @hapi/joi package

引入插件

在入口文件index.js中引入 api-swagger @hapi/inert @hapi/vision 插件。

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

const init = async () => {}函数中注册插件:

const swaggerOptions = {
    info: {
      title: 'Test API Documentation',
      version: Pack.version,
    },
  };

  await server.register([
    Inert,
    Vision,
    {
      plugin: HapiSwagger,
      options: swaggerOptions
    }
  ]);

使用插件

/routes/posts.js文件中进行配置。

首先,需要引入joi:

const Joi = require('@hapi/joi')

然后,对posts自定义路由插件进行配置:

exports.plugin = {
    name:'routePosts',
    version: '1.0.0',
    //pkg: require('../package.json'),
    register: async function (server, options) {

        server.route({
            path: '/posts',
            method: 'GET',
            options: {
                handler: PostsController.getAll,
                description: 'get posts',
                tags: ['api']
            }

        });
        server.route({
            path: '/posts/{id}',
            method: 'GET',

            options: {
                handler: PostsController.findById,
                description: 'get post by id',
                tags: ['api'],
                validate: {
                    params: Joi.object({
                        id: Joi.string()
                            .required()
                            .description('the id of the post')
                    })
                }
            }
        });
        server.route({
            path: '/posts',
            method: 'POST',

            options: {
                handler: PostsController.create,
                description: 'create post',
                tags: ['api'],
                validate: {
                    payload: Joi.object({
                        title: Joi.string()
                            .required()
                            .description('the post title'),
                        content: Joi.string()
                            .description('the post content'),
                        rating: Joi.number()
                            .description('the post rating'),
                    })
                }
            }
        });
        server.route({
            path: '/posts/{id}',
            method: 'PATCH',
            
            options: {
                handler: PostsController.edit,
                description: 'get post by id',
                tags: ['api'],
                validate: {
                    params: Joi.object({
                        id: Joi.string()
                            .required()
                            .description('the id of the post')
                    }),
                    payload: Joi.object({
                        title: Joi.string()
                            .required()
                            .description('the post title'),
                        content: Joi.string()
                            .required()
                            .description('the post content'),
                        rating: Joi.number()
                            .required()
                            .description('the post rating'),
                    })
                }
            }
        });
        server.route({
            path: '/posts/{id}',
            method: 'DELETE',
            
            options: {
                handler: PostsController.delete,
                description: 'get post by id',
                tags: ['api'],
                validate: {
                    params: Joi.object({
                        id: Joi.string()
                            .required()
                            .description('the id of the post')
                    })
                }
            }
        });

    }

最后,在入口文件index.js中注册自定义路由插件:

await server.register([{
      plugin: require('./routes/posts'),
      options:{}
    }
]);

测试

在终端窗口输入命令:

node .

项目成功启动后,提示:

Listening on http://localhost:8000

在浏览器中输入http://localhost:8000/documentation即可通过接口文档界面进行测试。