Aws-lambda-dotnet: Suporte de System.Text.Json para AWS Lambda SDK?

Criado em 14 nov. 2019  ·  4Comentários  ·  Fonte: aws/aws-lambda-dotnet

Como parte da migração de alguns serviços de trabalho do .NET Core 3.0 existentes em execução no EC2 para o AWS Lambda, codificamos uma implementação ILambdaSerializer personalizada para lidar com a desserialização de cargas úteis para a função Lambda, como SQSEvent .

Embora isso seja relativamente simples de fazer, seria bom se uma implementação de serializador para System.Text.Json fosse incorporada ao Lambda SDK para evitar a necessidade de copiar e colar em diferentes bases de código de função.

Uma falha com o estado das coisas a partir de hoje é que PropertyNameCaseInsensitive deve ser definido como true nas opções do serializador, pois os eventos não usam nomes consistentes de PascalCase vs. camelCase, que incorre em uma penalidade de desempenho (não tenho um quantificador de quanto é a penalidade). No caso de SQSEvent , acredito que é eventSourceARN que o engana, pois não mapeia para EventSourceArn .

Imagino que isso possa ser facilmente corrigido nas bibliotecas de eventos adicionando anotações de atributo [JsonPropertyName("...")] às propriedades dos modelos.

Acredito que mais benefícios poderiam ser obtidos se houvesse métodos assíncronos na interface para alavancar o suporte assíncrono de System.Text.Json.JsonSerializer e consumir o Stream diretamente, mas essa é uma mudança maior do que apenas fornecer uma implementação baseada em a interface atual.

Abaixo está o código que estamos usando. Pode se beneficiar de uma otimização adicional, mas, como está agora, está funcionando bem para nós:

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

feature-request

Comentários muito úteis

Obrigado @martincostello. Vou mover isso para nosso repositório Lambda .NET.

Todos 4 comentários

Obrigado @martincostello. Vou mover isso para nosso repositório Lambda .NET.

Apenas uma observação, @martincostello que não funcionará para o API Gateway.

PropertyNamingPolicy = JsonNamingPolicy.CamelCase

Você precisa adicionar isso também ou a resposta será considerada malformada devido à caixa pascal nas propriedades.

Obrigado @phillip-haydon que é útil.

Eu tenho trabalhado no suporte oficial para isso no branch system.text.json .

Estou trabalhando nos testes de eventos existentes para garantir que o novo serializador funcione da mesma forma que o Newtonsoft. Ainda é um trabalho em andamento, mas sinta-se à vontade para dar uma olhada e fornecer feedback.

O PR para isso foi criado com um link para algumas compilações de visualização dos pacotes NuGet para aqueles que estão testando o .NET Core 3.1 com o recurso de tempo de execução personalizado do Lambda. https://github.com/aws/aws-lambda-dotnet/pull/568.

Vou fechar este problema e usar o PR para rastrear esse recurso daqui para frente.

Esta página foi útil?
0 / 5 - 0 avaliações