使用Micronaut OpenAPI为密封的Kotlin类生成OpenAPI规范的问题



我在使用密封类时遇到问题。我从Micronaut openapi获得了一个规范,但我使用的代码生成器(orval(遇到了循环引用,并失败了。

给定此数据类别:

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type",
visible = true
)
@JsonSubTypes(
JsonSubTypes.Type(name = "lounge", value = AnonymousResponse.Lounge::class),
JsonSubTypes.Type(name = "diningRoom", value = AnonymousResponse.DiningRoom::class)
)
sealed class AnonymousResponse {
abstract val id: Int
@JsonTypeName("lounge")
data class Lounge(
override val id: Int,
val hasTv: Boolean,
) : AnonymousResponse()
@JsonTypeName("diningRoom")
data class DiningRoom(
override val id: Int,
val hasTable: Boolean,
) : AnonymousResponse()
}

Micronaut openapi生成以下组件:

components:
schemas:
AnonymousResponse:
type: object
properties:
id:
type: integer
format: int32
discriminator:
propertyName: type
mapping:
lounge: '#/components/schemas/AnonymousResponse.Lounge'
diningRoom: '#/components/schemas/AnonymousResponse.DiningRoom'
oneOf:
- $ref: '#/components/schemas/AnonymousResponse.Lounge'
- $ref: '#/components/schemas/AnonymousResponse.DiningRoom'
AnonymousResponse.DiningRoom:
allOf:
- $ref: '#/components/schemas/AnonymousResponse'
- required:
- hasTable
- id
type: object
properties:
id:
type: integer
format: int32
hasTable:
type: boolean
AnonymousResponse.Lounge:
allOf:
- $ref: '#/components/schemas/AnonymousResponse'
- required:
- hasTv
- id
type: object
properties:
id:
type: integer
format: int32
hasTv:
type: boolean

这导致orval中出现以下错误:

src/models/anonymousResponseDiningRoom.ts:10:13 - error TS2456: Type alias 'AnonymousResponseDiningRoom' circularly references itself.
10 export type AnonymousResponseDiningRoom = AnonymousResponse & AnonymousResponseDiningRoomAllOf;
~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/models/anonymousResponse.ts:11:13 - error TS2456: Type alias 'AnonymousResponse' circularly references itself.
11 export type AnonymousResponse = AnonymousResponseLounge | AnonymousResponseDiningRoom | AnonymousResponseOneOf;
~~~~~~~~~~~~~~~~~
src/models/anonymousResponseLounge.ts:10:13 - error TS2456: Type alias 'AnonymousResponseLounge' circularly references itself.
10 export type AnonymousResponseLounge = AnonymousResponse & AnonymousResponseLoungeAllOf;
~~~~~~~~~~~~~~~~~~~~~~~

我不完全确定是规范生成器还是代码生成器做错了什么;allOf"-AnonymousResponse引用在我看来很不确定,因为(至少从我的阅读方式来看(它会导致例如Lounge也包含来自DiningRoom的信息?

在尝试在密封类上放置@Schema注释,并研究如何自定义自动生成Schema后,我意识到这很有效:

// No Schema here
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type",
visible = true
)
@JsonSubTypes(
JsonSubTypes.Type(name = "lounge", value = AnonymousResponse.Lounge::class),
JsonSubTypes.Type(name = "diningRoom", value = AnonymousResponse.DiningRoom::class)
)
sealed class AnonymousResponse {
abstract val id: Int
@Schema // Schema here
data class Lounge(
override val id: Int,
val hasTv: Boolean,
) : AnonymousResponse()
@Schema // Schema here
data class DiningRoom(
override val id: Int,
val hasTable: Boolean,
) : AnonymousResponse()
}

最终产生了以下orval代码:

匿名响应.ts

import type { AnonymousResponseLounge } from './anonymousResponseLounge';
import type { AnonymousResponseDiningRoom } from './anonymousResponseDiningRoom';
import type { AnonymousResponseOneOf } from './anonymousResponseOneOf';
export type AnonymousResponse = AnonymousResponseLounge | AnonymousResponseDiningRoom | AnonymousResponseOneOf;

匿名响应Longge.ts

export interface AnonymousResponseLounge {
id: number;
hasTv: boolean;
type?: string;
}

匿名响应DiningRoom.ts

export interface AnonymousResponseLounge {
id: number;
hasTv: boolean;
type?: string;
}

匿名响应OneOf.ts

export type AnonymousResponseOneOf = {
id?: number;
};

虽然它没有鉴别器类型的常数值,但我不认为这是规范的错

最新更新