Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Text.Json Support for AWS Lambda SDK? #544

Closed
martincostello opened this issue Nov 14, 2019 · 4 comments
Closed

System.Text.Json Support for AWS Lambda SDK? #544

martincostello opened this issue Nov 14, 2019 · 4 comments
Labels
feature-request A feature should be added or improved.

Comments

@martincostello
Copy link
Contributor

As part of migrating some existing .NET Core 3.0 worker services running on EC2 to AWS Lambda, we've coded-up a custom ILambdaSerializer implementation to handle deserializing payloads to the Lambda function, such as SQSEvent.

While this is relatively simple to do, it would be nice if a serializer implementation for System.Text.Json was built into the Lambda SDK to save the need for copy-paste across different function codebases.

One shortcoming with the state-of-things as of today is that PropertyNameCaseInsensitive has to be set to true on the serializer options as the events don't use consistent PascalCase vs. camelCase naming, which incurs a performance penalty (I don't have a quantifier for how much the penalty is). In the case of SQSEvent I believe it's eventSourceARN that trips it up as it doesn't map over to EventSourceArn.

I imagine this could be easily fixed in the event libraries by adding [JsonPropertyName("...")] attribute annotations to the properties on the models.

I believe further benefit could be gained if there was asynchronous methods on the interface to leverage the async support of System.Text.Json.JsonSerializer and consume the Stream directly, but that's a bigger change that just providing an implementation based on the current interface.

Below is the code we're using. It might benefit from further optimization, but as it is right now it's working well for us:

using System.IO;
using System.Text.Json;
using Amazon.Lambda.Core;

namespace MyLambdaFunction
{
    public sealed class SystemTextJsonLambdaSerializer : ILambdaSerializer
    {
        private readonly JsonSerializerOptions _options;

        public SystemTextJsonLambdaSerializer()
        {
            // SQSEvent does not use a consistent camel/Pascal case naming convention,
            // so as we cannot annotate with attributes, the options need to be case
            // insensitive to be tolerant for things to work properly when deserializing.
            _options = new JsonSerializerOptions()
            {
                IgnoreNullValues = true,
                PropertyNameCaseInsensitive = true,
            };
        }

        public T Deserialize<T>(Stream requestStream)
        {
            using var copy = new MemoryStream();
            requestStream.CopyTo(copy);

            byte[] utf8Json = copy.ToArray();

            return JsonSerializer.Deserialize<T>(utf8Json, _options);
        }

        public void Serialize<T>(T response, Stream responseStream)
        {
            using var writer = new Utf8JsonWriter(responseStream);
            JsonSerializer.Serialize(writer, response, _options);
        }
    }
}

/cc @normj

@normj
Copy link
Member

normj commented Nov 14, 2019

Thanks @martincostello. I'm gonna move this to our Lambda .NET repo.

@normj normj transferred this issue from aws/aws-sdk-net Nov 14, 2019
@klaytaybai klaytaybai added the feature-request A feature should be added or improved. label Nov 14, 2019
@phillip-haydon
Copy link

Just a note, @martincostello that wont work for API Gateway.

PropertyNamingPolicy = JsonNamingPolicy.CamelCase

You need to add this too or the response will be considered malformed due to pascal casing on the properties.

@normj
Copy link
Member

normj commented Dec 20, 2019

Thanks @phillip-haydon that is helpful.

I have been working on official support for this in the system.text.json branch.

I'm working my way through the existing event tests to make sure the new serializer works the same as the Newtonsoft one. Its still very much a work in progress but feel free to take a look and provide feedback.

@normj
Copy link
Member

normj commented Jan 18, 2020

The PR for this has been created with a link to some preview builds of the NuGet packages for those that are currently trying out .NET Core 3.1 with the Lambda custom runtime feature. #568.

I'm going to close this issue and use the PR to track this feature going forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A feature should be added or improved.
Projects
None yet
Development

No branches or pull requests

4 participants