Skip to content

Commit 8b37b59

Browse files
authored
Add minimumCompressionSize trait and OpenAPI mapper
Add the aws.apigateway#minimumCompressionSize integer trait with @range(min: 0, max: 10485760) validation. The OpenAPI mapper converts it to the x-amazon-apigateway-minimum-compression-size extension for REST APIs.
1 parent 0e4cbd7 commit 8b37b59

11 files changed

Lines changed: 298 additions & 0 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "feature",
3+
"description": "Added `aws.apigateway#minimumCompressionSize` trait and OpenAPI mapper",
4+
"pull_requests": [
5+
"[#3076](https://github.com/smithy-lang/smithy/pull/3076)"
6+
]
7+
}

docs/source-2.0/aws/amazon-apigateway.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,41 @@ Value type
240240
customers.
241241

242242

243+
.. smithy-trait:: aws.apigateway#minimumCompressionSize
244+
.. _aws.apigateway#minimumCompressionSize-trait:
245+
246+
-----------------------------------------------
247+
``aws.apigateway#minimumCompressionSize`` trait
248+
-----------------------------------------------
249+
250+
Summary
251+
Defines the minimum payload size in bytes at which compression is applied
252+
on an API Gateway REST API.
253+
Trait selector
254+
``service``
255+
Value type
256+
``integer`` value between 0 and 10485760 (10MB).
257+
See also
258+
- `Payload compression for REST APIs`_ for more information
259+
- `x-amazon-apigateway-minimum-compression-size`_ for how this relates
260+
to OpenAPI
261+
262+
The following example sets the minimum compression size to 10240 bytes:
263+
264+
.. code-block:: smithy
265+
266+
$version: "2"
267+
268+
namespace smithy.example
269+
270+
use aws.apigateway#minimumCompressionSize
271+
272+
@minimumCompressionSize(10240)
273+
service Weather {
274+
version: "2018-03-17"
275+
}
276+
277+
243278
.. smithy-trait:: aws.apigateway#requestValidator
244279
.. _aws.apigateway#requestValidator-trait:
245280

@@ -891,3 +926,5 @@ integration response to two ``header`` parameters of the method response.
891926
.. _IntegrationResponse: https://docs.aws.amazon.com/apigateway/api-reference/resource/integration-response/
892927
.. _mapping templates: https://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html#models-mappings-mappings
893928
.. _Lambda Authorizers Payload Format: https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-lambda-authorizer.html#http-api-lambda-authorizer.payload-format
929+
.. _Payload compression for REST APIs: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-gzip-compression-decompression.html
930+
.. _x-amazon-apigateway-minimum-compression-size: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-openapi-minimum-compression-size.html

docs/source-2.0/guides/model-translations/converting-to-openapi.rst

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,49 @@ collecting all of the :ref:`mediaType-trait` values for all members marked
18091809
with :ref:`httppayload-trait`.
18101810

18111811

1812+
.. _apigateway-minimum-compression-size:
1813+
1814+
Minimum compression size
1815+
========================
1816+
1817+
The minimum payload size in bytes at which compression is applied on an
1818+
API Gateway REST API can be set using the
1819+
:ref:`aws.apigateway#minimumCompressionSize-trait`. The value must be
1820+
between 0 and 10485760 bytes (10 MB), inclusive. Smithy will add the
1821+
value of the trait to the generated OpenAPI document as the top-level
1822+
`x-amazon-apigateway-minimum-compression-size`_ extension.
1823+
1824+
The following Smithy model enables compression on payloads of 1024 bytes
1825+
or larger:
1826+
1827+
.. code-block:: smithy
1828+
1829+
$version: "2"
1830+
namespace smithy.example
1831+
1832+
use aws.apigateway#minimumCompressionSize
1833+
use aws.protocols#restJson1
1834+
1835+
@restJson1
1836+
@minimumCompressionSize(1024)
1837+
service Example {
1838+
version: "2019-06-17"
1839+
}
1840+
1841+
is converted to the following OpenAPI model:
1842+
1843+
.. code-block:: json
1844+
1845+
{
1846+
"openapi": "3.0.2",
1847+
"info": {
1848+
"title": "Example",
1849+
"version": "2019-06-17"
1850+
},
1851+
"x-amazon-apigateway-minimum-compression-size": 1024
1852+
}
1853+
1854+
18121855
.. _apigateway-request-validators:
18131856

18141857
Request validators
@@ -2276,6 +2319,7 @@ The conversion process is highly extensible through
22762319
.. _service providers: https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html
22772320
.. _Smithy Gradle plugin: https://github.com/smithy-lang/smithy-gradle-plugin
22782321
.. _x-amazon-apigateway-binary-media-types: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-binary-media-types.html
2322+
.. _x-amazon-apigateway-minimum-compression-size: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-openapi-minimum-compression-size.html
22792323
.. _x-amazon-apigateway-request-validators: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-request-validators.html
22802324
.. _x-amazon-apigateway-request-validator: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-request-validator.html
22812325
.. _intrinsic functions: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package software.amazon.smithy.aws.apigateway.openapi;
6+
7+
import java.util.List;
8+
import java.util.logging.Logger;
9+
import software.amazon.smithy.aws.apigateway.traits.MinimumCompressionSizeTrait;
10+
import software.amazon.smithy.model.traits.Trait;
11+
import software.amazon.smithy.openapi.fromsmithy.Context;
12+
import software.amazon.smithy.openapi.model.OpenApi;
13+
import software.amazon.smithy.utils.ListUtils;
14+
15+
/**
16+
* Adds the API Gateway x-amazon-apigateway-minimum-compression-size extension
17+
* to the OpenAPI model when the {@link MinimumCompressionSizeTrait} is applied
18+
* to a service.
19+
*
20+
* @see <a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-openapi-minimum-compression-size.html">Minimum compression size</a>
21+
*/
22+
final class AddMinimumCompressionSize implements ApiGatewayMapper {
23+
24+
private static final String EXTENSION_NAME = "x-amazon-apigateway-minimum-compression-size";
25+
private static final Logger LOGGER = Logger.getLogger(AddMinimumCompressionSize.class.getName());
26+
27+
@Override
28+
public List<ApiGatewayConfig.ApiType> getApiTypes() {
29+
return ListUtils.of(ApiGatewayConfig.ApiType.REST);
30+
}
31+
32+
@Override
33+
public OpenApi after(Context<? extends Trait> context, OpenApi openApi) {
34+
return context.getService()
35+
.getTrait(MinimumCompressionSizeTrait.class)
36+
.map(trait -> {
37+
LOGGER.fine(() -> String.format(
38+
"Adding %s to %s",
39+
EXTENSION_NAME,
40+
context.getService().getId()));
41+
return openApi.toBuilder()
42+
.putExtension(EXTENSION_NAME, trait.getValue())
43+
.build();
44+
})
45+
.orElse(openApi);
46+
}
47+
}

smithy-aws-apigateway-openapi/src/main/java/software/amazon/smithy/aws/apigateway/openapi/ApiGatewayExtension.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public List<OpenApiMapper> getOpenApiMappers() {
2121
ApiGatewayMapper.wrap(new AddAuthorizers()),
2222
ApiGatewayMapper.wrap(new AddBinaryTypes()),
2323
ApiGatewayMapper.wrap(new AddIntegrations()),
24+
ApiGatewayMapper.wrap(new AddMinimumCompressionSize()),
2425

2526
// CORS For REST APIs
2627
ApiGatewayMapper.wrap(new AddCorsToRestIntegrations()),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package software.amazon.smithy.aws.apigateway.openapi;
6+
7+
import static org.hamcrest.MatcherAssert.assertThat;
8+
import static org.hamcrest.Matchers.equalTo;
9+
import static org.junit.jupiter.api.Assertions.assertTrue;
10+
11+
import org.junit.jupiter.api.Test;
12+
import software.amazon.smithy.model.Model;
13+
import software.amazon.smithy.model.shapes.ShapeId;
14+
import software.amazon.smithy.openapi.OpenApiConfig;
15+
import software.amazon.smithy.openapi.fromsmithy.OpenApiConverter;
16+
import software.amazon.smithy.openapi.model.OpenApi;
17+
18+
public class AddMinimumCompressionSizeTest {
19+
@Test
20+
public void addsMinimumCompressionSize() {
21+
Model model = Model.assembler()
22+
.discoverModels(getClass().getClassLoader())
23+
.addImport(getClass().getResource("minimum-compression-size.smithy"))
24+
.assemble()
25+
.unwrap();
26+
OpenApiConfig config = new OpenApiConfig();
27+
config.setService(ShapeId.from("smithy.example#Service"));
28+
OpenApi result = OpenApiConverter.create()
29+
.config(config)
30+
.classLoader(getClass().getClassLoader())
31+
.convert(model);
32+
33+
assertTrue(result.getExtension("x-amazon-apigateway-minimum-compression-size").isPresent());
34+
int size = result.getExtension("x-amazon-apigateway-minimum-compression-size")
35+
.get()
36+
.expectNumberNode()
37+
.getValue()
38+
.intValue();
39+
assertThat(size, equalTo(10240));
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
$version: "2.0"
2+
3+
namespace smithy.example
4+
5+
use aws.apigateway#minimumCompressionSize
6+
use aws.protocols#restJson1
7+
8+
@restJson1
9+
@minimumCompressionSize(10240)
10+
service Service {
11+
version: "2006-03-01"
12+
operations: [Operation1]
13+
}
14+
15+
@http(uri: "/1", method: "GET")
16+
operation Operation1 {}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package software.amazon.smithy.aws.apigateway.traits;
6+
7+
import software.amazon.smithy.model.FromSourceLocation;
8+
import software.amazon.smithy.model.SourceLocation;
9+
import software.amazon.smithy.model.node.Node;
10+
import software.amazon.smithy.model.node.NumberNode;
11+
import software.amazon.smithy.model.shapes.ShapeId;
12+
import software.amazon.smithy.model.traits.AbstractTrait;
13+
import software.amazon.smithy.model.traits.Trait;
14+
15+
/**
16+
* Defines the minimum payload size in bytes at which compression is applied on an API Gateway REST API.
17+
*/
18+
public final class MinimumCompressionSizeTrait extends AbstractTrait {
19+
public static final ShapeId ID = ShapeId.from("aws.apigateway#minimumCompressionSize");
20+
21+
private final int value;
22+
23+
public MinimumCompressionSizeTrait(int value, FromSourceLocation sourceLocation) {
24+
super(ID, sourceLocation);
25+
this.value = value;
26+
}
27+
28+
public MinimumCompressionSizeTrait(int value) {
29+
this(value, SourceLocation.NONE);
30+
}
31+
32+
/**
33+
* Gets the minimum compression size value.
34+
*
35+
* @return Returns the minimum compression size in bytes.
36+
*/
37+
public int getValue() {
38+
return value;
39+
}
40+
41+
@Override
42+
protected Node createNode() {
43+
return new NumberNode(value, getSourceLocation());
44+
}
45+
46+
public static final class Provider extends AbstractTrait.Provider {
47+
public Provider() {
48+
super(ID);
49+
}
50+
51+
@Override
52+
public Trait createTrait(ShapeId target, Node value) {
53+
return new MinimumCompressionSizeTrait(
54+
value.expectNumberNode().getValue().intValue(),
55+
value.getSourceLocation());
56+
}
57+
}
58+
}

smithy-aws-apigateway-traits/src/main/resources/META-INF/services/software.amazon.smithy.model.traits.TraitService

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ software.amazon.smithy.aws.apigateway.traits.RequestValidatorTrait$Provider
44
software.amazon.smithy.aws.apigateway.traits.ApiKeySourceTrait$Provider
55
software.amazon.smithy.aws.apigateway.traits.IntegrationTrait$Provider
66
software.amazon.smithy.aws.apigateway.traits.MockIntegrationTrait$Provider
7+
software.amazon.smithy.aws.apigateway.traits.MinimumCompressionSizeTrait$Provider

smithy-aws-apigateway-traits/src/main/resources/META-INF/smithy/aws.apigateway.smithy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ structure mockIntegration {
136136
@trait(selector: ":test(service, operation)")
137137
string requestValidator
138138

139+
/// Defines the minimum payload size in bytes at which compression is applied on an API Gateway REST API.
140+
/// Value must be between 0 and 10485760 (10MB).
141+
@internal
142+
@tags(["internal"])
143+
@trait(selector: "service")
144+
@range(min: 0, max: 10485760)
145+
integer minimumCompressionSize
146+
139147
/// An object that associates an authorizer and associated metadata with an
140148
/// authentication mechanism.
141149
@private

0 commit comments

Comments
 (0)