连接响应验证

Connexion response validation

提问人:gratz 提问时间:10/30/2023 最后编辑:gratz 更新时间:10/30/2023 访问量:36

问:

使用最新的稳定版本 Connexion (2.14.2),该文档指出响应验证可用于“使用 jsonschema 验证所有响应,并且在开发过程中特别有用”

使用以下基本应用和 openapi 规范时,验证机制不会选取响应包含架构中未定义的 JSON 键/值对:

openapi: "3.0.0"

info:
  title: Hello World
  version: "1.0"
servers:
  - url: /openapi

paths:
  /version:
    get:
      operationId: app.version
      responses:
        200:
          description: Version
          content:
            application/json:
              schema:
                type: object
                properties:
                  version:
                    description: Version
                    example: '1.2.3'
                    type: string
import connexion


def version() -> dict:
  return {
    'foo': 'bar',
    'version': '1.2.3'
  }

app = connexion.FlaskApp(__name__)
app.add_api('openapi.yaml', validate_responses=True)
app.run(port=3000)

验证似乎通常有效,我的意思是我可以将函数的定义更改为以下内容,并且将产生验证错误:version

def version() -> dict:
  return {
    'foo': 'bar',
    'version': 5
  }
{
  "detail": "5 is not of type 'string'\n\nFailed validating 'type' in schema['properties']['version']:\n    {'description': 'Version', 'example': '1.2.3', 'type': 'string'}\n\nOn instance['version']:\n    5",
  "status": 500,
  "title": "Response body does not conform to specification",
  "type": "about:blank"
}

是我在这里做错了什么,还是 Connexion/jsonschema 不执行无关(或未知)键/值对的验证?

Python 验证 OpenAPI 连接

评论


答:

1赞 Jeremy Fiel 10/30/2023 #1

JSON Schema 是一种基于约束的语言,任何不指定/约束的内容都是允许的

在您的例子中,属性未定义,因此被忽略;没有对其施加任何限制。如果要阻止架构中的其他属性,可以使用fooadditionalProperties: false

openapi: "3.0.3"

info:
  title: Hello World
  version: "1.0"
servers:
  - url: /openapi

paths:
  /version:
    get:
      operationId: app.version
      responses:
        200:
          description: Version
          content:
            application/json:
              schema:
                additionalProperties: false
                type: object
                properties:
                  version:
                    description: Version
                    example: '1.2.3'
                    type: string

然后您的实例将失败

def version() -> dict:
  return {
    'foo': 'bar',
    'version': 5
  }

您可以在此入门指南中了解有关 JSON 架构的所有信息