diff --git a/.autover/autover.json b/.autover/autover.json
index b1fbf84da..afba7a20c 100644
--- a/.autover/autover.json
+++ b/.autover/autover.json
@@ -143,6 +143,10 @@
{
"Name": "Amazon.Lambda.TestTool",
"Path": "Tools/LambdaTestTool-v2/src/Amazon.Lambda.TestTool/Amazon.Lambda.TestTool.csproj"
+ },
+ {
+ "Name": "Amazon.Lambda.AppSyncEvents",
+ "Path": "Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj"
}
],
"UseCommitsForChangelog": false,
diff --git a/.autover/changes/78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json b/.autover/changes/78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json
new file mode 100644
index 000000000..320fd3ada
--- /dev/null
+++ b/.autover/changes/78ee1265-f50d-434a-b25c-fcb8e9e7a26a.json
@@ -0,0 +1,11 @@
+{
+ "Projects": [
+ {
+ "Name": "Amazon.Lambda.AppSyncEvents",
+ "Type": "Major",
+ "ChangelogMessages": [
+ "Added AppSyncResolverEvent to support direct lambda resolver"
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e0660aeb5..31e288af2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -105,6 +105,7 @@ The available projects are:
* Amazon.Lambda.SQSEvents
* Amazon.Lambda.TestUtilities
* Amazon.Lambda.TestTool.BlazorTester
+* Amazon.Lambda.AppSyncEvents
The possible increment types are:
* Patch
diff --git a/Libraries/Libraries.sln b/Libraries/Libraries.sln
index bd3278a8f..03e0b7c79 100644
--- a/Libraries/Libraries.sln
+++ b/Libraries/Libraries.sln
@@ -123,17 +123,21 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestMinimalAPIApp", "test\T
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.MQEvents", "src\Amazon.Lambda.MQEvents\Amazon.Lambda.MQEvents.csproj", "{BF85932E-2DFF-41CD-8090-A672468B8FBB}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amazon.Lambda.LexV2Events", "src\Amazon.Lambda.LexV2Events\Amazon.Lambda.LexV2Events.csproj", "{3C6AABF5-0372-41E0-874F-DF18ECCC7FB6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.LexV2Events", "src\Amazon.Lambda.LexV2Events\Amazon.Lambda.LexV2Events.csproj", "{3C6AABF5-0372-41E0-874F-DF18ECCC7FB6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest", "test\Amazon.Lambda.RuntimeSupport.Tests\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj", "{0BD83939-458C-4EF5-8663-7098AD1200F2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest", "test\Amazon.Lambda.RuntimeSupport.Tests\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj", "{0BD83939-458C-4EF5-8663-7098AD1200F2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestExecutableServerlessApp", "test\TestExecutableServerlessApp\TestExecutableServerlessApp.csproj", "{DD378063-C54A-44C7-9A6F-32A6A1AE94B3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestServerlessApp.NET8", "test\TestServerlessApp.NET8\TestServerlessApp.NET8.csproj", "{7300983D-8FCE-42EA-9B9E-B1C5347D15D8}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SnapshotRestore.Registry", "src\SnapshotRestore.Registry\SnapshotRestore.Registry.csproj", "{7261A438-8C1D-47AD-98B0-7678F72E4382}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SnapshotRestore.Registry", "src\SnapshotRestore.Registry\SnapshotRestore.Registry.csproj", "{7261A438-8C1D-47AD-98B0-7678F72E4382}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SnapshotRestore.Registry.Tests", "test\SnapshotRestore.Registry.Tests\SnapshotRestore.Registry.Tests.csproj", "{A699E183-D0D4-4F26-A0A7-88DA5607F455}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SnapshotRestore.Registry.Tests", "test\SnapshotRestore.Registry.Tests\SnapshotRestore.Registry.Tests.csproj", "{A699E183-D0D4-4F26-A0A7-88DA5607F455}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Amazon.Lambda.AppSyncEvents", "src\Amazon.Lambda.AppSyncEvents\Amazon.Lambda.AppSyncEvents.csproj", "{99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventsTests.NET8", "test\EventsTests.NET8\EventsTests.NET8.csproj", "{1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amazon.Lambda.DynamoDBEvents.SDK.Convertor", "src\Amazon.Lambda.DynamoDBEvents.SDK.Convertor\Amazon.Lambda.DynamoDBEvents.SDK.Convertor.csproj", "{3400F4E9-BA12-4D3D-9BA1-2798AA8D0AFC}"
EndProject
@@ -387,6 +391,14 @@ Global
{D61CBB71-17AB-4EC2-8C6A-70E9D7C60526}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D61CBB71-17AB-4EC2-8C6A-70E9D7C60526}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D61CBB71-17AB-4EC2-8C6A-70E9D7C60526}.Release|Any CPU.Build.0 = Release|Any CPU
+ {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -456,11 +468,14 @@ Global
{3400F4E9-BA12-4D3D-9BA1-2798AA8D0AFC} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12}
{074DB940-82BA-47D4-B888-C213D4220A82} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69}
{D61CBB71-17AB-4EC2-8C6A-70E9D7C60526} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69}
+ {99F39E49-1FD0-4EF5-BF4B-8F2473FB8198} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12}
+ {1FB22337-5D88-4CE7-ADFF-FFD89204F0E9} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {503678A4-B8D1-4486-8915-405A3E9CF0EB}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
+ test\EventsTests.Shared\EventsTests.Shared.projitems*{1fb22337-5d88-4ce7-adff-ffd89204f0e9}*SharedItemsImports = 5
test\EventsTests.Shared\EventsTests.Shared.projitems*{44e9d925-b61d-4234-97b7-61424c963ba6}*SharedItemsImports = 5
test\EventsTests.Shared\EventsTests.Shared.projitems*{a2cb78bb-e54f-48ca-bbfb-9553d27ef23d}*SharedItemsImports = 13
test\EventsTests.Shared\EventsTests.Shared.projitems*{c1bb30d2-3237-4cfc-ba93-627471148ec2}*SharedItemsImports = 5
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj
new file mode 100644
index 000000000..7b3352894
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/Amazon.Lambda.AppSyncEvents.csproj
@@ -0,0 +1,22 @@
+
+
+
+
+
+ Amazon Lambda .NET support - AWS AppSync package.
+ net8.0
+ Amazon.Lambda.AppSyncEvents
+ 0.0.1
+ Amazon.Lambda.AppSyncEvents
+ Amazon.Lambda.AppSyncEvents
+ AWS;Amazon;Lambda
+ enable
+
+
+
+ IL2026,IL2067,IL2075
+ true
+ true
+
+
+
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs
new file mode 100644
index 000000000..cfb36d85d
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerEvent.cs
@@ -0,0 +1,65 @@
+namespace Amazon.Lambda.AppSyncEvents;
+
+///
+/// Represents an AWS AppSync authorization event that is sent to a Lambda authorizer
+/// for evaluating access permissions to the GraphQL API.
+///
+public class AppSyncAuthorizerEvent
+{
+ ///
+ /// Gets or sets the authorization token received from the client request.
+ /// This token is used to make authorization decisions.
+ ///
+ public string AuthorizationToken { get; set; }
+
+ ///
+ /// Gets or sets the headers from the client request.
+ /// Contains key-value pairs of HTTP header names and their values.
+ ///
+ public Dictionary RequestHeaders { get; set; }
+
+ ///
+ /// Gets or sets the context information about the AppSync request.
+ /// Contains metadata about the API and the GraphQL operation being executed.
+ ///
+ public AppSyncRequestContext RequestContext { get; set; }
+}
+
+///
+/// Contains contextual information about the AppSync request being authorized.
+/// This class provides details about the API, account, and GraphQL operation.
+///
+public class AppSyncRequestContext
+{
+ ///
+ /// Gets or sets the unique identifier of the AppSync API.
+ ///
+ public string ApiId { get; set; }
+
+ ///
+ /// Gets or sets the AWS account ID where the AppSync API is deployed.
+ ///
+ public string AccountId { get; set; }
+
+ ///
+ /// Gets or sets the unique identifier for this specific request.
+ ///
+ public string RequestId { get; set; }
+
+ ///
+ /// Gets or sets the GraphQL query string containing the operation to be executed.
+ ///
+ public string QueryString { get; set; }
+
+ ///
+ /// Gets or sets the name of the GraphQL operation to be executed.
+ /// This corresponds to the operation name in the GraphQL query.
+ ///
+ public string OperationName { get; set; }
+
+ ///
+ /// Gets or sets the variables passed to the GraphQL operation.
+ /// Contains key-value pairs of variable names and their values.
+ ///
+ public Dictionary Variables { get; set; }
+}
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs
new file mode 100644
index 000000000..356bc1895
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncAuthorizerResult.cs
@@ -0,0 +1,33 @@
+using System.Text.Json.Serialization;
+namespace Amazon.Lambda.AppSyncEvents;
+
+///
+/// Represents the authorization result returned by a Lambda authorizer to AWS AppSync
+/// containing authorization decisions and optional context for the GraphQL API.
+///
+public class AppSyncAuthorizerResult
+{
+ ///
+ /// Indicates if the request is authorized
+ ///
+ [JsonPropertyName("isAuthorized")]
+ public bool IsAuthorized { get; set; }
+
+ ///
+ /// Custom context to pass to resolvers, only supports key-value pairs.
+ ///
+ [JsonPropertyName("resolverContext")]
+ public Dictionary ResolverContext { get; set; }
+
+ ///
+ /// List of fields that are denied access
+ ///
+ [JsonPropertyName("deniedFields")]
+ public IEnumerable DeniedFields { get; set; }
+
+ ///
+ /// The number of seconds that the response should be cached for
+ ///
+ [JsonPropertyName("ttlOverride")]
+ public int? TtlOverride { get; set; }
+}
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs
new file mode 100644
index 000000000..2b048cc81
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncCognitoIdentity.cs
@@ -0,0 +1,42 @@
+namespace Amazon.Lambda.AppSyncEvents;
+
+///
+/// Represents Amazon Cognito User Pools authorization identity for AppSync
+///
+public class AppSyncCognitoIdentity
+{
+ ///
+ /// The source IP address of the caller received by AWS AppSync
+ ///
+ public List SourceIp { get; set; }
+
+ ///
+ /// The username of the authenticated user
+ ///
+ public string Username { get; set; }
+
+ ///
+ /// The UUID of the authenticated user
+ ///
+ public string Sub { get; set; }
+
+ ///
+ /// The claims that the user has
+ ///
+ public Dictionary Claims { get; set; }
+
+ ///
+ /// The default authorization strategy for this caller (ALLOW or DENY)
+ ///
+ public string DefaultAuthStrategy { get; set; }
+
+ ///
+ /// List of OIDC groups
+ ///
+ public List Groups { get; set; }
+
+ ///
+ /// The token issuer
+ ///
+ public string Issuer { get; set; }
+}
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs
new file mode 100644
index 000000000..a22e82430
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncIamIdentity.cs
@@ -0,0 +1,47 @@
+namespace Amazon.Lambda.AppSyncEvents;
+
+///
+/// Represents AWS IAM authorization identity for AppSync
+///
+public class AppSyncIamIdentity
+{
+ ///
+ /// The source IP address of the caller received by AWS AppSync
+ ///
+ public List SourceIp { get; set; }
+
+ ///
+ /// The username of the authenticated user (IAM user principal)
+ ///
+ public string Username { get; set; }
+
+ ///
+ /// The AWS account ID of the caller
+ ///
+ public string AccountId { get; set; }
+
+ ///
+ /// The Amazon Cognito identity pool ID associated with the caller
+ ///
+ public string CognitoIdentityPoolId { get; set; }
+
+ ///
+ /// The Amazon Cognito identity ID of the caller
+ ///
+ public string CognitoIdentityId { get; set; }
+
+ ///
+ /// The ARN of the IAM user
+ ///
+ public string UserArn { get; set; }
+
+ ///
+ /// Either authenticated or unauthenticated based on the identity type
+ ///
+ public string CognitoIdentityAuthType { get; set; }
+
+ ///
+ /// A comma separated list of external identity provider information used in obtaining the credentials used to sign the request
+ ///
+ public string CognitoIdentityAuthProvider { get; set; }
+}
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs
new file mode 100644
index 000000000..b55a8645b
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncLambdaIdentity.cs
@@ -0,0 +1,13 @@
+namespace Amazon.Lambda.AppSyncEvents;
+
+///
+/// Represents AWS Lambda authorization identity for AppSync
+///
+public class AppSyncLambdaIdentity
+{
+ ///
+ /// Optional context information that will be passed to subsequent resolvers
+ /// Can contain user information, claims, or any other contextual data
+ ///
+ public Dictionary ResolverContext { get; set; }
+}
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs
new file mode 100644
index 000000000..f1023c286
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncOidcIdentity.cs
@@ -0,0 +1,22 @@
+namespace Amazon.Lambda.AppSyncEvents;
+
+///
+/// Represents OpenID Connect authorization identity for AppSync
+///
+public class AppSyncOidcIdentity
+{
+ ///
+ /// Claims from the OIDC token as key-value pairs
+ ///
+ public Dictionary Claims { get; set; }
+
+ ///
+ /// The issuer of the OIDC token
+ ///
+ public string Issuer { get; set; }
+
+ ///
+ /// The UUID of the authenticated user
+ ///
+ public string Sub { get; set; }
+}
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs
new file mode 100644
index 000000000..c650be02d
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/AppSyncResolverEvent.cs
@@ -0,0 +1,101 @@
+namespace Amazon.Lambda.AppSyncEvents;
+
+///
+/// Represents the event payload received from AWS AppSync.
+///
+public class AppSyncResolverEvent
+{
+ ///
+ /// Gets or sets the input arguments for the GraphQL operation.
+ ///
+ public TArguments Arguments { get; set; }
+
+ ///
+ /// An object that contains information about the caller.
+ /// Returns null for API_KEY authorization.
+ /// Returns AppSyncIamIdentity for AWS_IAM authorization.
+ /// Returns AppSyncCognitoIdentity for AMAZON_COGNITO_USER_POOLS authorization.
+ /// For AWS_LAMBDA authorization, returns the object returned by your Lambda authorizer function.
+ ///
+ ///
+ /// The Identity object type depends on the authorization mode:
+ /// - For API_KEY: null
+ /// - For AWS_IAM:
+ /// - For AMAZON_COGNITO_USER_POOLS:
+ /// - For AWS_LAMBDA:
+ /// - For OPENID_CONNECT:
+ ///
+ public object Identity { get; set; }
+
+ ///
+ /// Gets or sets information about the data source that originated the event.
+ ///
+ public object Source { get; set; }
+
+ ///
+ /// Gets or sets information about the HTTP request that triggered the event.
+ ///
+ public RequestContext Request { get; set; }
+
+ ///
+ /// Gets or sets information about the previous state of the data before the operation was executed.
+ ///
+ public object Prev { get; set; }
+
+ ///
+ /// Gets or sets information about the GraphQL operation being executed.
+ ///
+ public Information Info { get; set; }
+
+ ///
+ /// Gets or sets additional information that can be passed between Lambda functions during an AppSync pipeline.
+ ///
+ public Dictionary Stash { get; set; }
+}
+
+///
+/// Represents information about the HTTP request that triggered the event.
+///
+public class RequestContext
+{
+ ///
+ /// Gets or sets the headers of the HTTP request.
+ ///
+ public Dictionary Headers { get; set; }
+
+ ///
+ /// Gets or sets the domain name associated with the request.
+ ///
+ public string DomainName { get; set; }
+}
+
+///
+/// Represents information about the GraphQL operation being executed.
+///
+public class Information
+{
+ ///
+ /// Gets or sets the name of the GraphQL field being executed.
+ ///
+ public string FieldName { get; set; }
+
+ ///
+ /// Gets or sets a list of fields being selected in the GraphQL operation.
+ ///
+ public List SelectionSetList { get; set; }
+
+ ///
+ /// Gets or sets the GraphQL selection set for the operation.
+ ///
+ public string SelectionSetGraphQL { get; set; }
+
+ ///
+ /// Gets or sets the variables passed to the GraphQL operation.
+ ///
+ public Dictionary Variables { get; set; }
+
+ ///
+ /// Gets or sets the parent type name for the GraphQL operation.
+ ///
+ public string ParentTypeName { get; set; }
+}
diff --git a/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md
new file mode 100644
index 000000000..c883e32cd
--- /dev/null
+++ b/Libraries/src/Amazon.Lambda.AppSyncEvents/README.md
@@ -0,0 +1,72 @@
+# Amazon.Lambda.AppSyncEvents
+
+This package contains classes that can be used as input types for Lambda functions that process AppSync events.
+
+## Sample Function
+
+The following is a sample class and Lambda function that receives AppSync resolver event record data as an `appSyncResolverEvent` and logs some of the incoming event data. (Note that by default anything written to Console will be logged as CloudWatch Logs events.)
+
+```csharp
+public void Handler(AppSyncResolverEvent> appSyncResolverEvent, ILambdaContext context)
+{
+ foreach (var item in appSyncResolverEvent.Arguments)
+ {
+ Console.WriteLine($"AppSync request key - {item.Key}.");
+ }
+
+ if (appSyncResolverEvent.Identity != null)
+ {
+ // Create an instance of the serializer
+ var lambdaSerializer = new DefaultLambdaJsonSerializer();
+
+ using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(appSyncResolverEvent.Identity.ToString()!)))
+ {
+ // When using AMAZON_COGNITO_USER_POOLS authorization
+ var cognitoIdentity = lambdaSerializer.Deserialize(stream);
+
+ // When using AWS_IAM authorization
+ var iamIdentity = lambdaSerializer.Deserialize(stream);
+
+ // When using AWS_LAMBDA authorization
+ var lambdaIdentity = lambdaSerializer.Deserialize(stream);
+
+ // When using OPENID_CONNECT authorization
+ var oidcIdentity = lambdaSerializer.Deserialize(stream);
+ }
+ }
+}
+```
+
+## Example of Custom Lambda Authorizer
+This example demonstrates how to implement a custom Lambda authorizer for AppSync using the AppSync Events package. The authorizer function receives an `AppSyncAuthorizerEvent` containing the authorization token and request context. It returns an `AppSyncAuthorizerResult` that determines whether the request is authorized and includes additional context.
+
+The function provides contextual data through the `ResolverContext` property of the `AppSyncAuthorizerResult` instance. This information can be accessed via the `Identity` property of the `AppSyncResolverEvent` instance. Since the `Identity` property is of type `object`, you can deserialize it to `AppSyncLambdaIdentity` (as shown above) to get strong typing support.
+
+
+```csharp
+public async Task CustomLambdaAuthorizerHandler(AppSyncAuthorizerEvent appSyncAuthorizerEvent)
+{
+ var authorizationToken = appSyncAuthorizerEvent.AuthorizationToken;
+ var apiId = appSyncAuthorizerEvent.RequestContext.ApiId;
+ var accountId = appSyncAuthorizerEvent.RequestContext.AccountId;
+
+ var response = new AppSyncAuthorizerResult
+ {
+ IsAuthorized = authorizationToken == "custom-authorized",
+ ResolverContext = new Dictionary
+ {
+ { "userid", "test-user-id" },
+ { "info", "contextual information A" },
+ { "more_info", "contextual information B" }
+ },
+ DeniedFields = new List
+ {
+ $"arn:aws:appsync:{Environment.GetEnvironmentVariable("AWS_REGION")}:{accountId}:apis/{apiId}/types/Event/fields/comments",
+ "Mutation.createEvent"
+ },
+ TtlOverride = 10
+ };
+
+ return response;
+}
+```
\ No newline at end of file
diff --git a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj
index af60ce665..5e64d7c09 100644
--- a/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj
+++ b/Libraries/test/EventsTests.NET6/EventsTests.NET6.csproj
@@ -1,7 +1,7 @@
- net6.0;net8.0
+ net6.0
EventsTests31
true
EventsTests.NET6
diff --git a/Libraries/test/EventsTests.NET8/AppSyncEventTests.cs b/Libraries/test/EventsTests.NET8/AppSyncEventTests.cs
new file mode 100644
index 000000000..4c927f1fd
--- /dev/null
+++ b/Libraries/test/EventsTests.NET8/AppSyncEventTests.cs
@@ -0,0 +1,287 @@
+
+#pragma warning disable 618
+namespace Amazon.Lambda.Tests;
+
+using Amazon.Lambda.AppSyncEvents;
+using Amazon.Lambda.Core;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Xunit;
+
+public class AppSyncEventTests
+{
+ // This utility method takes care of removing the BOM that System.Text.Json doesn't like.
+ public MemoryStream LoadJsonTestFile(string filename)
+ {
+ var json = File.ReadAllText(filename);
+ return new MemoryStream(UTF8Encoding.UTF8.GetBytes(json));
+ }
+
+ public string SerializeJson(ILambdaSerializer serializer, T response)
+ {
+ string serializedJson;
+ using (MemoryStream stream = new MemoryStream())
+ {
+ serializer.Serialize(response, stream);
+
+ stream.Position = 0;
+ serializedJson = Encoding.UTF8.GetString(stream.ToArray());
+ }
+ return serializedJson;
+ }
+
+ [Theory]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
+ public void AppSyncTest(Type serializerType)
+ {
+ var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
+ using (var fileStream = LoadJsonTestFile("appsync-event.json"))
+ {
+ var appSyncEvent = serializer.Deserialize>>(fileStream);
+ Assert.NotNull(appSyncEvent);
+ Assert.NotNull(appSyncEvent.Arguments);
+ Assert.NotNull(appSyncEvent.Arguments["input"]);
+
+ Assert.NotNull(appSyncEvent.Request);
+ Assert.NotNull(appSyncEvent.Request.Headers);
+ var headers = appSyncEvent.Request.Headers;
+ Assert.Equal("value1", headers["key1"]);
+ Assert.Equal("value2", headers["key2"]);
+
+ Assert.NotNull(appSyncEvent.Info);
+ Assert.Equal("openSupportTicket", appSyncEvent.Info.FieldName);
+ Assert.Equal("Mutation", appSyncEvent.Info.ParentTypeName);
+
+ Assert.NotNull(appSyncEvent.Info.SelectionSetList);
+ Assert.Equal(6, appSyncEvent.Info.SelectionSetList.Count);
+ Assert.Contains("ticketId", appSyncEvent.Info.SelectionSetList);
+ Assert.Contains("status", appSyncEvent.Info.SelectionSetList);
+ Assert.Contains("title", appSyncEvent.Info.SelectionSetList);
+ Assert.Contains("description", appSyncEvent.Info.SelectionSetList);
+ Assert.Contains("createdAt", appSyncEvent.Info.SelectionSetList);
+ Assert.Contains("updatedAt", appSyncEvent.Info.SelectionSetList);
+
+ Assert.NotNull(appSyncEvent.Info.SelectionSetGraphQL);
+ Assert.NotNull(appSyncEvent.Info.Variables);
+ Assert.NotNull(appSyncEvent.Info.Variables["input"]);
+
+ Assert.NotNull(appSyncEvent.Stash);
+ Assert.Empty(appSyncEvent.Stash);
+ }
+ }
+
+ [Theory]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
+ public void AppSyncTestCognitoAuthorizer(Type serializerType)
+ {
+ var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
+ using (var fileStream = LoadJsonTestFile("appsync-event-cognito-authorizer.json"))
+ {
+ var request = serializer.Deserialize>>(fileStream);
+
+ Assert.NotNull(request.Identity);
+
+ using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString())))
+ {
+ var identity = serializer.Deserialize(stream);
+ Assert.NotNull(identity);
+
+ // Claims
+ Assert.NotNull(identity.Claims);
+ Assert.True(identity.Claims.ContainsKey("client_id"));
+ Assert.True(identity.Claims.ContainsKey("scope"));
+ Assert.True(identity.Claims.ContainsKey("sub"));
+ Assert.True(identity.Claims.ContainsKey("token_use"));
+
+ // DefaultAuthStrategy
+ Assert.NotEmpty(identity.DefaultAuthStrategy);
+
+ // Groups
+ Assert.NotNull(identity.Groups);
+ Assert.NotEmpty(identity.Groups);
+
+ // Issuer
+ Assert.NotEmpty(identity.Issuer);
+
+ // SourceIp
+ Assert.NotNull(identity.SourceIp);
+ Assert.NotEmpty(identity.SourceIp);
+
+ // Sub
+ Assert.NotEmpty(identity.Sub);
+
+ // Username
+ Assert.NotEmpty(identity.Username);
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
+ public void AppSyncTestIAMAuthorizer(Type serializerType)
+ {
+ var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
+ using (var fileStream = LoadJsonTestFile("appsync-event-iam-authorizer.json"))
+ {
+ var request = serializer.Deserialize>>(fileStream);
+
+ Assert.NotNull(request.Identity);
+
+ using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString())))
+ {
+ var identity = serializer.Deserialize(stream);
+ Assert.NotNull(identity);
+
+ // AccountId
+ Assert.NotEmpty(identity.AccountId);
+
+ // CognitoIdentityAuthProvider
+ Assert.NotEmpty(identity.CognitoIdentityAuthProvider);
+
+ // CognitoIdentityAuthType
+ Assert.NotEmpty(identity.CognitoIdentityAuthType);
+
+ // CognitoIdentityId
+ Assert.NotEmpty(identity.CognitoIdentityId);
+
+ // CognitoIdentityPoolId
+ Assert.NotEmpty(identity.CognitoIdentityPoolId);
+
+ // SourceIp
+ Assert.NotNull(identity.SourceIp);
+ Assert.NotEmpty(identity.SourceIp);
+
+ // UserArn
+ Assert.NotEmpty(identity.UserArn);
+
+ // Username
+ Assert.NotEmpty(identity.Username);
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
+ public void AppSyncTestLambdaAuthorizer(Type serializerType)
+ {
+ var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
+ using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer.json"))
+ {
+ var request = serializer.Deserialize>>(fileStream);
+
+ Assert.NotNull(request.Identity);
+
+ using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString())))
+ {
+ var identity = serializer.Deserialize(stream);
+ Assert.NotNull(identity);
+
+ // ResolverContext
+ Assert.NotNull(identity.ResolverContext);
+ Assert.NotEmpty(identity.ResolverContext["userid"]);
+ Assert.NotEmpty(identity.ResolverContext["info"]);
+ Assert.NotEmpty(identity.ResolverContext["more_info"]);
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
+ public void AppSyncTestOidcAuthorizer(Type serializerType)
+ {
+ var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
+ using (var fileStream = LoadJsonTestFile("appsync-event-oidc-authorizer.json"))
+ {
+ var request = serializer.Deserialize>>(fileStream);
+
+ Assert.NotNull(request.Identity);
+
+ using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(request.Identity.ToString())))
+ {
+ var identity = serializer.Deserialize(stream);
+ Assert.NotNull(identity);
+
+ // Claims
+ Assert.NotNull(identity.Claims);
+ Assert.True(identity.Claims.ContainsKey("client_id"));
+
+ // Issuer
+ Assert.NotEmpty(identity.Issuer);
+
+ // Sub
+ Assert.NotEmpty(identity.Sub);
+ }
+ }
+ }
+
+ [Theory]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
+ public void AppSyncTestLambdaAuthorizerRequestEvent(Type serializerType)
+ {
+ var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
+ using (var fileStream = LoadJsonTestFile("appsync-event-lambda-authorizer-request.json"))
+ {
+ var request = serializer.Deserialize(fileStream);
+
+ // Assert Authorization Token
+ Assert.Equal("custom-token", request.AuthorizationToken);
+
+ // Assert Request Context
+ Assert.NotNull(request.RequestContext);
+ Assert.Equal("xxxxxxxx", request.RequestContext.ApiId);
+ Assert.Equal("112233445566", request.RequestContext.AccountId);
+ Assert.Equal("36307622-97fe-4dfa-bd71-b15b1d03ce97", request.RequestContext.RequestId);
+ Assert.Equal("MyQuery", request.RequestContext.OperationName);
+ Assert.NotNull(request.RequestContext.Variables);
+ Assert.Empty(request.RequestContext.Variables);
+ Assert.Contains("listTodos", request.RequestContext.QueryString);
+
+ // Assert Request Headers
+ Assert.NotNull(request.RequestHeaders);
+ Assert.Equal("This is test token", request.RequestHeaders["authorization"]);
+ Assert.Equal("application/json", request.RequestHeaders["content-type"]);
+ Assert.Equal("https://ap-south-1.console.aws.amazon.com", request.RequestHeaders["origin"]);
+ }
+ }
+
+ [Theory]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.LambdaJsonSerializer))]
+ [InlineData(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
+ public void AppSyncTestLambdaAuthorizerResponseEvent(Type serializerType)
+ {
+ var response = new AppSyncAuthorizerResult
+ {
+ IsAuthorized = true,
+ ResolverContext = new Dictionary
+ {
+ { "userid", "test-user-id" },
+ { "info", "contextual information A" },
+ { "more_info", "contextual information B" }
+ },
+ DeniedFields = new List
+ {
+ "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments",
+ "Mutation.createEvent"
+ },
+ TtlOverride = 10
+ };
+
+ var serializer = Activator.CreateInstance(serializerType) as ILambdaSerializer;
+ var json = SerializeJson(serializer, response);
+ var actualObject = JObject.Parse(json);
+ var expectedJObject = JObject.Parse(File.ReadAllText("appsync-event-lambda-authorizer-response.json"));
+
+ Assert.True(JToken.DeepEquals(actualObject, expectedJObject));
+ }
+}
+
+#pragma warning restore 618
diff --git a/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj
new file mode 100644
index 000000000..db86179bf
--- /dev/null
+++ b/Libraries/test/EventsTests.NET8/EventsTests.NET8.csproj
@@ -0,0 +1,66 @@
+
+
+
+ net8.0
+ EventsTests31
+ true
+ EventsTests.NET8
+ latest
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems
index 4fdc41123..b424aa506 100644
--- a/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems
+++ b/Libraries/test/EventsTests.Shared/EventsTests.Shared.projitems
@@ -12,6 +12,13 @@
+
+
+
+
+
+
+
diff --git a/Libraries/test/EventsTests.Shared/appsync-event-cognito-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-cognito-authorizer.json
new file mode 100644
index 000000000..0c4805d02
--- /dev/null
+++ b/Libraries/test/EventsTests.Shared/appsync-event-cognito-authorizer.json
@@ -0,0 +1,68 @@
+{
+ "arguments": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "identity": {
+ "claims": {
+ "sub": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12",
+ "cognito:groups": [
+ "admin"
+ ],
+ "iss": "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_xxxxxx",
+ "version": 2,
+ "client_id": "458vq6091kg88r4qurfnxxxxx",
+ "origin_jti": "6102131f-89b2-4909-80bc-200ccf675892",
+ "event_id": "373cdbc2-5460-4dff-bebb-3cba1de69777",
+ "token_use": "access",
+ "scope": "aws.cognito.signin.user.admin openid profile email",
+ "auth_time": 1737358577,
+ "exp": 1737362177,
+ "iat": 1737358577,
+ "jti": "821f10f1-9a6c-46bd-b1d6-62e266d6639b",
+ "username": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12"
+ },
+ "defaultAuthStrategy": "ALLOW",
+ "groups": [
+ "admin"
+ ],
+ "issuer": "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_xxxxxx",
+ "sourceIp": [
+ "192.168.234.157"
+ ],
+ "sub": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12",
+ "username": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12"
+ },
+ "source": null,
+ "request": {
+ "headers": {
+ "key1": "value1",
+ "key2": "value2"
+ },
+ "domainName": null
+ },
+ "prev": null,
+ "info": {
+ "fieldName": "openSupportTicket",
+ "selectionSetList": [
+ "ticketId",
+ "status",
+ "title",
+ "description",
+ "createdAt",
+ "updatedAt",
+ "__typename"
+ ],
+ "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}",
+ "variables": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "parentTypeName": "Mutation"
+ },
+ "stash": {}
+}
\ No newline at end of file
diff --git a/Libraries/test/EventsTests.Shared/appsync-event-iam-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-iam-authorizer.json
new file mode 100644
index 000000000..f26e60b7c
--- /dev/null
+++ b/Libraries/test/EventsTests.Shared/appsync-event-iam-authorizer.json
@@ -0,0 +1,48 @@
+{
+ "arguments": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "identity": {
+ "accountId": "123456789012",
+ "cognitoIdentityPoolId": "us-east-1:1234abcd-1234-5678-abcd-1234567890ab",
+ "cognitoIdentityId": "us-east-1:1234abcd-1234-5678-abcd-1234567890ab",
+ "sourceIp": [ "192.0.2.1" ],
+ "username": "IAMUser",
+ "userArn": "arn:aws:iam::123456789012:user/IAMUser",
+ "cognitoIdentityAuthType": "authenticated",
+ "cognitoIdentityAuthProvider": "cognito-identity.amazonaws.com"
+ },
+ "source": null,
+ "request": {
+ "headers": {
+ "key1": "value1",
+ "key2": "value2"
+ },
+ "domainName": null
+ },
+ "prev": null,
+ "info": {
+ "fieldName": "openSupportTicket",
+ "selectionSetList": [
+ "ticketId",
+ "status",
+ "title",
+ "description",
+ "createdAt",
+ "updatedAt",
+ "__typename"
+ ],
+ "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}",
+ "variables": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "parentTypeName": "Mutation"
+ },
+ "stash": {}
+}
\ No newline at end of file
diff --git a/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-request.json b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-request.json
new file mode 100644
index 000000000..47648175f
--- /dev/null
+++ b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-request.json
@@ -0,0 +1,35 @@
+{
+ "authorizationToken": "custom-token",
+ "requestContext": {
+ "apiId": "xxxxxxxx",
+ "accountId": "112233445566",
+ "requestId": "36307622-97fe-4dfa-bd71-b15b1d03ce97",
+ "queryString": "query MyQuery {\n listTodos {\n completed\n createdAt\n description\n id\n title\n updatedAt\n }\n}\n",
+ "operationName": "MyQuery",
+ "variables": {}
+ },
+ "requestHeaders": {
+ "x-forwarded-for": "182.70.233.9, 15.158.25.215",
+ "accept-encoding": "gzip, deflate, br, zstd",
+ "sec-ch-ua-mobile": "?0",
+ "referer": "https://ap-south-1.console.aws.amazon.com/",
+ "via": "2.0 30c122bd8d8efabc1fd1b3b11bfb53ea.cloudfront.net (CloudFront)",
+ "content-type": "application/json",
+ "origin": "https://ap-south-1.console.aws.amazon.com",
+ "sec-fetch-mode": "cors",
+ "authorization": "This is test token",
+ "sec-fetch-dest": "empty",
+ "content-length": "159",
+ "x-amz-user-agent": "AWS-Console-AppSync/",
+ "sec-ch-ua-platform": "\"macOS\"",
+ "x-forwarded-proto": "https",
+ "accept-language": "en-US,en;q=0.9",
+ "host": "cndjdbaxrfhzppcdhvfvx3a7zq.appsync-api.ap-south-1.amazonaws.com",
+ "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36",
+ "sec-fetch-site": "cross-site",
+ "accept": "application/json, text/plain, */*",
+ "priority": "u=1, i",
+ "sec-ch-ua": "\"Chromium\";v=\"134\", \"Not:A-Brand\";v=\"24\", \"Google Chrome\";v=\"134\"",
+ "x-forwarded-port": "443"
+ }
+ }
\ No newline at end of file
diff --git a/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-response.json b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-response.json
new file mode 100644
index 000000000..6f406ad5f
--- /dev/null
+++ b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer-response.json
@@ -0,0 +1,13 @@
+{
+ "isAuthorized": true,
+ "resolverContext": {
+ "userid": "test-user-id",
+ "info": "contextual information A",
+ "more_info": "contextual information B"
+ },
+ "deniedFields": [
+ "arn:aws:appsync:us-east-1:1234567890:apis/xxxxxx/types/Event/fields/comments",
+ "Mutation.createEvent"
+ ],
+ "ttlOverride": 10
+ }
\ No newline at end of file
diff --git a/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer.json
new file mode 100644
index 000000000..d6fcf6a0c
--- /dev/null
+++ b/Libraries/test/EventsTests.Shared/appsync-event-lambda-authorizer.json
@@ -0,0 +1,45 @@
+{
+ "arguments": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "identity": {
+ "resolverContext": {
+ "userid": "test-user-id",
+ "info": "contextual information A",
+ "more_info": "contextual information B"
+ }
+ },
+ "source": null,
+ "request": {
+ "headers": {
+ "key1": "value1",
+ "key2": "value2"
+ },
+ "domainName": null
+ },
+ "prev": null,
+ "info": {
+ "fieldName": "openSupportTicket",
+ "selectionSetList": [
+ "ticketId",
+ "status",
+ "title",
+ "description",
+ "createdAt",
+ "updatedAt",
+ "__typename"
+ ],
+ "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}",
+ "variables": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "parentTypeName": "Mutation"
+ },
+ "stash": {}
+}
\ No newline at end of file
diff --git a/Libraries/test/EventsTests.Shared/appsync-event-oidc-authorizer.json b/Libraries/test/EventsTests.Shared/appsync-event-oidc-authorizer.json
new file mode 100644
index 000000000..c4d50868e
--- /dev/null
+++ b/Libraries/test/EventsTests.Shared/appsync-event-oidc-authorizer.json
@@ -0,0 +1,51 @@
+{
+ "arguments": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "identity": {
+ "claims": {
+ "client_id": "458vq6091kg88r4qurfnxxxxx",
+ "event_id": "373cdbc2-5460-4dff-bebb-3cba1de69777",
+ "username": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12"
+ },
+ "defaultAuthStrategy": "ALLOW",
+ "groups": [
+ "admin"
+ ],
+ "issuer": "https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_xxxxxx",
+ "sub": "b662d2e4-d0a1-7098-4973-20a5d6ff5a12"
+ },
+ "source": null,
+ "request": {
+ "headers": {
+ "key1": "value1",
+ "key2": "value2"
+ },
+ "domainName": null
+ },
+ "prev": null,
+ "info": {
+ "fieldName": "openSupportTicket",
+ "selectionSetList": [
+ "ticketId",
+ "status",
+ "title",
+ "description",
+ "createdAt",
+ "updatedAt",
+ "__typename"
+ ],
+ "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n __typename\n}",
+ "variables": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "parentTypeName": "Mutation"
+ },
+ "stash": {}
+}
\ No newline at end of file
diff --git a/Libraries/test/EventsTests.Shared/appsync-event.json b/Libraries/test/EventsTests.Shared/appsync-event.json
new file mode 100644
index 000000000..224f5cb05
--- /dev/null
+++ b/Libraries/test/EventsTests.Shared/appsync-event.json
@@ -0,0 +1,38 @@
+{
+ "arguments": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "identity": null,
+ "source": null,
+ "request": {
+ "headers": {
+ "key1": "value1",
+ "key2": "value2"
+ },
+ "domainName": null
+ },
+ "prev": null,
+ "info": {
+ "fieldName": "openSupportTicket",
+ "selectionSetList": [
+ "ticketId",
+ "status",
+ "title",
+ "description",
+ "createdAt",
+ "updatedAt"
+ ],
+ "selectionSetGraphQL": "{\n ticketId\n status\n title\n description\n createdAt\n updatedAt\n }",
+ "variables": {
+ "input": {
+ "title": "Support Ticket Test",
+ "description": "Support Ticket Test"
+ }
+ },
+ "parentTypeName": "Mutation"
+ },
+ "stash": {}
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index f5ce22798..37871d167 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,7 @@ These are the packages and their README.md files:
* [Amazon.Lambda.SNSEvents](Libraries/src/Amazon.Lambda.SNSEvents) - [README.md](Libraries/src/Amazon.Lambda.SNSEvents/README.md)
* [Amazon.Lambda.SQSEvents](Libraries/src/Amazon.Lambda.SQSEvents) - [README.md](Libraries/src/Amazon.Lambda.SQSEvents/README.md)
* [Amazon.Lambda.KafkaEvents](Libraries/src/Amazon.Lambda.KafkaEvents) - [README.md](Libraries/src/Amazon.Lambda.KafkaEvents/README.md)
+* [Amazon.Lambda.AppSyncEvents](Libraries/src/Amazon.Lambda.AppSyncEvents) - [README.md](Libraries/src/Amazon.Lambda.AppSyncEvents/README.md)
### Amazon.Lambda.Tools