如何调和 REST 和 JSONschema?
How to conciliate REST and JSONschema?
我正在开始一个新项目,该项目包含一个带有 pyramid/python 后端的 Extjs 6 应用程序。
由于这种架构,后端将只提供一个 RPC,不会直接提供任何页面。我对这种东西的实现通常是基于 REST 的,并且非常适合这个 CRUD 应用程序。
关于数据验证,我想从 Colander/Peppercorn 转移到更简单、更流线型的 json 架构。
这里的想法是将各种请求的所有参数 - 减去 url 中包含的 id 移动到一个 json 主体中,这样可以很容易地处理json架构。
这里的主要问题是 GET 请求不应该有主体,我绝对想把参数放在那里(过滤器、分页等)。
可能有一些 REST 或类似 REST 和 JSONschema 的方法,但我无法在网上找到任何东西。
编辑:有人在 GET HTTP 请求中提到了关于 body 的问题。虽然在 GET HTTP 请求中放入正文在某种程度上是可能的,但它违反了 HTTP 1.1 规范的一部分,因此这不是解决此问题的方法。
我不明白你为什么需要做任何具体的事情。在 Pylons request.GET
returns 中,查询字符串中参数的字典(实际上是 MultiDict,但基本相同)。您可以轻松地将其转换为 JSON 或直接将其传递给架构验证。
如果我理解正确的话,您想使用 JSON 模式进行输入验证,但您正在努力弄清楚如何在 [=40= 中使用 JSON 模式验证查询参数] 方式。
遗憾的是,没有明确的答案。 JSON 架构并非为此而设计。以下是我在使用 REST 和 JSON Schema 时考虑过的选项。
- 将查询参数转换为 JSON 然后根据架构进行验证
- 将您的 JSON 填入查询参数并验证该参数的值。 (即 /foo/1?params={"page": 2, "perPage": 10})
- 使用 POST 而不是 GET,当人们告诉您您的 REST 方式有误时,请用手指捂住耳朵。反正他们知道什么。
我更喜欢选项 1,因为它是惯用的 HTTP。
选项 2 可能是最容易在后端使用的,但它很脏。
选项 3 主要是个玩笑,但严肃地说,REST 或 HTTP 中没有任何内容表明 POST 只能用于创建。事实上,它是 HTTP 方法中最灵活和通用的。把它想象成一个做某事的工厂。某些东西可以生成并存储新资源,或者只是 return 它。如果您发现需要发送大量查询参数,那么它可能不是真正简单的 GET。我的经验法则是,如果结果本质上不可缓存,则 POST 可能更合适(或者至少不是不合适)。
最干净的方法是将 JSON 字符串放在单个查询参数中。如果你有一个 JSON 模式来验证它,客户端可以使用相同的 JSON 模式,因此已经有 JSON 形式的数据。
http://example.net/some/model/1?query={"foo":1,"bar":["baz","qux"]}
如果您出于某种原因不喜欢在查询中使用 JSON,您可以使用一个标准来转换查询参数。 There is no universally agreed-upon specification for param strings,但有一些做法,具体取决于语言和 framework/library。
示例:http://example.net/some/model/1?foo=1,bar[]=baz,bar[]=qux
对于新用户来说,这可能看起来更清晰,但如果客户端使用 lib/language 会以不同方式查询 JSON,则会更加困难。
我正在开始一个新项目,该项目包含一个带有 pyramid/python 后端的 Extjs 6 应用程序。
由于这种架构,后端将只提供一个 RPC,不会直接提供任何页面。我对这种东西的实现通常是基于 REST 的,并且非常适合这个 CRUD 应用程序。
关于数据验证,我想从 Colander/Peppercorn 转移到更简单、更流线型的 json 架构。
这里的想法是将各种请求的所有参数 - 减去 url 中包含的 id 移动到一个 json 主体中,这样可以很容易地处理json架构。
这里的主要问题是 GET 请求不应该有主体,我绝对想把参数放在那里(过滤器、分页等)。
可能有一些 REST 或类似 REST 和 JSONschema 的方法,但我无法在网上找到任何东西。
编辑:有人在 GET HTTP 请求中提到了关于 body 的问题。虽然在 GET HTTP 请求中放入正文在某种程度上是可能的,但它违反了 HTTP 1.1 规范的一部分,因此这不是解决此问题的方法。
我不明白你为什么需要做任何具体的事情。在 Pylons request.GET
returns 中,查询字符串中参数的字典(实际上是 MultiDict,但基本相同)。您可以轻松地将其转换为 JSON 或直接将其传递给架构验证。
如果我理解正确的话,您想使用 JSON 模式进行输入验证,但您正在努力弄清楚如何在 [=40= 中使用 JSON 模式验证查询参数] 方式。
遗憾的是,没有明确的答案。 JSON 架构并非为此而设计。以下是我在使用 REST 和 JSON Schema 时考虑过的选项。
- 将查询参数转换为 JSON 然后根据架构进行验证
- 将您的 JSON 填入查询参数并验证该参数的值。 (即 /foo/1?params={"page": 2, "perPage": 10})
- 使用 POST 而不是 GET,当人们告诉您您的 REST 方式有误时,请用手指捂住耳朵。反正他们知道什么。
我更喜欢选项 1,因为它是惯用的 HTTP。
选项 2 可能是最容易在后端使用的,但它很脏。
选项 3 主要是个玩笑,但严肃地说,REST 或 HTTP 中没有任何内容表明 POST 只能用于创建。事实上,它是 HTTP 方法中最灵活和通用的。把它想象成一个做某事的工厂。某些东西可以生成并存储新资源,或者只是 return 它。如果您发现需要发送大量查询参数,那么它可能不是真正简单的 GET。我的经验法则是,如果结果本质上不可缓存,则 POST 可能更合适(或者至少不是不合适)。
最干净的方法是将 JSON 字符串放在单个查询参数中。如果你有一个 JSON 模式来验证它,客户端可以使用相同的 JSON 模式,因此已经有 JSON 形式的数据。
http://example.net/some/model/1?query={"foo":1,"bar":["baz","qux"]}
如果您出于某种原因不喜欢在查询中使用 JSON,您可以使用一个标准来转换查询参数。 There is no universally agreed-upon specification for param strings,但有一些做法,具体取决于语言和 framework/library。
示例:http://example.net/some/model/1?foo=1,bar[]=baz,bar[]=qux
对于新用户来说,这可能看起来更清晰,但如果客户端使用 lib/language 会以不同方式查询 JSON,则会更加困难。