Skip to content

Commit

Permalink
Add support for type string with format binary (#231)
Browse files Browse the repository at this point in the history
* Rename byte specialization to Base64String

see https://swagger.io/docs/specification/data-models/data-types/#format

* Add support for string with format binary

* Improve non-object parameter naming
  • Loading branch information
ascheja authored Sep 1, 2023
1 parent e485ba5 commit e589ae6
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/main/kotlin/com/cjbooms/fabrikt/model/KotlinTypeInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ sealed class KotlinTypeInfo(val modelKClass: KClass<*>, val generatedModelClassN
Enum(schema.getEnumValues(), schema.toModelClassName(enclosingName.toModelClassName()))
OasType.Uuid -> Uuid
OasType.Uri -> Uri
OasType.ByteArray -> ByteArray
OasType.Base64String -> ByteArray
OasType.Binary -> ByteArray
OasType.Double -> Double
OasType.Float -> Float
OasType.Number -> Numeric
Expand Down
7 changes: 5 additions & 2 deletions src/main/kotlin/com/cjbooms/fabrikt/model/OasType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ sealed class OasType(
object Enum : OasType("string", specialization = Specialization.ENUM)
object Uuid : OasType("string", specialization = Specialization.UUID)
object Uri : OasType("string", specialization = Specialization.URI)
object ByteArray : OasType("string", specialization = Specialization.BYTE)
object Base64String : OasType("string", specialization = Specialization.BYTE)
object Binary : OasType("string", specialization = Specialization.BINARY)
object Map : OasType("object", specialization = Specialization.MAP)
object UnknownAdditionalProperties :
OasType("object", specialization = Specialization.UNKNOWN_ADDITIONAL_PROPERTIES)
Expand Down Expand Up @@ -77,6 +78,7 @@ sealed class OasType(
isStringDefinitionWithFormat("uuid") -> Specialization.UUID
isStringDefinitionWithFormat("uri") -> Specialization.URI
isStringDefinitionWithFormat("byte") -> Specialization.BYTE
isStringDefinitionWithFormat("binary") -> Specialization.BINARY
isEnumDefinition() -> Specialization.ENUM
isMapTypeAdditionalProperties(oasKey) -> Specialization.TYPED_MAP_ADDITIONAL_PROPERTIES
isSimpleMapDefinition() -> Specialization.MAP
Expand All @@ -101,6 +103,7 @@ sealed class OasType(
URI,
NONE,
ONE_OF_ANY,
BYTE
BYTE,
BINARY
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ object KaizenParserExtensions {
.filterNot { invalidNames.contains(it) }
.filter { it.toIntOrNull() == null } // Ignore numeric-identifiers path-parts in: allOf / oneOf / anyOf
.last()
.replace("~1", "-") // so application~1octet-stream becomes application-octet-stream
}

fun Schema.safeType(): String? =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,13 @@ class MicronautControllerGeneratorTest {
}
return Linter.lintString(singleFileBuilder.build().toString())
}

@Test
fun `ensure generates ByteArray body parameter and response for string with format binary`() {
val api = SourceApi(readTextResource("/examples/binary/api.yaml"))
val controllers = MicronautControllerInterfaceGenerator(Packages(basePackage), api, JavaxValidationAnnotations).generate().toSingleFile()
val expectedControllers = readTextResource("/examples/binary/controllers/micronaut/Controllers.kt")

assertThat(controllers.trim()).isEqualTo(expectedControllers.trim())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -224,4 +224,13 @@ class SpringControllerGeneratorTest {

assertThat(controllers.trim()).isEqualTo(expectedControllers.trim())
}

@Test
fun `ensure generates ByteArray body parameter and response for string with format binary`() {
val api = SourceApi(readTextResource("/examples/binary/api.yaml"))
val controllers = SpringControllerInterfaceGenerator(Packages(basePackage), api, JavaxValidationAnnotations).generate().toSingleFile()
val expectedControllers = readTextResource("/examples/binary/controllers/spring/Controllers.kt")

assertThat(controllers.trim()).isEqualTo(expectedControllers.trim())
}
}
24 changes: 24 additions & 0 deletions src/test/resources/examples/binary/api.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
openapi: 3.0.1
info:
description: Testing binary body and binary response
title: Test
version: '0.0'
paths:
/binary-data:
post:
operationId: postBinaryData
requestBody:
required: true
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
200:
description: Success
content:
application/octet-stream:
schema:
type: string
format: binary
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package ie.zalando.controllers

import io.micronaut.http.HttpResponse
import io.micronaut.http.annotation.Body
import io.micronaut.http.annotation.Consumes
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Post
import io.micronaut.http.annotation.Produces
import javax.validation.Valid
import kotlin.ByteArray

@Controller
interface BinaryDataController {
/**
*
*
* @param applicationOctetStream
*/
@Post(uri = "/binary-data")
@Consumes(value = ["application/octet-stream"])
@Produces(value = ["application/octet-stream"])
fun postBinaryData(
@Body @Valid
applicationOctetStream: ByteArray
): HttpResponse<ByteArray>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package ie.zalando.controllers

import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Controller
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import javax.validation.Valid
import kotlin.ByteArray

@Controller
@Validated
@RequestMapping("")
interface BinaryDataController {
/**
*
*
* @param applicationOctetStream
*/
@RequestMapping(
value = ["/binary-data"],
produces = ["application/octet-stream"],
method = [RequestMethod.POST],
consumes = ["application/octet-stream"]
)
fun postBinaryData(
@RequestBody @Valid
applicationOctetStream: ByteArray
):
ResponseEntity<ByteArray>
}

0 comments on commit e589ae6

Please sign in to comment.