OpenAPI Version Support
BerryCrush supports multiple OpenAPI specification versions through a flexible abstraction layer, enabling forward compatibility with future versions.
Supported Versions
Version |
Status |
Key Features |
|---|---|---|
2.x (Swagger) |
Planned |
Legacy API support |
3.0.x |
✅ Supported |
Components, callbacks, links |
3.1.x |
✅ Supported |
Webhooks, JSON Schema 2020-12 |
3.2.x |
Future |
Automatic version detection ready |
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ OpenAPI Abstraction │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ OpenApiSpec │◄─────│ OpenApiParser │◄─────│ YAML/JSON │ │
│ │ (interface) │ │ (interface) │ │ File │ │
│ └──────┬───────┘ └───────────────┘ └──────────────┘ │
│ │ │
│ │ Provides unified access │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ SpecRegistry │ │ Operation- │ │ HttpRequest │ │
│ │ │ │ Resolver │ │ Builder │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Key Interfaces
OpenApiVersion
Enumeration of supported version categories:
enum class OpenApiVersion {
V2_X, // Swagger 2.0
V3_0_X, // OpenAPI 3.0.x
V3_1_X, // OpenAPI 3.1.x
V3_2_X, // OpenAPI 3.2.x (future)
UNKNOWN
}
Version detection is automatic:
val version = OpenApiVersion.detect("3.1.0") // Returns V3_1_X
OpenApiSpec
Unified interface for accessing OpenAPI specification content:
interface OpenApiSpec {
val version: OpenApiVersion // Detected version
val specVersion: String // Raw version string ("3.1.0")
val info: SpecInfo // Title, description, version
val servers: List<ServerInfo> // Server URLs
val paths: Map<String, PathSpec> // API endpoints
val components: ComponentsSpec? // Reusable components
val webhooks: Map<String, PathSpec> // 3.1+ webhooks
fun getOperation(operationId: String): OperationSpec?
fun getAllOperations(): List<OperationSpec>
val rawModel: Any // Access underlying parser model
}
OpenApiParser
Parser interface for loading specifications:
interface OpenApiParser {
fun parse(path: Path): OpenApiSpec
fun parse(path: String): OpenApiSpec
fun parseContent(content: String): OpenApiSpec
fun supportedVersions(): Set<OpenApiVersion>
}
Feature Detection
BerryCrush uses feature detection over version checking for maximum compatibility:
// ✅ Recommended: Check for feature presence
if (spec.hasWebhooks()) {
spec.webhooks.forEach { (name, pathSpec) ->
// Handle webhook
}
}
// ❌ Avoid: Checking version numbers
if (spec.version >= OpenApiVersion.V3_1_X) { // Not recommended
// ...
}
This approach ensures forward compatibility with unknown future versions.
OpenAPI 3.1.x Features
Webhooks
Webhooks are callback URLs that an API provider calls to deliver events:
# In OpenAPI 3.1.x spec
webhooks:
newBooking:
post:
summary: New booking notification
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Booking'
Access in BerryCrush:
spec.webhooks["newBooking"]?.operations?.get(HttpMethod.POST)
JSON Schema 2020-12
OpenAPI 3.1.x uses JSON Schema Draft 2020-12 with new keywords:
Keyword |
3.0.x |
3.1.x |
|---|---|---|
|
|
|
|
Boolean |
Number |
|
Boolean |
Number |
|
N/A |
Supported |
|
N/A |
Supported |
BerryCrush’s SchemaSpec interface handles these differences transparently.
Implementation Details
SwaggerParserAdapter
The default implementation uses io.swagger.parser.v3:swagger-parser:
// Internal implementation
internal class SwaggerParserAdapter : OpenApiParser {
override fun parse(path: Path): OpenApiSpec {
val result = OpenAPIParser().readLocation(path.toString(), null, null)
return SwaggerOpenApiSpec(result.openAPI)
}
}
SpecRegistry Integration
SpecRegistry stores parsed specs and provides operation resolution:
data class LoadedSpec(
val name: String,
val spec: OpenApiSpec, // Uses abstraction
val baseUrl: String,
)
Best Practices
Use
OpenApiSpecInterfaceDon’t access
rawModelunless absolutely necessaryThe abstraction handles version differences
Check Features, Not Versions
Use
hasWebhooks(),hasComponents()methodsDon’t hardcode version checks
Handle Missing Features Gracefully
Webhooks return empty map for 3.0.x specs
Code should work regardless of spec version
Test with Multiple Versions
Test fixtures include both 3.0.x and 3.1.x specs
Ensure scenarios work across versions
Test Fixtures
Real-world OpenAPI 3.1.x specs for testing:
File |
Source |
Features |
|---|---|---|
|
Local |
OpenAPI 3.0.3 baseline |
|
ReadMe.io |
3.1.0, webhooks, OAuth2 |
|
OAI Official |
3.1.0, webhooks, callbacks |
Located in core/src/test/resources/.