我使用openapi-generator
6.2.1
从openapi
3.0.2
YAML文件生成服务器端Java Spring接口和TypeScript客户机类。
我尝试使用oneOf
功能来指定特定属性可以具有以下两种确切类型之一:PublicMetadataSchemaV1
或ClosedMetadataSchemaV1
中的一个或多个。
定义如下:
ReadRaidMetadataResponseV1:
# Using oneOf/discriminator is probably pushing too close to the edge of
# what openapi-gen can do yet, for example that's why metadataSchema is a
# string instead of an enum:
# https://github.com/OpenAPITools/openapi-generator/pull/13846
type: object
description: Any type of metadata
oneOf:
# - $ref: 'metadata-schema-v1.yaml#/components/schemas/MetadataSchemaV1'
- $ref: '#/components/schemas/PublicMetadataSchemaV1'
- $ref: '#/components/schemas/ClosedMetadataSchemaV1'
discriminator:
propertyName: metadataSchema
mapping:
raido-metadata-schema-v1: '#/components/schemas/PublicMetadataSchemaV1'
closed-metadata-schema-v1: '#/components/schemas/ClosedMetadataSchemaV1'
PublicMetadataSchemaV1:
description: >
This object only exists because openapi-gen discriminator needs to be
a string, currently.
See https://github.com/OpenAPITools/openapi-generator/pull/13846.
Eventually, want the mapping to just use MetadataSchemaV1.
type: object
required: [ metadataSchema, id, titles, dates, access]
# this is how we make PublicMetadataSchemaV1 inherit all the fields oneOf:
# MetadataSchemaV1.
allOf:
- $ref: 'metadata-schema-v1.yaml#/components/schemas/MetadataSchemaV1'
properties:
# This is where we "override" the type of metadataSchema to be a string
# instead of the enum that we would prefer it to be.
# Rather than "string" this should be a "constant" with value `raido-metadata-schema-v1`
# metadataSchema: {$ref: 'shared.yaml#/components/schemas/RaidoMetaschema' }
metadataSchema: { type: string }
ClosedMetadataSchemaV1:
type: object
required: [ metadataSchema, id, titles, dates, access]
properties:
# Rather than "string" this should be a "constant" with value `closed-metadata-schema-v1`
# metadataSchema: {$ref: 'shared.yaml#/components/schemas/RaidoMetaschema' }
metadataSchema: { type: string }
id: {$ref: 'shared.yaml#/components/schemas/IdBlock'}
access: {$ref: 'shared.yaml#/components/schemas/AccessBlock'}
这里的问题是JavaSpring
生成器创建的代码如下所示:
@JsonIgnoreProperties(
value = "metadataSchema", // ignore manually set metadataSchema, it will be automatically generated by Jackson during serialization
allowSetters = true // allows the metadataSchema to be set during deserialization
)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "metadataSchema", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(value = ClosedMetadataSchemaV1.class, name = "ClosedMetadataSchemaV1"),
@JsonSubTypes.Type(value = PublicMetadataSchemaV1.class, name = "PublicMetadataSchemaV1"),
@JsonSubTypes.Type(value = ClosedMetadataSchemaV1.class, name = "closed-metadata-schema-v1"),
@JsonSubTypes.Type(value = PublicMetadataSchemaV1.class, name = "raido-metadata-schema-v1")
})
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-11-21T15:03:48.931461200+10:00[Australia/Brisbane]")
public interface ReadRaidMetadataResponseV1 {
public String getMetadataSchema();
}
并且API服务始终将“类名”Map(即PublicMetadataSchemaV1
)作为值,而不是将已定义的raido-metadata-schema-v1
“Map”值作为值。
但生成的TypeScript代码如下所示:
export function ReadRaidMetadataResponseV1FromJSONTyped(json: any, ignoreDiscriminator: boolean): ReadRaidMetadataResponseV1 {
if ((json === undefined) || (json === null)) {
return json;
}
switch (json['metadataSchema']) {
case 'closed-metadata-schema-v1':
return {...ClosedMetadataSchemaV1FromJSONTyped(json, true), metadataSchema: 'closed-metadata-schema-v1'};
case 'raido-metadata-schema-v1':
return {...PublicMetadataSchemaV1FromJSONTyped(json, true), metadataSchema: 'raido-metadata-schema-v1'};
default:
throw new Error(`No variant of ReadRaidMetadataResponseV1 exists with 'metadataSchema=${json['metadataSchema']}'`);
}
}
因此它总是失败,因为TypeScript代码只知道(正确的)raido-metadata-schema-v1
Map值。
带有完整代码的存储库是公开的,您可以在以下位置找到完整的openapi
YAML文件:https://github.com/au-research/raido-v2/blob/b06c08349a58b4559768963c5e3fbb81cc2c2f28/api-svc/idl-raid-v2/src/shared.yaml#L36
的问题:如何构建我的openapi
定义,或者需要使用哪些标志,以便生成的typescript-fetch
代码能够实际使用JavaSpring
生成器提供的API?
1条答案
按热度按时间r8uurelv1#
这个问题的简单“解决方法”答案**(*)**是,您必须将Map值设定为与Map到的类型名称相同。也就是说:
必须重写为:
(*)-“简单”,但令人讨厌,而且可能很尴尬。如果有人发布的答案允许Map值是任意的,而不是被迫匹配类型名称-我会很高兴地将其标记为正确答案。