diff --git a/docs/sdk-reference/state/serialization.md b/docs/sdk-reference/state/serialization.md index 3c174ea..07dabca 100644 --- a/docs/sdk-reference/state/serialization.md +++ b/docs/sdk-reference/state/serialization.md @@ -99,8 +99,13 @@ Each SDK uses a default SerDes when you do not provide one. === "C#" - There is no per-operation default SerDes. Register a single `ILambdaSerializer` at the - host boundary and the SDK uses it for every durable operation result. + The default is the single `ILambdaSerializer` registered at the host boundary — the SDK + uses it for every durable operation result and for the handler's return value. An + optional per-operation override is available (see + [Custom SerDes on durable operations](#custom-serdes-on-durable-operations)): set + `Serializer` on `StepConfig`, `CallbackConfig`, `InvokeConfig`, + `WaitForConditionConfig`, or `ChildContextConfig` to use a different + `ILambdaSerializer` for that one operation. Use `DefaultLambdaJsonSerializer` (from `Amazon.Lambda.Serialization.SystemTextJson`) for reflection-based serialization. For AOT or trim-friendly functions, use @@ -163,8 +168,10 @@ Each SDK uses a default SerDes when you do not provide one. === "C#" - .NET has no per-operation SerDes interface. Serialization is controlled by the single - `ILambdaSerializer` registered on `ILambdaContext.Serializer`. + .NET has no separate per-operation SerDes interface — it reuses the standard + `ILambdaSerializer` contract. Serialization defaults to the single `ILambdaSerializer` + registered on `ILambdaContext.Serializer`, and an individual operation can override it + by setting `Serializer` (an `ILambdaSerializer`) on that operation's config. ```csharp --8<-- "examples/csharp/sdk-reference/serialization/SerdesInterface.cs" @@ -240,9 +247,10 @@ same handler continue to use the default. === "C#" - `StepConfig` does not expose a serializer. The step result is serialized with the - `ILambdaSerializer` registered at the host boundary. Register a custom - `ILambdaSerializer` there to change how step results are serialized. + Set `StepConfig.Serializer` to serialize this step's result with a specific + `ILambdaSerializer`. When it is `null` (default), the step result is serialized with the + `ILambdaSerializer` registered at the host boundary. Only this step is affected; other + operations and the handler's return value continue to use the registered serializer. ```csharp --8<-- "examples/csharp/sdk-reference/serialization/StepConfigExample.cs" @@ -276,9 +284,10 @@ system sends when it completes the callback. === "C#" - `CallbackConfig` does not expose a serializer. The payload the external system delivers - is deserialized with the `ILambdaSerializer` registered at the host boundary. Register a - custom `ILambdaSerializer` there to change how the callback payload is deserialized. + Set `CallbackConfig.Serializer` to deserialize the callback payload with a specific + `ILambdaSerializer`. When it is `null` (default), the payload the external system + delivers is deserialized with the `ILambdaSerializer` registered at the host boundary. + Only the deserialize path is used for callbacks. ```csharp --8<-- "examples/csharp/sdk-reference/serialization/CallbackConfigExample.cs" @@ -320,9 +329,12 @@ Map and parallel perations support two SerDes fields that apply at different lev === "C#" - `MapConfig` does not expose a serializer, and there is no separate item-level - serializer. Each item result is serialized with the `ILambdaSerializer` registered at - the host boundary. `ParallelConfig` likewise has no serializer field. + Set `MapConfig.ItemSerializer` (and `ParallelConfig.ItemSerializer`) to serialize + each item / branch **result** with a specific `ILambdaSerializer`. When `null` (default), + item results use the `ILambdaSerializer` registered at the host boundary. There is no + separate whole-result serializer: the aggregated batch envelope (per-item statuses and + completion reason) is an SDK-internal, source-generated structure and is not + user-serialized — only the per-item results are. ```csharp --8<-- "examples/csharp/sdk-reference/serialization/MapConfigExample.cs" diff --git a/examples/csharp/sdk-reference/serialization/CallbackConfigExample.cs b/examples/csharp/sdk-reference/serialization/CallbackConfigExample.cs index 4e0fcef..92e1f50 100644 --- a/examples/csharp/sdk-reference/serialization/CallbackConfigExample.cs +++ b/examples/csharp/sdk-reference/serialization/CallbackConfigExample.cs @@ -1,5 +1,6 @@ using Amazon.Lambda.Core; using Amazon.Lambda.DurableExecution; +using Amazon.Lambda.Serialization.SystemTextJson; public class CallbackConfigExample { @@ -9,13 +10,14 @@ public Task Handler( private async Task Workflow(object input, IDurableContext ctx) { - // CallbackConfig has no serializer slot. The callback payload delivered by - // the external system is deserialized with the ILambdaSerializer registered - // on ILambdaContext.Serializer. To customize deserialization, register a - // custom ILambdaSerializer at the host boundary. + // Set CallbackConfig.Serializer to deserialize the callback payload with a specific + // ILambdaSerializer. When null (default), the payload the external system delivers is + // deserialized with the ILambdaSerializer registered on ILambdaContext.Serializer. + // Only the deserialize path is used for callbacks. var config = new CallbackConfig { Timeout = TimeSpan.FromHours(1), + Serializer = new DefaultLambdaJsonSerializer(), }; ICallback callback = diff --git a/examples/csharp/sdk-reference/serialization/MapConfigExample.cs b/examples/csharp/sdk-reference/serialization/MapConfigExample.cs index 6f107ab..a7a93c2 100644 --- a/examples/csharp/sdk-reference/serialization/MapConfigExample.cs +++ b/examples/csharp/sdk-reference/serialization/MapConfigExample.cs @@ -1,5 +1,6 @@ using Amazon.Lambda.Core; using Amazon.Lambda.DurableExecution; +using Amazon.Lambda.Serialization.SystemTextJson; public class MapConfigExample { @@ -9,12 +10,15 @@ public Task Handler( private async Task> Workflow(object input, IDurableContext ctx) { - // MapConfig has no serializer slot. Each item result is serialized with the - // ILambdaSerializer registered on ILambdaContext.Serializer. To customize - // serialization, register a custom ILambdaSerializer at the host boundary. + // Set MapConfig.ItemSerializer to serialize each item's RESULT with a specific + // ILambdaSerializer. When null (default), item results are serialized with the + // ILambdaSerializer registered on ILambdaContext.Serializer. This controls only the + // per-item result — not the aggregated batch envelope (statuses / completion + // reason), which is SDK-internal. ParallelConfig has the same ItemSerializer field. var config = new MapConfig { MaxConcurrency = 3, + ItemSerializer = new CamelCaseLambdaJsonSerializer(), }; var items = new[] { "a", "b", "c" }; diff --git a/examples/csharp/sdk-reference/serialization/StepConfigExample.cs b/examples/csharp/sdk-reference/serialization/StepConfigExample.cs index 0f24bf0..b69f904 100644 --- a/examples/csharp/sdk-reference/serialization/StepConfigExample.cs +++ b/examples/csharp/sdk-reference/serialization/StepConfigExample.cs @@ -1,5 +1,6 @@ using Amazon.Lambda.Core; using Amazon.Lambda.DurableExecution; +using Amazon.Lambda.Serialization.SystemTextJson; public class StepConfigExample { @@ -9,13 +10,14 @@ public Task Handler( private async Task Workflow(object input, IDurableContext ctx) { - // StepConfig has no serializer slot. The step result is serialized with - // the ILambdaSerializer registered on ILambdaContext.Serializer. To - // customize serialization, register a custom ILambdaSerializer at the - // host boundary instead of setting a per-step SerDes. + // Set StepConfig.Serializer to serialize THIS step's result with a specific + // ILambdaSerializer. When null (default), the step result is serialized with the + // ILambdaSerializer registered on ILambdaContext.Serializer. Only this step is + // affected — other operations and the handler's return value are unchanged. var config = new StepConfig { RetryStrategy = RetryStrategy.Exponential(maxAttempts: 3), + Serializer = new CamelCaseLambdaJsonSerializer(), }; Order order = await ctx.StepAsync(