Java & Kotlin - type mapping support in the asyncapi cli
Why do we need this improvement?
As Kotlin user, would appreciate to have the data mapping support so that I could map type such as Double -> BigDecimal to avoid possible side-effects. Double -> BigDecimal is the only issue with type mapping we had, but considering other users might have different use cases, I am creating the ticket for general type mapping.
How will this change help?
It will help Java & Kotlin users to have type mapping so they don't need to use default mapping of types.
Screenshots
No response
How could it be implemented/designed?
Having another flag in the asyncapi generate model to support type mapping, something like --kotlinTypeMapping
🚧 Breaking changes
No
👀 Have you checked for similar open issues?
- [x] I checked and didn't find a similar issue
🏢 Have you read the Contributing Guidelines?
- [x] I have read the Contributing Guidelines
Are you willing to work on this issue?
None
Candidate to be moved to modelina.
Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our contributors guide and the instructions about a basic recommended setup useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.
hi @Shurtu-gal @derberg
Thanks for opening this issue! We've been discussing the design for type mapping support in Java/Kotlin and wanted to share our proposal for feedback.
Proposed Implementation
We're thinking of a two-level approach with global and field-level type mappings:
1. Global Type Mappings
Define default type mappings at the document level that apply to all fields:
asyncapi: "2.2.0"
info:
title: Account Service
version: 1.0.0
# Global mappings - applies to ALL fields of these types
typeMappings:
number: BigDecimal
integer: Long
string: String
2. Field-Level Overrides
Override the global mapping for specific fields using the x-type extension:
components:
messages:
UserSignedUp:
payload:
type: object
properties:
amount:
type: number
# Uses global mapping: BigDecimal ✓
percentage:
type: number
x-type: Double
# Override: This specific field uses Double instead
description: Percentage where precision loss is acceptable
accountId:
type: integer
# Uses global mapping: Long ✓
Design Rationale
Why two levels?
-
Global mappings: Cover the common case where you want all
numbertypes to beBigDecimal -
Field-level overrides: Allow exceptions where specific fields need different types (e.g., percentages can use
Double)
Why x-type for field-level?
- Follows AsyncAPI extension conventions (
x-prefix) - Clear and unambiguous - one type per field
- Consistent with similar tools like OpenAPI Generator
- Avoids confusing nested structures
Precedence Order:
Field-level (x-type) > Global (typeMappings) > Default generator mapping
CLI Support
We also propose supporting type mappings via CLI for quick overrides:
asyncapi generate models kotlin asyncapi.yaml \
--type-mapping number=BigDecimal \
--type-mapping integer=Long
CLI mappings would override the global typeMappings in the spec file.
Simple Type Names vs Fully Qualified
Support both simple and fully qualified names:
typeMappings:
# Simple names (generator adds imports automatically)
number: BigDecimal
integer: Long
# Fully qualified (when needed for custom/ambiguous types)
timestamp: java.time.Instant
customType: com.mycompany.Money
Complete Example
asyncapi: "2.2.0"
info:
title: Account Service
version: 1.0.0
typeMappings:
number: BigDecimal # All numbers → BigDecimal by default
integer: Long
channels:
user/signedup:
subscribe:
message:
$ref: "#/components/messages/UserSignedUp"
components:
messages:
UserSignedUp:
payload:
type: object
properties:
displayName:
type: string
email:
type: string
format: email
amount:
type: number
description: Uses BigDecimal (global mapping)
taxRate:
type: number
x-type: Double
description: Override to Double - precision loss acceptable
accountId:
type: integer
description: Uses Long (global mapping)
Questions
- Does this approach align with AsyncAPI CLI's architecture and conventions?
- Is
x-typean appropriate extension name, or would you prefer something likex-java-type/x-kotlin-typeto be language-specific? - Should the global
typeMappingsbe at the root level, or nested under a generator-specific configuration? - Are there any concerns about this design conflicting with existing or planned features?
We're happy to contribute a PR once we align on the design. Thanks for considering this!