Azure / Azure/azure-functions-host

Custom Trigger/Binding Serialization in Isolated worker

Open
#9,519 3 comments 0 reactions 0 assignees View on GitHub
Needs: Attention :wave:
Dominant language
C#
Stars
2k
Forks
482
Avg merge
2d 12h
Merged PRs (30d)
38

Description

This applies to v4 Isolated Worker Functions

Languages: C#

In our organization, we have developed a Custom Trigger/Output Bindings extension for one of the major message brokers that don't currently have support for Azure Functions out of the box, that allows us to use the functions to send/receive to their queues/topics. We have being using this extension successfully for the last couple of years.

One of the major features of the extension is to deserialize/serialize the payload base on custom types provided by the function's method signature. We currently support sending/receiving ```string```, ```byte[]``` and ```POCO``` classes. The extension provides JSON serialization by default, but it's replaceable by implementing an interface and registering the instance with DI. We have cases where serialization is AVRO, for example.

In the hosted model, everything works as expected, because the serializer that's registered with the custom trigger is in the same process, and has access to the runtime type specified by the function signature. In the Isolated model, this is not the case since the custom trigger would run on the host and the function signature would be on another process.
We would like for the custom trigger to support the Isolated model, but we've found no way to go forward with this, the trigger in the host only receives either a byte[] or a JSON serialized representation of the object.

For reference I'm including a pseudo-code snippet of how a function signature would look, the ```Message``` class is defined in the extension, ```CustomPoco``` is defined in the Isolated Functions project:

```
[Function("FunctionName")]
[CustomBindingOutput]
public Message MyFunctionName([CustomTrigger(Queue = "my-queue")] CustomPoco payload)
{
...
return new Message("destination-topic-or-queue", payload);
}
```

The extension uses whichever serializer is registered in the DI container with interfaces like this:
```
public interface IInputSerializer
{
T ReadObject(byte[] input);
}
```
and
```
public interface IOutputSerializer
{
byte[] WriteObject(T input);
}
```

That allows us to provide a default serializer but also let the consumer register their own if needed. We also access other properties of the ```Message``` class for headers, etc.

I would like to understand what would be the path forward to support this type of scenario for developing custom extensions, for either triggers and output bindings.

Contributor guide

Open the contributing guide

Research direction

Start by tracing the isolated-worker boundary described between CustomTrigger/CustomBindingOutput and the function signature, then review how IInputSerializer and IOutputSerializer are registered and invoked. The issue names no repository files or tests; done would require an agreed design for carrying custom type and serializer information across the host/worker boundary for trigger and output-binding scenarios.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, csharp
Domain
backend, cloud
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.