Aws-lambda-dotnet: Prise en charge de System.Text.Json pour le SDK AWS Lambda ?

Créé le 14 nov. 2019  ·  4Commentaires  ·  Source: aws/aws-lambda-dotnet

Dans le cadre de la migration de certains services de travail .NET Core 3.0 existants exécutés sur EC2 vers AWS Lambda, nous avons codé une implémentation personnalisée ILambdaSerializer pour gérer les charges utiles de désérialisation vers la fonction Lambda, telles que SQSEvent .

Bien que cela soit relativement simple à faire, il serait bien qu'une implémentation de sérialiseur pour System.Text.Json soit intégrée au SDK Lambda pour éviter d'avoir à copier-coller sur différentes bases de code de fonction.

L'un des inconvénients de l'état actuel des choses est que PropertyNameCaseInsensitive doit être défini sur true dans les options du sérialiseur, car les événements n'utilisent pas une dénomination cohérente PascalCase par rapport à camelCase, ce qui encourt une pénalité de performance (je n'ai pas de quantificateur pour combien la pénalité est). Dans le cas de SQSEvent , je crois que c'est eventSourceARN qui le déclenche car il ne correspond pas à EventSourceArn .

J'imagine que cela pourrait être facilement corrigé dans les bibliothèques d'événements en ajoutant des annotations d'attribut [JsonPropertyName("...")] aux propriétés des modèles.

Je pense que d'autres avantages pourraient être obtenus s'il y avait des méthodes asynchrones sur l'interface pour tirer parti du support asynchrone de System.Text.Json.JsonSerializer et consommer directement les Stream , mais c'est un changement plus important qui fournit simplement une implémentation basée sur l'interface actuelle.

Ci-dessous le code que nous utilisons. Il pourrait bénéficier d'une optimisation supplémentaire, mais tel qu'il est actuellement, il fonctionne bien pour nous :

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

Commentaire le plus utile

Merci @martincostello. Je vais déplacer cela vers notre référentiel Lambda .NET.

Tous les 4 commentaires

Merci @martincostello. Je vais déplacer cela vers notre référentiel Lambda .NET.

Juste une note, @martincostello qui ne fonctionnera pas pour API Gateway.

PropertyNamingPolicy = JsonNamingPolicy.CamelCase

Vous devez également l'ajouter ou la réponse sera considérée comme malformée en raison de la casse pascal sur les propriétés.

Merci @phillip-haydon qui est utile.

J'ai travaillé sur le support officiel pour cela dans la branche system.text.json .

Je travaille sur les tests d'événements existants pour m'assurer que le nouveau sérialiseur fonctionne de la même manière que celui de Newtonsoft. C'est encore un travail en cours, mais n'hésitez pas à jeter un coup d'œil et à donner votre avis.

Le PR pour cela a été créé avec un lien vers certaines versions d'aperçu des packages NuGet pour ceux qui testent actuellement .NET Core 3.1 avec la fonctionnalité d'exécution personnalisée Lambda. https://github.com/aws/aws-lambda-dotnet/pull/568.

Je vais fermer ce problème et utiliser le PR pour suivre cette fonctionnalité à l'avenir.

Cette page vous a été utile?
0 / 5 - 0 notes