首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有方法在Hapi使用的Joi模型中将整数属性定义为int64

有没有方法在Hapi使用的Joi模型中将整数属性定义为int64
EN

Stack Overflow用户
提问于 2022-03-10 09:46:15
回答 2查看 367关注 0票数 0

我有以下Joi模型

代码语言:javascript
运行
复制
const SimpleModel = Joi.object({
    id: Joi.number().integer().required().description('ID')
}).label('SimpleModel');

该模型正在下面的@hapi/hapi路由中使用

代码语言:javascript
运行
复制
{
    method: 'GET',
    path: `/api/v1.0/data`,
    handler: () => { id: 1 }, // a mock handler
    config: {
        plugins: {
            'hapi-swagger': {
                responses: {
                    200: {
                        description: 'OK',
                        schema: SimpleModel
                    }
                }
            }
        }
    }
}

上面的模型生成如下所示的swagger定义

代码语言:javascript
运行
复制
swagger: '2.0'
host: localhost:8080
basePath: /api
info: 
  title: 'Swagger for SimpleModel'
  version: '1.0'
schemes:
  - http
  - https
paths:
  /v1.0/data:
    get:
      summary: Returns an object
      responses:
        '200':
          schema:
            $ref: '#/definitions/SimpleModel'
          description: OK
definitions:
  SimpleModel:
    type: object
    properties:
      id:
        type: integer
        description: ID
    required:
      - id

我想要的是在id中添加一个额外的字段,即format: int64

代码语言:javascript
运行
复制
definitions:
  SimpleModel:
    type: object
    properties:
      id:
        type: integer
        format: int64 # <-- new field here!
        description: ID
    required:
      - id

虽然swagger支持这一点,但是我无法在我的Joi模型中找到任何方法来定义它,这样它就会出现在hapi-swagger生成的swagger中。

我已经在网上搜索了好几天了,但是我在网上找不到任何有用的东西,不管是文档还是例子。

是否有一种方法可以在生成的format: int64中包含SimpleModel

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-23 20:14:22

package.json

代码语言:javascript
运行
复制
{
  "name": "71422008",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "@hapi/hapi": "^20.2.1",
    "@hapi/inert": "^6.0.5",
    "@hapi/vision": "^6.1.0",
    "blipp": "^4.0.2",
    "hapi-swagger": "^14.2.5",
    "joi": "^17.6.0",
    "qs": "^6.10.3"
  }
}

index.js

代码语言:javascript
运行
复制
const Hapi = require('@hapi/hapi');
const Joi = require('joi');
const Blipp = require('blipp');
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');
const HapiSwagger = require('hapi-swagger');
const HapiSwaggerProperties = require('hapi-swagger/lib/properties');

const _parseNumber = HapiSwaggerProperties.prototype.parseNumber;
HapiSwaggerProperties.prototype.parseNumber = function(property, joiObj) {
  let _property = _parseNumber.apply(this, [property, joiObj]);
  _property.format = 'int64';
  return _property;
}
const SimpleModel = Joi.object({
    id: Joi.number().integer().required().description('ID')
}).label('SimpleModel');

const ser = async () => {
  const swaggerOptions = {
    info: {
      title: 'Test API Documentation',
      description: 'This is a sample example of API documentation.'
    }
  };

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

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

  server.route({
    method: 'GET',
    path: `/api/v1.0/data`,
    options: {
      handler: () => { id: 1 }, // a mock handler
      tags: ['api'],
      plugins: {
        'hapi-swagger': {
          responses: {
            200: {
              description: 'OK',
              schema: SimpleModel
            }
          }
        }
      }
    },
  });

  await server.start();
  return server;
};

ser()
  .then((server) => {
    console.log(`Server listening on ${server.info.uri}`);
  })
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });

输出:

代码语言:javascript
运行
复制
...
    "definitions": {
        "SimpleModel": {
            "type": "object",
            "properties": {
                "id": {
                    "type": "integer",
                    "description": "ID",
                    "format": "int64"
                }
            },
            "required": [
                "id"
            ]
        }
    }
...

具有自定义类型的示例2:

代码语言:javascript
运行
复制
const Hapi = require('@hapi/hapi');
const Joi = require('joi');
const Blipp = require('blipp');
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');
const HapiSwagger = require('hapi-swagger');
const HapiSwaggerProperties = require('hapi-swagger/lib/properties');

const custom = Joi.extend(joi => ({
  type: 'number',
  base: Joi.number().$_setFlag('type', 'integer').$_setFlag('format', 'int64'),
  rules: {
    i32: {
      method(first, second) {
        return this.$_setFlag('type', 'integer').$_setFlag('format', 'int32');
      }
    }
  }
}));

const _parseNumber = HapiSwaggerProperties.prototype.parseNumber;
HapiSwaggerProperties.prototype.parseNumber = function(property, joiObj) {
  let _property = _parseNumber.apply(this, [property, joiObj]);

  const describe = joiObj.describe();
  if (describe.flags) {
    if (describe.flags.format) {
      _property.format = describe.flags.format;
    }

    if (describe.flags.type) {
      _property.type = describe.flags.type;
    }
  }
  return _property;
}

const SimpleModel = Joi.object({
    id: Joi.number().integer().required().description('ID'),
    seconds: custom.number().i32(),
    epochSeconds: custom.number(),
}).label('SimpleModel');

const ser = async () => {
  const swaggerOptions = {
    info: {
      title: 'Test API Documentation',
      description: 'This is a sample example of API documentation.'
    }
  };

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

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

  server.route({
    method: 'GET',
    path: `/api/v1.0/data`,
    options: {
      handler: () => { id: 1 }, // a mock handler
      tags: ['api'],
      plugins: {
        'hapi-swagger': {
          responses: {
            200: {
              description: 'OK',
              schema: SimpleModel
            }
          }
        }
      }
    },
  });

  await server.start();
  return server;
};

ser()
  .then((server) => {
    console.log(`Server listening on ${server.info.uri}`);
  })
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });

输出:

代码语言:javascript
运行
复制
...
    "definitions": {
        "SimpleModel": {
            "type": "object",
            "properties": {
                "id": {
                    "type": "integer",
                    "description": "ID"
                },
                "seconds": {
                    "type": "integer",
                    "format": "int32"
                },
                "epochSeconds": {
                    "type": "integer",
                    "format": "int64"
                }
            },
            "required": [
                "id"
            ]
        }
    }
...

示例3具有自定义类型和元属性:

代码语言:javascript
运行
复制
const Hapi = require('@hapi/hapi');
const Hoek = require('@hapi/hoek');
const Joi = require('joi');
const Blipp = require('blipp');
const Inert = require('@hapi/inert');
const Vision = require('@hapi/vision');
const HapiSwagger = require('hapi-swagger');
const HapiSwaggerProperties = require('hapi-swagger/lib/properties');

const custom = Joi.extend(joi => ({
  type: 'int',
  base: Joi.number().meta({
    'type': 'integer',
    'format': 'int32',
  }),
  rules: {
    i64: {
      method(first, second) {
        return this.meta({
          'type': 'integer',
          'format': 'int64',
        });
      }
    }
  }
}));

const _parsePropertyMetadata = HapiSwaggerProperties.prototype.parsePropertyMetadata;
HapiSwaggerProperties.prototype.parsePropertyMetadata = function(property, name, parent, joiObj) {
  let _property = _parsePropertyMetadata.apply(this, [property, name, parent, joiObj]);

  const _type = Hoek.reach(joiObj, 'type');
  if (!this.propertyMap[_type]) {
    delete _property['x-meta']
  }

  let xMeta = Hoek.reach(joiObj, '$_terms.metas');
  xMeta = xMeta.length > 0 ? xMeta[xMeta.length - 1] : undefined;
  if (xMeta) {
    if (xMeta.type) {
      _property.type = xMeta.type;
    }

    if (xMeta.format) {
      _property.format = xMeta.format;
    }
  }

  return _property;
}

const SimpleModel = Joi.object({
    id: Joi.number().integer().required().description('ID'),
    seconds: custom.int(),
    epochSeconds: custom.int().i64(),
}).label('SimpleModel');

const ser = async () => {
  const swaggerOptions = {
    info: {
      title: 'Test API Documentation',
      description: 'This is a sample example of API documentation.'
    }
  };

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

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

  server.route({
    method: 'GET',
    path: `/api/v1.0/data`,
    options: {
      handler: () => { id: 1 }, // a mock handler
      tags: ['api'],
      plugins: {
        'hapi-swagger': {
          responses: {
            200: {
              description: 'OK',
              schema: SimpleModel
            }
          }
        }
      }
    },
  });

  await server.start();
  return server;
};

ser()
  .then((server) => {
    console.log(`Server listening on ${server.info.uri}`);
  })
  .catch((err) => {
    console.error(err);
    process.exit(1);
  });
代码语言:javascript
运行
复制
...
    "definitions": {
        "SimpleModel": {
            "type": "object",
            "properties": {
                "id": {
                    "type": "integer",
                    "description": "ID"
                },
                "seconds": {
                    "type": "integer",
                    "format": "int32"
                },
                "epochSeconds": {
                    "type": "integer",
                    "format": "int64"
                }
            },
            "required": [
                "id"
            ]
        }
    }
...
票数 1
EN

Stack Overflow用户

发布于 2022-05-14 17:38:59

使用我获得的commentsanswer,我能够向hapi-swagger的存储库提交一个拉请求。

因此,从v14.3.0版本开始,下面的Joi模型定义将给出所需的结果

代码语言:javascript
运行
复制
const SimpleModel = Joi.object({
    id: Joi.number().integer().required().description('ID').meta({ format: 'int64' })
}).label('SimpleModel');
代码语言:javascript
运行
复制
definitions:
  SimpleModel:
    type: object
    properties:
      id:
        type: integer
        format: int64
        description: ID
    required:
      - id
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71422008

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档