OpenAPI JSON对象作为查询参数

2023/05/19

1. 概述

在本教程中,我们将学习如何使用OpenAPI将JSON对象作为查询参数。

2. OpenAPI 2中的查询参数

OpenAPI 2不支持对象作为查询参数;仅支持原始值和原始数组。

因此,我们希望将JSON参数定义为字符串。

为了实际看到这一点,让我们将一个名为params的参数定义为一个字符串,尽管我们将在后端将其解析为JSON:

swagger: "2.0"
...
paths:
    /tickets:
        get:
            tags:
                - "tickets"
            summary: "Send an JSON Object as a query param"
            parameters:
                - name: "params"
                  in: "path"
                  description: "{\"type\":\"foo\",\"color\":\"green\"}"
                  required: true
                  type: "string"

因此,而不是:

GET http://localhost:8080/api/tickets?type=foo&color=green

干的好:

GET http://localhost:8080/api/tickets?params={"type":"foo","color":"green"}

3. OpenAPI 3中的查询参数

OpenAPI 3引入了对对象作为查询参数的支持。

要指定JSON参数,我们需要将内容部分添加到我们的定义中,其中包括MIME类型和模式:

openapi: 3.0.1
...
paths:
    /tickets:
        get:
            tags:
                - tickets
            summary: Send an JSON Object as a query param
            parameters:
                -   name: params
                    in: query
                    description: '{"type":"foo","color":"green"}'
                    required: true
                    schema:
                        type: object
                        properties:
                            type:
                                type: "string"
                            color:
                                type: "string"

我们的请求现在看起来像:

GET http://localhost:8080/api/tickets?params[type]=foo¶ms[color]=green

而且,实际上,它仍然可以看起来像:

GET http://localhost:8080/api/tickets?params={"type":"foo","color":"green"}

第一个选项允许我们使用参数验证,这将让我们在发出请求之前知道是否有问题。

对于第二个选项,我们用它来换取对后端的更好控制以及OpenAPI 2兼容性。

4. URL编码

请务必注意,在做出将请求参数作为JSON对象传输的决定时,我们需要对参数进行URL编码以确保安全传输。

因此,要发送以下URL:

GET /tickets?params={"type":"foo","color":"green"}

我们实际上会这样做:

GET /tickets?params=%7B%22type%22%3A%22foo%22%2C%22color%22%3A%22green%22%7D

5. 限制

另外,让我们记住将JSON对象作为一组查询参数传递的限制:

  • 降低安全性
  • 参数长度限制

例如,我们在查询参数中放置的数据越多,出现在服务器日志中的数据就越多,敏感数据暴露的可能性就越高。

此外,单个查询参数不能超过2048个字符。当然,我们都可以想象我们的JSON对象比这更大的场景。实际上,我们的JSON字符串的URL编码实际上会将我们的有效负载限制为大约1000个字符。

一种解决方法是在正文中发送更大的JSON对象。通过这种方式,我们解决了安全问题和JSON长度限制。

实际上,GET或POST都支持这个。通过GET发送正文的原因之一是维护我们API的RESTful语义。

当然,它有点不寻常并且没有得到普遍支持。例如,某些JavaScript HTTP库不允许GET请求具有请求主体。

简而言之,这种选择是语义和通用兼容性之间的权衡。

6. 总结

综上所述,在本文中我们学习了如何使用OpenAPI将JSON对象指定为查询参数。然后,我们观察了后端的一些影响。

与往常一样,本教程的完整源代码可在GitHub上获得。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章