我的资源有一个ID(典型情况)。
它还有一个 slug ,它是人类可读但仍然唯一的标识符(主要是美化URL)。
创建资源时,此 slug 是可选。如果客户端提供了一个,则说明该客户端正在使用;否则,服务器将生成一个。
但是,在读取资源时,该子弹是必需的。
我们确实希望清楚区别,所以任何阅读OpenAPI规范的工具都知道确切的期望。
这当然可以通过使用与allOf
修饰符链接的不同模式的混合来实现(请参见下面的示例),但是我想避免执行这种组合(假设它首先与工具一起使用) )。
所以我的问题是:
OpenAPI> = 3.0.2中是否有一种方法可以声明属性required-readOnly和optional-writeOnly?
使用成分的解决方案:
openapi: 3.0.2
info:
title: Person API
version: 1.0.0
paths:
'/persons/{person-slug}':
get:
parameters:
- $ref: '#/components/parameters/PersonSlug'
responses:
200:
description: Information on a person.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SlugRead'
- $ref: '#/components/schemas/Person'
post:
parameters:
- $ref: '#/components/parameters/PersonSlug'
responses:
200:
description: Information on a person.
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/SlugWrite'
- $ref: '#/components/schemas/Person'
components:
parameters:
PersonSlug:
name: 'person-slug'
description: Human readable unique ID of a person.
required: true
in: path
schema:
type: string
schemas:
SlugRead: # required
required:
- slug
properties:
slug:
type: string
readOnly: true
SlugWrite: # not required
properties:
slug:
type: string
Person:
required:
- first_name
- last_name
- birth_date
properties:
first_name:
type: string
last_name:
type: string
birth_date:
type: string
format: date
答案 0 :(得分:2)
对于将来偶然发现这个问题的任何人,我使用基本架构和派生架构解决了特定操作。
Person:
properties:
id:
type: integer
readOnly: true
name:
type: string
slug:
type: string
PersonWRITE:
allOf: # name is required, slug is optional and id is not available
- $ref: '#/components/schemas/Person'
- required: [name]
PersonREAD:
allOf: # everything is available and required
- $ref: '#/components/schemas/Person'
- required: [id, name, slug]
它本质上是 OP 的解决方案,但移到了组件级别,因此您不必在请求/响应定义中使用“allOf”。
编辑: 请注意,以下内容无效:
PersonWRITE: #wrong
$ref: '#/components/schemas/Person'
required: [name]
键是allOf
,它结合了列表中对象的所有属性。在 $ref 扩展后,模式看起来像这样(仍然是一个有效的 yaml,我只是稍微对它进行了 jsonified,以指出数组元素实际上是两个属性将被组合的对象):
PersonWRITE:
allOf: [
{
properties: {
id: { type: integer, readOnly: true },
name: { type: string },
slug: { type: string }
}
},
{
required: [name]
}
]
答案 1 :(得分:0)
看不到如何准确地实现 ,但我认为可以通过对期望的(只写)vs分配的(只读)字段使用单独的字段来定义效果鼻涕虫:
Person:
required:
- first_name
- last_name
- birth_date
- assigned_slug
properties:
first_name:
type: string
last_name:
type: string
birth_date:
type: string
format: date
assigned_slug:
type: string
readOnly: true
desired_slug:
type: string
writeOnly: true
不知道是否有任何工具会用它做正确的事!