如何在Swagger-PHP中定义键与对应固定类型值的配对?
问题
需要在@OA\JsonContent()中定义key和value两个属性,要求每个键对应固定类型的值,例如:
scoring.password.length => boolean scoring.entity.device => boolean scoring.twofactor_when_score_gte => integer
尝试了如下代码,但效果不佳:value与key类型不关联,且在Redocly中键名不可见:
@OA\RequestBody( required=true, description="Pass setting key-value pair", @OA\JsonContent( required={"key", "value"}, @OA\Property(property="key", type="object", @OA\AdditionalProperties(type="array", @OA\Items(oneOf={ @OA\Property(property="scoring.password.length", type="bool"), @OA\Property(property="scoring.password.complexity.symbols", type="bool"), @OA\Property(property="scoring.password.complexity.mixed_case", type="bool"), @OA\Property(property="scoring.password.leaks", type="bool"), @OA\Property(property="scoring.password.complexity.letters", type="bool"), @OA\Property(property="scoring.password.complexity.numbers", type="bool"), @OA\Property(property="scoring.entity.device", type="bool"), @OA\Property(property="scoring.entity.geodata", type="bool"), @OA\Property(property="scoring.entity.disposable_email", type="bool"), @OA\Property(property="scoring.entity.leaks.phone", type="bool"), @OA\Property(property="scoring.entity.leaks.email", type="bool"), @OA\Property(property="scoring.entity.blacklist", type="bool"), @OA\Property(property="scoring.twofactor_when_score_gte", type="integer"), @OA\Property(property="scoring.disallow_when_score_gte", type="integer"), @OA\Property(property="deny_login.blacklist.email", type="bool"), @OA\Property(property="deny_login.blacklist.domain", type="bool"), @OA\Property(property="deny_login.blacklist.ip", type="bool"), } ) ), ), @OA\Property(property="value", type="string", description="The value of the setting (int|string|bool)"), ),
解决方案
要实现指定键与对应固定类型值关联的效果,同时让Redocly正确展示键名和类型,得换个写法——用oneOf枚举每个合法的key-value组合,而不是把key定义成对象类型。
场景1:单次传递单个键值对
如果API每次只接受一组key-value,用下面的写法:
@OA\RequestBody( required=true, description="传递设置的键值对", @OA\JsonContent( oneOf={ // 布尔类型键值对 @OA\Schema( required={"key", "value"}, @OA\Property(property="key", type="string", example="scoring.password.length"), @OA\Property(property="value", type="boolean", example=true) ), @OA\Schema( required={"key", "value"}, @OA\Property(property="key", type="string", example="scoring.entity.device"), @OA\Property(property="value", type="boolean", example=false) ), // 整数类型键值对 @OA\Schema( required={"key", "value"}, @OA\Property(property="key", type="string", example="scoring.twofactor_when_score_gte"), @OA\Property(property="value", type="integer", example=70) ), // 补充剩余所有键值组合... @OA\Schema( required={"key", "value"}, @OA\Property(property="key", type="string", example="scoring.disallow_when_score_gte"), @OA\Property(property="value", type="integer", example=90) ), @OA\Schema( required={"key", "value"}, @OA\Property(property="key", type="string", example="deny_login.blacklist.email"), @OA\Property(property="value", type="boolean", example=true) ) }, @OA\Examples( example="布尔类型设置", value={"key": "scoring.password.length", "value": true}, summary="布尔类型设置示例" ), @OA\Examples( example="整数类型设置", value={"key": "scoring.twofactor_when_score_gte", "value": 70}, summary="整数类型设置示例" ) ) )
- 用
oneOf枚举每组合法的键值对,确保每个key对应的value类型固定,解决类型不匹配的问题。 - 每个
@OA\Schema单独定义一组键值对,Redocly会清晰展示每个键名和对应类型。 - 加
@OA\Examples能让文档更直观,方便开发者理解。
场景2:单次传递多个键值对
如果API支持批量提交多个设置,就用对象结构结合正则匹配键名:
@OA\RequestBody( required=true, description="批量传递设置键值对", @OA\JsonContent( type="object", patternProperties={ // 匹配所有布尔类型的键 "^scoring\.password\.(length|complexity\.(symbols|mixed_case|letters|numbers)|leaks)$": { "type": "boolean" }, "^scoring\.entity\.(device|geodata|disposable_email|leaks\.(phone|email)|blacklist)$": { "type": "boolean" }, "^deny_login\.blacklist\.(email|domain|ip)$": { "type": "boolean" }, // 匹配整数类型的键 "^scoring\.(twofactor_when_score_gte|disallow_when_score_gte)$": { "type": "integer" } }, additionalProperties=false, // 禁止传递未定义的键 example={ "scoring.password.length": true, "scoring.twofactor_when_score_gte": 70, "deny_login.blacklist.email": false } ) )
- 用正则表达式匹配键名,自动约束对应的值类型,不用重复定义每个键。
additionalProperties=false确保只能提交文档里的合法键,避免非法参数。- 支持一次性提交多组设置,符合批量操作的场景。
内容的提问来源于stack exchange,提问作者Petr Katerinak
相关产品推荐
相关产品推荐

