Aws-lambda-dotnet: Dukungan System.Text.Json untuk AWS Lambda SDK?

Dibuat pada 14 Nov 2019  ·  4Komentar  ·  Sumber: aws/aws-lambda-dotnet

Sebagai bagian dari migrasi beberapa layanan pekerja .NET Core 3.0 yang berjalan di EC2 ke AWS Lambda, kami telah mengkodekan implementasi ILambdaSerializer khusus untuk menangani deserializing payload ke fungsi Lambda, seperti SQSEvent .

Meskipun ini relatif mudah dilakukan, alangkah baiknya jika implementasi serializer untuk System.Text.Json dibangun ke dalam Lambda SDK untuk menghemat kebutuhan copy-paste di berbagai basis kode fungsi.

Satu kekurangan dengan keadaan saat ini adalah bahwa PropertyNameCaseInsensitive harus disetel ke true pada opsi serializer karena peristiwa tidak menggunakan penamaan PascalCase vs. camelCase yang konsisten, yang menimbulkan penalti kinerja (saya tidak memiliki quantifier untuk berapa banyak penalti). Dalam kasus SQSEvent saya yakin eventSourceARN yang menyebabkannya naik karena tidak dipetakan ke EventSourceArn .

Saya membayangkan ini dapat dengan mudah diperbaiki di perpustakaan acara dengan menambahkan anotasi atribut [JsonPropertyName("...")] ke properti pada model.

Saya percaya manfaat lebih lanjut dapat diperoleh jika ada metode asinkron pada antarmuka untuk memanfaatkan dukungan async dari System.Text.Json.JsonSerializer dan mengkonsumsi Stream secara langsung, tetapi itu adalah perubahan yang lebih besar yang hanya menyediakan implementasi berdasarkan antarmuka saat ini.

Di bawah ini adalah kode yang kami gunakan. Ini mungkin mendapat manfaat dari pengoptimalan lebih lanjut, tetapi seperti saat ini, ini berfungsi dengan baik untuk kami:

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

Komentar yang paling membantu

Terima kasih @martincostello. Saya akan memindahkan ini ke repo Lambda .NET kami.

Semua 4 komentar

Terima kasih @martincostello. Saya akan memindahkan ini ke repo Lambda .NET kami.

Sekedar catatan, @martincostello yang tidak akan berfungsi untuk API Gateway.

PropertyNamingPolicy = JsonNamingPolicy.CamelCase

Anda perlu menambahkan ini juga atau respons akan dianggap salah format karena casing pascal pada properti.

Terima kasih @phillip-haydon yang sangat membantu.

Saya telah mengerjakan dukungan resmi untuk ini di cabang system.text.json .

Saya sedang mengerjakan tes acara yang ada untuk memastikan serializer baru berfungsi sama dengan yang Newtonsoft. Ini masih banyak pekerjaan yang sedang berjalan tetapi jangan ragu untuk melihat dan memberikan umpan balik.

PR untuk ini telah dibuat dengan tautan ke beberapa build pratinjau paket NuGet untuk mereka yang saat ini mencoba .NET Core 3.1 dengan fitur runtime kustom Lambda. https://github.com/aws/aws-lambda-dotnet/pull/568.

Saya akan menutup masalah ini dan menggunakan PR untuk melacak fitur ini ke depannya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat