Skip to content

Commit

Permalink
add support for discriminated union conversion to openapi (#86)
Browse files Browse the repository at this point in the history
* add support for discriminated unions to openapi
* create missing headers
* rename union test operation
* remove incorrect union shape
* fix json tests
* Add discriminator field to alternatives in openapi

Co-authored-by: Olivier Mélois <[email protected]>
  • Loading branch information
lewisjkl and Baccata authored Jan 31, 2022
1 parent c04016a commit 5759f2c
Show file tree
Hide file tree
Showing 9 changed files with 354 additions and 137 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ object SchematicJCodecTests extends SimpleIOSuite {

expect(
result == PayloadData(
None,
Some(TestBiggerUnion.OneCase(One(Some("hello"))))
)
)
Expand Down
83 changes: 83 additions & 0 deletions modules/openapi/src/smithy4s/openapi/DiscriminatedUnion.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2021 Disney Streaming
*
* Licensed under the Tomorrow Open Source Technology License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://disneystreaming.github.io/TOST-1.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package smithy4s.openapi

import _root_.software.amazon.smithy.jsonschema.JsonSchemaConfig
import _root_.software.amazon.smithy.jsonschema.JsonSchemaMapper
import _root_.software.amazon.smithy.jsonschema.Schema.Builder
import _root_.software.amazon.smithy.model.shapes.Shape

import scala.jdk.CollectionConverters._
import software.amazon.smithy.model.node.ObjectNode
import smithy4s.api.DiscriminatedUnionTrait
import software.amazon.smithy.jsonschema.Schema

class DiscriminatedUnions() extends JsonSchemaMapper {
private final val COMPONENTS = "components"

def updateSchema(
shape: Shape,
schemaBuilder: Builder,
config: JsonSchemaConfig
): Builder = {
val maybeDiscriminated = shape.getTrait(classOf[DiscriminatedUnionTrait])
if (maybeDiscriminated.isPresent()) {
val discriminated = maybeDiscriminated.get()
val discriminatorField = discriminated.getValue()
val unionSchema = schemaBuilder.build()

val alternatives = unionSchema.getOneOf().asScala
val discriminatedAlts =
alternatives.flatMap(alt => alt.getProperties().asScala)

val transformedAlts = discriminatedAlts.map { case (label, altSchema) =>
val localDiscriminator = Schema
.builder()
.`type`("string")
.enumValues(List(label).asJava)
.build()
val discObject = Schema
.builder()
.`type`("object")
.properties(
Map(
discriminatorField -> localDiscriminator
).asJava
)
.required(List(discriminatorField).asJava)
.build()
Schema
.builder()
.allOf(
List(altSchema, discObject).asJava
)
.build()
}.asJava

schemaBuilder
.oneOf(transformedAlts)
.putExtension(
"discriminator",
ObjectNode
.builder()
.withMember("propertyName", discriminated.getValue())
.build()
)

} else schemaBuilder
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ final class Smithy4sOpenApiExtension() extends Smithy2OpenApiExtension {
).asJava

override def getJsonSchemaMappers(): ju.List[JsonSchemaMapper] = List(
new OpenApiJsonSchemaMapper(): JsonSchemaMapper
new OpenApiJsonSchemaMapper(): JsonSchemaMapper,
new DiscriminatedUnions()
).asJava

}
Loading

0 comments on commit 5759f2c

Please sign in to comment.