-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support serializing traits into specification extensions in OpenAPI #1609
Support serializing traits into specification extensions in OpenAPI #1609
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Xtansia, thanks for the contribution! This PR adds a lot of new functionality to OpenAPI conversions which is powerful and exciting.
Overall feedback for the changes besides the comments:
- For new files, use the following copyright header:
/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */
- Some classes / methods are missing updated javadoc comments.
- The tests should be expanded to cover:
- Custom extension traits for all applicable shape types, or constrained via selector the shape types used to define custom extension traits.
- Applying these custom extension traits to different parts of the smithy model, e.g. operations, input / output, members of structures and unions, etc.
- This feature and trait should be renamed to "Specification Extensions" rather than "Vendor Extensions" to match the official OpenAPI specification.
The trait also needs a dedicated section in the "Converting Smithy to OpenAPI" guide at docs/source-2.0/guides/converting-to-openapi.rst
similar to other trait definitions (arbitrary example: httpApiKeyAuth
). This would include:
- How to use it in a smithy model,
- Where to get the trait (the new
smithy-openapi-traits
package!), - The expected OpenAPI conversion (similar to the
@examples
trait conversion section), and - What subset of OpenAPI conversions are supported by this trait compared to the OpenAPI Specification (behavior captured in the expanded tests).
For unsupported features, I believe the jsonAdd
configuration setting documented in the "Converting Smithy to OpenAPI" guide should cover most cases.
smithy-openapi-traits/src/main/resources/META-INF/smithy/openapi.smithy
Outdated
Show resolved
Hide resolved
smithy-openapi-traits/src/main/resources/META-INF/smithy/openapi.smithy
Outdated
Show resolved
Hide resolved
smithy-jsonschema/src/test/java/software/amazon/smithy/jsonschema/JsonSchemaConverterTest.java
Outdated
Show resolved
Hide resolved
...openapi-traits/src/main/java/software/amazon/smithy/openapi/traits/VendorExtensionTrait.java
Outdated
Show resolved
Hide resolved
...openapi-traits/src/main/java/software/amazon/smithy/openapi/traits/VendorExtensionTrait.java
Outdated
Show resolved
Hide resolved
...api/src/test/java/software/amazon/smithy/openapi/fromsmithy/OpenApiJsonSchemaMapperTest.java
Show resolved
Hide resolved
...openapi-traits/src/main/java/software/amazon/smithy/openapi/traits/VendorExtensionTrait.java
Outdated
Show resolved
Hide resolved
smithy-jsonschema/src/main/java/software/amazon/smithy/jsonschema/JsonSchemaMapper.java
Outdated
Show resolved
Hide resolved
smithy-jsonschema/src/main/java/software/amazon/smithy/jsonschema/JsonSchemaMapper.java
Outdated
Show resolved
Hide resolved
.../src/main/java/software/amazon/smithy/openapi/fromsmithy/mappers/VendorExtensionsMapper.java
Outdated
Show resolved
Hide resolved
@syall Thank you for the super thorough feedback, I'll get to work addressing those 👍 |
8e63791
to
847fff2
Compare
@syall I've had a first go at fixing all the changes you requested and drafting some documentation, would get your thoughts on anything that needs further improving. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Xtansia, all of my comments are on the documentation section added.
One item I missed from last review is that SpecificationExtensionsMapper
is missing a corresponding SpecificationExtensionsMapperTest
. Besides this, the code changes look good!
@syall Is there something specific you'd want to be covered by a |
@Xtansia Good question. I think moving out the test to The
|
78afd1a
to
344625d
Compare
@syall I've refactored those tests and added cases covering all trait shapes on services, operation, structure and string (as an "inlined" schema). Do you think that's sufficient or would you like coverage of applying the extensions to all simple & aggregate types? |
@Xtansia The current tests are sufficient, I believe that the Simple & Aggregate shapes fall under the same testing category for "inlined" schema. |
The JsonSchemaMapper::updateSchema
breaking change has too much risk, looking into alternatives.
@syall Other possibility I can think of for not breaking current implementations of Add overload with default implementation to interface: public interface JsonSchemaMapper {
default byte getOrder() { return 0; }
default Schema.Builder updateSchema(Shape shape, Schema.Builder schemaBuilder, JsonSchemaConfig config) { return schemaBuilder; }
default Schema.Builder updateSchema(Shape shape, Schema.Builder schemaBuilder, JsonSchemaConfig config, Model model) { return schemaBuilder; }
} And change private Schema buildSchema(Shape shape, Schema.Builder builder) {
JsonSchemaConfig config = converter.getConfig();
for (JsonSchemaMapper mapper : mappers) {
builder = mapper.updateSchema(shape, builder, config);
builder = mapper.updateSchema(shape, builder, config, model);
}
return builder.build();
} Though it's a tad gross in duplication, and I'm not sure if adding a default implementation to the original method def is class compatible with code compiled with the previous interface version. Alternatively could do similar thing but with a new interface (ie. |
@syall Have pushed up an a version of what I suggested, also changed to passing in a "context" object to the new interface to minimise breaking changes in future. |
7c92736
to
8e927d3
Compare
8e927d3
to
22eb49a
Compare
@syall Have you been able to review my alternative approach? |
22eb49a
to
9d8bd81
Compare
f89280a
to
1c437c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the previous approach to use an overloaded JsonSchemaMapper::updateSchema()
that uses the new JsonSchemaMapperContext
.
JsonSchemaMapperContext
is a class that contains all the info needed to update schemas, and is additive by adding fields to the class (e.g. in this PR Model
). This avoids adding overloaded methods with parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed JsonSchemaMapper
tests to class implementation rather than functional interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a breaking change in JsonSchemaMapper
from a functional interface to a normal interface.
Although this is a breaking change, I think this is a reasonable compromise to enable this feature.
Additionally add a JsonSchemaMapperV2 interface rather than breaking original.
1c437c1
to
3635eb0
Compare
…mithy-lang#1609) ## `smithy.openapi#specificationExtension` Adds a meta trait `smithy.openapi#specificationExtension` that can be used to annotate traits to indicate they should be serialized into specification extension (`x-*`) properties when converting to OpenAPI. This is supported on shapes, operations, and services. By default the extension will be named by the shape ID replacing `#` & `.` with `-` prefixed with `x-`, otherwise the extension can be specified using the `as` property. A new package `smithy-openapi-traits` is introduced to contain the `smithy.openapi#specificationExtension` trait. ## `JsonSchemaMapper` and `JsonSchemaShapeVisitor` BREAKING CHANGE: Technically, `JsonSchemaMapper` has a breaking change from a functional interface to a normal interface, but we are anticipating customers are not using `JsonSchemaMapper` as a functional interface since it was not annotated with `@FunctionalInterface`. `JsonSchemaMapper` is updated to use `updateSchema(JsonSchemaMapperContext, Schema.Builder)` in `JsonSchemaShapeVisitor`, which will call the existing `updateSchema(Shape, Schema.Builder, JsonSchemaConfig)` by default when not implemented for backwards compatibility. ## `smithy-openapi` Support is added for `smithy.openapi#specificationExtension` by implementing `SpecificationExtensionsMapper` for operations and services and updating `OpenApiJsonSchemaMapper` for shapes. --------- Co-authored-by: Steven Yuan <[email protected]>
Description of changes
Adds a "meta-trait"
smithy.openapi#specificationExtension
that can be used to annotate other traits to indicate they should be serialized into specification extension (x-*
) properties when converting to OpenAPI. This is supported on both shapes/"schemas" as well as operations. By default the extension will be named by the shape ID replacing#
&.
with-
prefixed withx-
, otherwise there is anas:
member on the trait that allows renaming.I believe this could be useful in bridging the gap where custom traits are currently unsupported in OpenAPI conversion, by allowing some opt in.
Adds a
JsonSchemaMapperV2
interface that extends the original, and adds an overload ofupdateSchema
that accepts a context object that includes the model being converted.Example
Some operation:
Becomes:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.