diff --git a/.github/workflows/samples.yml b/.github/workflows/samples.yml
index cdf923ea..960055ad 100644
--- a/.github/workflows/samples.yml
+++ b/.github/workflows/samples.yml
@@ -7,18 +7,16 @@ on:
push:
branches: [ main ]
paths:
- - 'samples/kinesis-firehose-event-handler/**'
+ - 'samples/**'
pull_request:
branches: [ '*' ]
paths:
- - 'samples/kinesis-firehose-event-handler/**'
+ - 'samples/**'
- '.github/workflows/samples.yml'
jobs:
- build:
-
+ build-kinesis-sample:
runs-on: ubuntu-latest
-
steps:
- uses: actions/checkout@v4
- name: Set up JDK 1.8
@@ -37,3 +35,26 @@ jobs:
# Install samples
- name: Install Kinesis Firehose Sample with Maven
run: mvn -B install --file samples/kinesis-firehose-event-handler/pom.xml
+
+ custom-serialization:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
+ with:
+ java-version: 21
+ distribution: corretto
+ # Build custom-serialization samples
+ - name: install sam
+ uses: aws-actions/setup-sam@v2
+ - name: test fastJson
+ run: cd samples/custom-serialization/fastJson && sam build && sam local invoke -e events/event.json | grep 200
+ - name: test gson
+ run: cd samples/custom-serialization/gson && sam build && sam local invoke -e events/event.json | grep 200
+ - name: test jackson-jr
+ run: cd samples/custom-serialization/jackson-jr && sam build && sam local invoke -e events/event.json | grep 200
+ - name: test moshi
+ run: cd samples/custom-serialization/moshi && sam build && sam local invoke -e events/event.json | grep 200
+ - name: test request-stream-handler
+ run: cd samples/custom-serialization/request-stream-handler && sam build && sam local invoke -e events/event.json | grep 200
+
diff --git a/samples/custom-serialization/.gitignore b/samples/custom-serialization/.gitignore
new file mode 100644
index 00000000..2b448259
--- /dev/null
+++ b/samples/custom-serialization/.gitignore
@@ -0,0 +1,7 @@
+**/target/
+**/HelloWorld.iml
+**/samconfig.toml
+**/dependency-reduced-pom.xml
+**/.aws-sam
+**/.gradle
+**/bin
diff --git a/samples/custom-serialization/README.md b/samples/custom-serialization/README.md
new file mode 100644
index 00000000..d9e75147
--- /dev/null
+++ b/samples/custom-serialization/README.md
@@ -0,0 +1,5 @@
+The Lambda Java managed runtimes support custom serialization for JSON events.
+https://docs.aws.amazon.com/lambda/latest/dg/java-custom-serialization.html
+
+## Sample projects
+In this repository you will find a number of sample projects from AWS to help you get started with the custom serialization feature.
diff --git a/samples/custom-serialization/fastJson/HelloWorldFunction/pom.xml b/samples/custom-serialization/fastJson/HelloWorldFunction/pom.xml
new file mode 100644
index 00000000..fde6b625
--- /dev/null
+++ b/samples/custom-serialization/fastJson/HelloWorldFunction/pom.xml
@@ -0,0 +1,52 @@
+
+ 4.0.0
+ helloworld
+ HelloWorld
+ 1.0
+ jar
+ A sample Hello World created for SAM CLI.
+
+ 21
+ 21
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-core
+ 1.2.3
+
+
+ com.amazonaws
+ aws-lambda-java-events
+ 3.14.0
+
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.33
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
diff --git a/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/FastJsonSerializer.java b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/FastJsonSerializer.java
new file mode 100644
index 00000000..44709e76
--- /dev/null
+++ b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/FastJsonSerializer.java
@@ -0,0 +1,50 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package com.example.vehicles.serialization;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONException;
+import com.amazonaws.services.lambda.runtime.CustomPojoSerializer;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Type;
+
+public class FastJsonSerializer implements CustomPojoSerializer {
+ /**
+ * ServiceLoader class requires that the single exposed provider type has a default constructor
+ * to easily instantiate the service providers that it finds
+ */
+ public FastJsonSerializer() {
+ }
+
+ @Override
+ public T fromJson(InputStream input, Type type) {
+ try {
+ return JSON.parseObject(input, type);
+ } catch (JSONException e) {
+ throw (e);
+ }
+ }
+
+ @Override
+ public T fromJson(String input, Type type) {
+ try {
+ return JSON.parseObject(input, type);
+ } catch (JSONException e) {
+ throw (e);
+ }
+ }
+
+ @Override
+ public void toJson(T value, OutputStream output, Type type) {
+ try {
+ JSON.writeTo(output, value);
+ } catch (JSONException e) {
+ throw (e);
+ }
+ }
+
+}
diff --git a/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/helloworld/App.java b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/helloworld/App.java
new file mode 100644
index 00000000..02ba6048
--- /dev/null
+++ b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/helloworld/App.java
@@ -0,0 +1,23 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+
+/**
+ * Handler for requests to Lambda function.
+ */
+public class App implements RequestHandler {
+
+ public APIGatewayProxyResponseEvent handleRequest(Vehicle vehicle, Context context) {
+ System.out.println("input: " + vehicle);
+
+ return new APIGatewayProxyResponseEvent().withStatusCode(200);
+ }
+
+}
diff --git a/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/helloworld/Vehicle.java b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
new file mode 100644
index 00000000..2d34ee6e
--- /dev/null
+++ b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
@@ -0,0 +1,49 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.alibaba.fastjson2.annotation.JSONField;
+
+public class Vehicle {
+
+ @JSONField(name = "vehicle-type")
+ private String vehicleType;
+
+ @JSONField(name = "vehicleID")
+ private String vehicleId;
+
+ public Vehicle() {
+ }
+
+ public Vehicle(String vehicleType, String vehicleId) {
+ this.vehicleType = vehicleType;
+ this.vehicleId = vehicleId;
+ }
+
+ public String getVehicleType() {
+ return vehicleType;
+ }
+
+ public void setVehicleType(String vehicleType) {
+ this.vehicleType = vehicleType;
+ }
+
+ public String getVehicleId() {
+ return vehicleId;
+ }
+
+ public void setVehicleId(String vehicleId) {
+ this.vehicleId = vehicleId;
+ }
+
+ @Override
+ public String toString() {
+ return "Vehicle{" +
+ "vehicleType='" + vehicleType + '\'' +
+ ", vehicleId='" + vehicleId + '\'' +
+ '}';
+ }
+}
diff --git a/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
new file mode 100644
index 00000000..58c85a7a
--- /dev/null
+++ b/samples/custom-serialization/fastJson/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
@@ -0,0 +1 @@
+com.example.vehicles.serialization.FastJsonSerializer
\ No newline at end of file
diff --git a/samples/custom-serialization/fastJson/README.md b/samples/custom-serialization/fastJson/README.md
new file mode 100644
index 00000000..3f6a2f3a
--- /dev/null
+++ b/samples/custom-serialization/fastJson/README.md
@@ -0,0 +1,7 @@
+Build and test commands
+
+```bash
+sam build
+sam local invoke -e events/event.json
+```
+
diff --git a/samples/custom-serialization/fastJson/events/event.json b/samples/custom-serialization/fastJson/events/event.json
new file mode 100644
index 00000000..5d882dba
--- /dev/null
+++ b/samples/custom-serialization/fastJson/events/event.json
@@ -0,0 +1,4 @@
+{
+ "vehicle-type": "car",
+ "vehicleID": 123
+}
\ No newline at end of file
diff --git a/samples/custom-serialization/fastJson/template.yaml b/samples/custom-serialization/fastJson/template.yaml
new file mode 100644
index 00000000..016239cf
--- /dev/null
+++ b/samples/custom-serialization/fastJson/template.yaml
@@ -0,0 +1,43 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+Description: >
+ fastJson
+
+ Sample SAM Template for fastJson
+
+# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
+Globals:
+ Function:
+ Timeout: 20
+ MemorySize: 512
+
+Resources:
+ HelloWorldFunction:
+ Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
+ Properties:
+ CodeUri: HelloWorldFunction
+ Handler: helloworld.App::handleRequest
+ Runtime: java21
+ Architectures:
+ - x86_64
+ MemorySize: 512
+ Events:
+ HelloWorld:
+ Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
+ Properties:
+ Path: /hello
+ Method: get
+
+Outputs:
+ # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
+ # Find out more about other implicit resources you can reference within SAM
+ # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
+ HelloWorldApi:
+ Description: "API Gateway endpoint URL for Prod stage for Hello World function"
+ Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
+ HelloWorldFunction:
+ Description: "Hello World Lambda Function ARN"
+ Value: !GetAtt HelloWorldFunction.Arn
+ HelloWorldFunctionIamRole:
+ Description: "Implicit IAM Role created for Hello World function"
+ Value: !GetAtt HelloWorldFunctionRole.Arn
diff --git a/samples/custom-serialization/gson/HelloWorldFunction/pom.xml b/samples/custom-serialization/gson/HelloWorldFunction/pom.xml
new file mode 100644
index 00000000..56327d99
--- /dev/null
+++ b/samples/custom-serialization/gson/HelloWorldFunction/pom.xml
@@ -0,0 +1,51 @@
+
+ 4.0.0
+ helloworld
+ HelloWorld
+ 1.0
+ jar
+ A sample Hello World created for SAM CLI.
+
+ 21
+ 21
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-core
+ 1.2.3
+
+
+ com.amazonaws
+ aws-lambda-java-events
+ 3.14.0
+
+
+ com.google.code.gson
+ gson
+ 2.11.0
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
diff --git a/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/GsonSerializer.java b/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/GsonSerializer.java
new file mode 100644
index 00000000..5d259765
--- /dev/null
+++ b/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/GsonSerializer.java
@@ -0,0 +1,60 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package com.example.vehicles.serialization;
+
+import com.amazonaws.services.lambda.runtime.CustomPojoSerializer;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.stream.JsonReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.UncheckedIOException;
+import java.lang.reflect.Type;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+public class GsonSerializer implements CustomPojoSerializer {
+ private static final Charset utf8 = StandardCharsets.UTF_8;
+ private static Gson gson;
+
+ public GsonSerializer() {
+ gson = new GsonBuilder()
+ .disableHtmlEscaping()
+ .serializeSpecialFloatingPointValues()
+ .create();
+ }
+
+ @Override
+ public T fromJson(InputStream input, Type type) {
+ try (JsonReader reader = new JsonReader(new InputStreamReader(input, utf8))) {
+ return gson.fromJson(reader, type);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public T fromJson(String input, Type type) {
+ try (JsonReader reader = new JsonReader(new StringReader(input))) {
+ return gson.fromJson(reader, type);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public void toJson(T value, OutputStream output, Type type) {
+ try (PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output, utf8)))) {
+ writer.write(gson.toJson(value));
+ }
+ }
+}
diff --git a/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/helloworld/App.java b/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/helloworld/App.java
new file mode 100644
index 00000000..02ba6048
--- /dev/null
+++ b/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/helloworld/App.java
@@ -0,0 +1,23 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+
+/**
+ * Handler for requests to Lambda function.
+ */
+public class App implements RequestHandler {
+
+ public APIGatewayProxyResponseEvent handleRequest(Vehicle vehicle, Context context) {
+ System.out.println("input: " + vehicle);
+
+ return new APIGatewayProxyResponseEvent().withStatusCode(200);
+ }
+
+}
diff --git a/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/helloworld/Vehicle.java b/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
new file mode 100644
index 00000000..ffce611b
--- /dev/null
+++ b/samples/custom-serialization/gson/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
@@ -0,0 +1,49 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.google.gson.annotations.SerializedName;
+
+public class Vehicle {
+
+ @SerializedName("vehicle-type")
+ private String vehicleType;
+
+ @SerializedName("vehicleID")
+ private String vehicleId;
+
+ public Vehicle() {
+ }
+
+ public Vehicle(String vehicleType, String vehicleId) {
+ this.vehicleType = vehicleType;
+ this.vehicleId = vehicleId;
+ }
+
+ public String getVehicleType() {
+ return vehicleType;
+ }
+
+ public void setVehicleType(String vehicleType) {
+ this.vehicleType = vehicleType;
+ }
+
+ public String getVehicleId() {
+ return vehicleId;
+ }
+
+ public void setVehicleId(String vehicleId) {
+ this.vehicleId = vehicleId;
+ }
+
+ @Override
+ public String toString() {
+ return "Vehicle{" +
+ "vehicleType='" + vehicleType + '\'' +
+ ", vehicleId='" + vehicleId + '\'' +
+ '}';
+ }
+}
diff --git a/samples/custom-serialization/gson/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer b/samples/custom-serialization/gson/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
new file mode 100644
index 00000000..0a4e281c
--- /dev/null
+++ b/samples/custom-serialization/gson/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
@@ -0,0 +1 @@
+com.example.vehicles.serialization.GsonSerializer
\ No newline at end of file
diff --git a/samples/custom-serialization/gson/README.md b/samples/custom-serialization/gson/README.md
new file mode 100644
index 00000000..924c0cfd
--- /dev/null
+++ b/samples/custom-serialization/gson/README.md
@@ -0,0 +1,6 @@
+Build and test commands
+
+```bash
+sam build
+sam local invoke -e events/event.json
+```
\ No newline at end of file
diff --git a/samples/custom-serialization/gson/events/event.json b/samples/custom-serialization/gson/events/event.json
new file mode 100644
index 00000000..5d882dba
--- /dev/null
+++ b/samples/custom-serialization/gson/events/event.json
@@ -0,0 +1,4 @@
+{
+ "vehicle-type": "car",
+ "vehicleID": 123
+}
\ No newline at end of file
diff --git a/samples/custom-serialization/gson/template.yaml b/samples/custom-serialization/gson/template.yaml
new file mode 100644
index 00000000..baf3b075
--- /dev/null
+++ b/samples/custom-serialization/gson/template.yaml
@@ -0,0 +1,43 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+Description: >
+ gson
+
+ Sample SAM Template for gson
+
+# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
+Globals:
+ Function:
+ Timeout: 20
+ MemorySize: 512
+
+Resources:
+ HelloWorldFunction:
+ Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
+ Properties:
+ CodeUri: HelloWorldFunction
+ Handler: helloworld.App::handleRequest
+ Runtime: java21
+ Architectures:
+ - x86_64
+ MemorySize: 512
+ Events:
+ HelloWorld:
+ Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
+ Properties:
+ Path: /hello
+ Method: get
+
+Outputs:
+ # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
+ # Find out more about other implicit resources you can reference within SAM
+ # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
+ HelloWorldApi:
+ Description: "API Gateway endpoint URL for Prod stage for Hello World function"
+ Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
+ HelloWorldFunction:
+ Description: "Hello World Lambda Function ARN"
+ Value: !GetAtt HelloWorldFunction.Arn
+ HelloWorldFunctionIamRole:
+ Description: "Implicit IAM Role created for Hello World function"
+ Value: !GetAtt HelloWorldFunctionRole.Arn
diff --git a/samples/custom-serialization/jackson-jr/HelloWorldFunction/build.gradle b/samples/custom-serialization/jackson-jr/HelloWorldFunction/build.gradle
new file mode 100644
index 00000000..71c89b7a
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/HelloWorldFunction/build.gradle
@@ -0,0 +1,18 @@
+plugins {
+ id 'java'
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ implementation 'com.amazonaws:aws-lambda-java-core:1.2.3'
+ implementation 'com.amazonaws:aws-lambda-java-events:3.14.0'
+ implementation 'com.fasterxml.jackson.jr:jackson-jr-objects:2.15.2'
+ implementation 'com.fasterxml.jackson.jr:jackson-jr-annotation-support:2.15.2'
+ implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2'
+}
+
+sourceCompatibility = 21
+targetCompatibility = 21
diff --git a/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/JacksonJRSerializer.java b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/JacksonJRSerializer.java
new file mode 100644
index 00000000..1ae1661b
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/JacksonJRSerializer.java
@@ -0,0 +1,88 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package com.example.vehicles.serialization;
+
+import com.amazonaws.services.lambda.runtime.CustomPojoSerializer;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.json.JsonWriteFeature;
+import com.fasterxml.jackson.jr.annotationsupport.JacksonAnnotationExtension;
+import com.fasterxml.jackson.jr.ob.JSON;
+import com.fasterxml.jackson.jr.ob.JSON.Feature;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.lang.reflect.Type;
+
+public class JacksonJRSerializer implements CustomPojoSerializer {
+
+ private static final JSON globalJson = createJson();
+
+ private static final JacksonJRSerializer instance = new JacksonJRSerializer(globalJson);
+
+ private final JSON json;
+
+ private JacksonJRSerializer(JSON json) {
+ this.json = json;
+ }
+
+ /**
+ * ServiceLoader class requires that the single exposed provider type has a default constructor
+ * to easily instantiate the service providers that it finds
+ */
+ public JacksonJRSerializer() {
+ this.json = globalJson;
+ }
+
+ public static JacksonJRSerializer getInstance() {
+ return instance;
+ }
+
+ public JSON getJson() {
+ return json;
+ }
+
+ private static JSON createJson() {
+ JSON json = JSON.builder(createJsonFactory())
+ .register(JacksonAnnotationExtension.std)
+ .build();
+
+ json.with(Feature.FLUSH_AFTER_WRITE_VALUE, false);
+
+ return json;
+ }
+
+ private static JsonFactory createJsonFactory() {
+ return JsonFactory.builder().build();
+ }
+
+ @Override
+ public T fromJson(InputStream input, Type type) {
+ try {
+ return json.beanFrom((Class) type, input);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public T fromJson(String input, Type type) {
+ try {
+ return json.beanFrom((Class) type, input);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public void toJson(T value, OutputStream output, Type type) {
+ try {
+ json.write(value, output);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+}
diff --git a/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/helloworld/App.java b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/helloworld/App.java
new file mode 100644
index 00000000..02ba6048
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/helloworld/App.java
@@ -0,0 +1,23 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+
+/**
+ * Handler for requests to Lambda function.
+ */
+public class App implements RequestHandler {
+
+ public APIGatewayProxyResponseEvent handleRequest(Vehicle vehicle, Context context) {
+ System.out.println("input: " + vehicle);
+
+ return new APIGatewayProxyResponseEvent().withStatusCode(200);
+ }
+
+}
diff --git a/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/helloworld/Vehicle.java b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
new file mode 100644
index 00000000..f32c503b
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
@@ -0,0 +1,49 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class Vehicle {
+
+ @JsonProperty("vehicle-type")
+ private String vehicleType;
+
+ @JsonProperty("vehicleID")
+ private String vehicleId;
+
+ public Vehicle() {
+ }
+
+ public Vehicle(String vehicleType, String vehicleId) {
+ this.vehicleType = vehicleType;
+ this.vehicleId = vehicleId;
+ }
+
+ public String getVehicleType() {
+ return vehicleType;
+ }
+
+ public void setVehicleType(String vehicleType) {
+ this.vehicleType = vehicleType;
+ }
+
+ public String getVehicleId() {
+ return vehicleId;
+ }
+
+ public void setVehicleId(String vehicleId) {
+ this.vehicleId = vehicleId;
+ }
+
+ @Override
+ public String toString() {
+ return "Vehicle{" +
+ "vehicleType='" + vehicleType + '\'' +
+ ", vehicleId='" + vehicleId + '\'' +
+ '}';
+ }
+}
diff --git a/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
new file mode 100644
index 00000000..a54949b0
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
@@ -0,0 +1 @@
+com.example.vehicles.serialization.JacksonJRSerializer
\ No newline at end of file
diff --git a/samples/custom-serialization/jackson-jr/README.md b/samples/custom-serialization/jackson-jr/README.md
new file mode 100644
index 00000000..3f6a2f3a
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/README.md
@@ -0,0 +1,7 @@
+Build and test commands
+
+```bash
+sam build
+sam local invoke -e events/event.json
+```
+
diff --git a/samples/custom-serialization/jackson-jr/events/event.json b/samples/custom-serialization/jackson-jr/events/event.json
new file mode 100644
index 00000000..5d882dba
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/events/event.json
@@ -0,0 +1,4 @@
+{
+ "vehicle-type": "car",
+ "vehicleID": 123
+}
\ No newline at end of file
diff --git a/samples/custom-serialization/jackson-jr/template.yaml b/samples/custom-serialization/jackson-jr/template.yaml
new file mode 100644
index 00000000..e3cf91df
--- /dev/null
+++ b/samples/custom-serialization/jackson-jr/template.yaml
@@ -0,0 +1,43 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+Description: >
+ jackson-jr
+
+ Sample SAM Template for jackson-jr
+
+# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
+Globals:
+ Function:
+ Timeout: 20
+ MemorySize: 512
+
+Resources:
+ HelloWorldFunction:
+ Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
+ Properties:
+ CodeUri: HelloWorldFunction
+ Handler: helloworld.App::handleRequest
+ Runtime: java21
+ Architectures:
+ - x86_64
+ MemorySize: 512
+ Events:
+ HelloWorld:
+ Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
+ Properties:
+ Path: /hello
+ Method: get
+
+Outputs:
+ # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
+ # Find out more about other implicit resources you can reference within SAM
+ # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
+ HelloWorldApi:
+ Description: "API Gateway endpoint URL for Prod stage for Hello World function"
+ Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
+ HelloWorldFunction:
+ Description: "Hello World Lambda Function ARN"
+ Value: !GetAtt HelloWorldFunction.Arn
+ HelloWorldFunctionIamRole:
+ Description: "Implicit IAM Role created for Hello World function"
+ Value: !GetAtt HelloWorldFunctionRole.Arn
diff --git a/samples/custom-serialization/moshi/HelloWorldFunction/pom.xml b/samples/custom-serialization/moshi/HelloWorldFunction/pom.xml
new file mode 100644
index 00000000..abbf6968
--- /dev/null
+++ b/samples/custom-serialization/moshi/HelloWorldFunction/pom.xml
@@ -0,0 +1,52 @@
+
+ 4.0.0
+ helloworld
+ HelloWorld
+ 1.0
+ jar
+ A sample Hello World created for SAM CLI.
+
+ 21
+ 21
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-core
+ 1.2.3
+
+
+ com.amazonaws
+ aws-lambda-java-events
+ 3.14.0
+
+
+
+ com.squareup.moshi
+ moshi
+ 1.15.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
diff --git a/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/MoshiSerializer.java b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/MoshiSerializer.java
new file mode 100644
index 00000000..1254b1ee
--- /dev/null
+++ b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/com/example/vehicles/serialization/MoshiSerializer.java
@@ -0,0 +1,74 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package com.example.vehicles.serialization;
+
+import com.amazonaws.services.lambda.runtime.CustomPojoSerializer;
+import com.squareup.moshi.JsonAdapter;
+import com.squareup.moshi.Moshi;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UncheckedIOException;
+import java.lang.reflect.Type;
+import okio.BufferedSink;
+import okio.Okio;
+
+public class MoshiSerializer implements CustomPojoSerializer {
+
+ private static final Moshi globalMoshi = createMoshi();
+
+ private final Moshi moshi;
+
+ /**
+ * ServiceLoader class requires that the single exposed provider type has a
+ * default constructor
+ * to easily instantiate the service providers that it finds
+ */
+ public MoshiSerializer() {
+ this.moshi = globalMoshi;
+ }
+
+ private static Moshi createMoshi() {
+ return new Moshi.Builder().build();
+ }
+
+ @Override
+ public T fromJson(InputStream input, Type type) {
+ JsonAdapter jsonAdapter = moshi.adapter(type);
+ try {
+ return jsonAdapter.fromJson(Okio.buffer(Okio.source(input)));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public T fromJson(String input, Type type) {
+ JsonAdapter jsonAdapter = moshi.adapter(type);
+ try {
+ return jsonAdapter.fromJson(input);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+
+ @Override
+ public void toJson(T value, OutputStream output, Type type) {
+ JsonAdapter jsonAdapter = moshi.adapter(type);
+ BufferedSink out = Okio.buffer(Okio.sink(output));
+ try {
+ jsonAdapter.toJson(out, value);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ out.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/helloworld/App.java b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/helloworld/App.java
new file mode 100644
index 00000000..02ba6048
--- /dev/null
+++ b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/helloworld/App.java
@@ -0,0 +1,23 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+
+/**
+ * Handler for requests to Lambda function.
+ */
+public class App implements RequestHandler {
+
+ public APIGatewayProxyResponseEvent handleRequest(Vehicle vehicle, Context context) {
+ System.out.println("input: " + vehicle);
+
+ return new APIGatewayProxyResponseEvent().withStatusCode(200);
+ }
+
+}
diff --git a/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/helloworld/Vehicle.java b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
new file mode 100644
index 00000000..0087ee2c
--- /dev/null
+++ b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
@@ -0,0 +1,49 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.squareup.moshi.Json;
+
+public class Vehicle {
+
+ @Json(name = "vehicle-type")
+ private String vehicleType;
+
+ @Json(name = "vehicleID")
+ private String vehicleId;
+
+ public Vehicle() {
+ }
+
+ public Vehicle(String vehicleType, String vehicleId) {
+ this.vehicleType = vehicleType;
+ this.vehicleId = vehicleId;
+ }
+
+ public String getVehicleType() {
+ return vehicleType;
+ }
+
+ public void setVehicleType(String vehicleType) {
+ this.vehicleType = vehicleType;
+ }
+
+ public String getVehicleId() {
+ return vehicleId;
+ }
+
+ public void setVehicleId(String vehicleId) {
+ this.vehicleId = vehicleId;
+ }
+
+ @Override
+ public String toString() {
+ return "Vehicle{" +
+ "vehicleType='" + vehicleType + '\'' +
+ ", vehicleId='" + vehicleId + '\'' +
+ '}';
+ }
+}
diff --git a/samples/custom-serialization/moshi/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
new file mode 100644
index 00000000..8f07647e
--- /dev/null
+++ b/samples/custom-serialization/moshi/HelloWorldFunction/src/main/resources/META-INF/services/com.amazonaws.services.lambda.runtime.CustomPojoSerializer
@@ -0,0 +1 @@
+com.example.vehicles.serialization.MoshiSerializer
\ No newline at end of file
diff --git a/samples/custom-serialization/moshi/README.md b/samples/custom-serialization/moshi/README.md
new file mode 100644
index 00000000..3f6a2f3a
--- /dev/null
+++ b/samples/custom-serialization/moshi/README.md
@@ -0,0 +1,7 @@
+Build and test commands
+
+```bash
+sam build
+sam local invoke -e events/event.json
+```
+
diff --git a/samples/custom-serialization/moshi/events/event.json b/samples/custom-serialization/moshi/events/event.json
new file mode 100644
index 00000000..5d882dba
--- /dev/null
+++ b/samples/custom-serialization/moshi/events/event.json
@@ -0,0 +1,4 @@
+{
+ "vehicle-type": "car",
+ "vehicleID": 123
+}
\ No newline at end of file
diff --git a/samples/custom-serialization/moshi/template.yaml b/samples/custom-serialization/moshi/template.yaml
new file mode 100644
index 00000000..8d2b9536
--- /dev/null
+++ b/samples/custom-serialization/moshi/template.yaml
@@ -0,0 +1,43 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+Description: >
+ moshi
+
+ Sample SAM Template for moshi
+
+# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
+Globals:
+ Function:
+ Timeout: 20
+ MemorySize: 512
+
+Resources:
+ HelloWorldFunction:
+ Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
+ Properties:
+ CodeUri: HelloWorldFunction
+ Handler: helloworld.App::handleRequest
+ Runtime: java21
+ Architectures:
+ - x86_64
+ MemorySize: 512
+ Events:
+ HelloWorld:
+ Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
+ Properties:
+ Path: /hello
+ Method: get
+
+Outputs:
+ # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
+ # Find out more about other implicit resources you can reference within SAM
+ # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
+ HelloWorldApi:
+ Description: "API Gateway endpoint URL for Prod stage for Hello World function"
+ Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
+ HelloWorldFunction:
+ Description: "Hello World Lambda Function ARN"
+ Value: !GetAtt HelloWorldFunction.Arn
+ HelloWorldFunctionIamRole:
+ Description: "Implicit IAM Role created for Hello World function"
+ Value: !GetAtt HelloWorldFunctionRole.Arn
diff --git a/samples/custom-serialization/request-stream-handler/HelloWorldFunction/pom.xml b/samples/custom-serialization/request-stream-handler/HelloWorldFunction/pom.xml
new file mode 100644
index 00000000..234dd6eb
--- /dev/null
+++ b/samples/custom-serialization/request-stream-handler/HelloWorldFunction/pom.xml
@@ -0,0 +1,51 @@
+
+ 4.0.0
+ helloworld
+ HelloWorld
+ 1.0
+ jar
+ A sample Hello World created for SAM CLI.
+
+ 17
+ 17
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-core
+ 1.2.3
+
+
+ com.amazonaws
+ aws-lambda-java-events
+ 3.14.0
+
+
+ com.google.code.gson
+ gson
+ 2.10.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+
+
diff --git a/samples/custom-serialization/request-stream-handler/HelloWorldFunction/src/main/java/helloworld/App.java b/samples/custom-serialization/request-stream-handler/HelloWorldFunction/src/main/java/helloworld/App.java
new file mode 100644
index 00000000..645fe8f5
--- /dev/null
+++ b/samples/custom-serialization/request-stream-handler/HelloWorldFunction/src/main/java/helloworld/App.java
@@ -0,0 +1,46 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
+import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Handler for requests to Lambda function.
+ */
+
+public class App implements RequestStreamHandler {
+ private static final Charset usAscii = StandardCharsets.US_ASCII;
+ private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
+
+ @Override
+ public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
+ try (
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, usAscii));
+ PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, usAscii)))
+ ) {
+ Vehicle vehicle = gson.fromJson(reader, Vehicle.class); System.out.println("input: " + vehicle);
+ APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent().withStatusCode(200);
+ writer.write(gson.toJson(responseEvent));
+ } catch (IllegalStateException | JsonSyntaxException exception) {
+ exception.printStackTrace();
+ }
+ }
+}
diff --git a/samples/custom-serialization/request-stream-handler/HelloWorldFunction/src/main/java/helloworld/Vehicle.java b/samples/custom-serialization/request-stream-handler/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
new file mode 100644
index 00000000..ffce611b
--- /dev/null
+++ b/samples/custom-serialization/request-stream-handler/HelloWorldFunction/src/main/java/helloworld/Vehicle.java
@@ -0,0 +1,49 @@
+/*
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package helloworld;
+
+import com.google.gson.annotations.SerializedName;
+
+public class Vehicle {
+
+ @SerializedName("vehicle-type")
+ private String vehicleType;
+
+ @SerializedName("vehicleID")
+ private String vehicleId;
+
+ public Vehicle() {
+ }
+
+ public Vehicle(String vehicleType, String vehicleId) {
+ this.vehicleType = vehicleType;
+ this.vehicleId = vehicleId;
+ }
+
+ public String getVehicleType() {
+ return vehicleType;
+ }
+
+ public void setVehicleType(String vehicleType) {
+ this.vehicleType = vehicleType;
+ }
+
+ public String getVehicleId() {
+ return vehicleId;
+ }
+
+ public void setVehicleId(String vehicleId) {
+ this.vehicleId = vehicleId;
+ }
+
+ @Override
+ public String toString() {
+ return "Vehicle{" +
+ "vehicleType='" + vehicleType + '\'' +
+ ", vehicleId='" + vehicleId + '\'' +
+ '}';
+ }
+}
diff --git a/samples/custom-serialization/request-stream-handler/README.md b/samples/custom-serialization/request-stream-handler/README.md
new file mode 100644
index 00000000..924c0cfd
--- /dev/null
+++ b/samples/custom-serialization/request-stream-handler/README.md
@@ -0,0 +1,6 @@
+Build and test commands
+
+```bash
+sam build
+sam local invoke -e events/event.json
+```
\ No newline at end of file
diff --git a/samples/custom-serialization/request-stream-handler/events/event.json b/samples/custom-serialization/request-stream-handler/events/event.json
new file mode 100644
index 00000000..5d882dba
--- /dev/null
+++ b/samples/custom-serialization/request-stream-handler/events/event.json
@@ -0,0 +1,4 @@
+{
+ "vehicle-type": "car",
+ "vehicleID": 123
+}
\ No newline at end of file
diff --git a/samples/custom-serialization/request-stream-handler/template.yaml b/samples/custom-serialization/request-stream-handler/template.yaml
new file mode 100644
index 00000000..b1ba3789
--- /dev/null
+++ b/samples/custom-serialization/request-stream-handler/template.yaml
@@ -0,0 +1,43 @@
+AWSTemplateFormatVersion: '2010-09-09'
+Transform: AWS::Serverless-2016-10-31
+Description: >
+ request-stream-handler
+
+ Sample SAM Template for request-stream-handler
+
+# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
+Globals:
+ Function:
+ Timeout: 20
+ MemorySize: 512
+
+Resources:
+ HelloWorldFunction:
+ Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
+ Properties:
+ CodeUri: HelloWorldFunction
+ Handler: helloworld.App::handleRequest
+ Runtime: java21
+ Architectures:
+ - x86_64
+ MemorySize: 512
+ Events:
+ HelloWorld:
+ Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
+ Properties:
+ Path: /hello
+ Method: get
+
+Outputs:
+ # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
+ # Find out more about other implicit resources you can reference within SAM
+ # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
+ HelloWorldApi:
+ Description: "API Gateway endpoint URL for Prod stage for Hello World function"
+ Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
+ HelloWorldFunction:
+ Description: "Hello World Lambda Function ARN"
+ Value: !GetAtt HelloWorldFunction.Arn
+ HelloWorldFunctionIamRole:
+ Description: "Implicit IAM Role created for Hello World function"
+ Value: !GetAtt HelloWorldFunctionRole.Arn