Proposed change
Provide the NatsHeaders to the Deserialize method.
public interface INatsDeserialize<out T>
{
T? Deserialize(in ReadOnlySequence<byte> buffer, NatsHeaders? headers);
}
Provide the ability for the Serialize to provide the headers for the serialized payload.
public interface INatsSerialize<in T>
{
void Serialize(IBufferWriter<byte> bufferWriter, T value, out NatsHeaders? headers);
}
Use case
- If an endpoint wants to handle $SYS.REQ.USER.AUTH request messages that have encrypted contents, you need access to the headers to correctly deserialize to a NatsAuthorizationRequestClaims.
- A consumer might need access to a header to understand the version of a message, encoding, etc.
The current INatsDeserialize interface only gives you the payload bytes, and so there is no way (that i can see) to implement a clean message handler when you need header information for deserializing.
This would improve the code readability and maintainability, and allow it to be implemented like other "simple" messages.
Because currently the code for $SYS.REQ.USER.AUTH would have to do:
await _svcServer.AddEndpointAsync<byte[]>(HandleMessage, subject: "$SYS.REQ.USER.AUTH");
async ValueTask HandleMessage(NatsSvcMsg<byte[]> message)
{
var request = DecodeMessage(message);
/// handle request
}
NatsAuthorizationRequest DecodeMessage(NatsSvcMsg<byte[]> message)
{
string jwt;
if (message.Headers.TryGetValue("Nats-Server-Xkey", out var serverKey))
{
var encryptionKeyPair = FindEncryptionKey(serverKey);
var decrypted = encryptionKeyPair.Open(message.Data);
jwt = Encoding.ASCII.GetString(decrypted);
}
else
{
jwt = Encoding.ASCII.GetString(message.Data);
}
var arc = NatsJwt.DecodeClaims<NatsAuthorizationRequestClaims>(jwt);
return arc.AuthorizationRequest;
}
If the headers were available, it would allow for Serialization/Deserialization to be handled the same way other "simple" messages are.
await _svcServer.AddEndpointAsync<NatsAuthorizationRequest>(HandleMessage, subject: "$SYS.REQ.USER.AUTH", serializer: new NatsAuthorizationRequestDeserializer());
async ValueTask HandleMessage(NatsSvcMsg<NatsAuthorizationRequest> message)
{
var request = message.Data;
//handle request
}
class NatsAuthorizationRequestDeserializer: INatsDeserialize<NatsAuthorizationRequest>
{
public T? Deserialize(in ReadOnlySequence<byte> buffer, NatsHeaders? headers)
{
string jwt;
if (headers.TryGetValue("Nats-Server-Xkey", out var serverKey))
{
var encryptionKeyPair = FindEncryptionKey(serverKey);
var decrypted = encryptionKeyPair.Open(buffer);
jwt = Encoding.ASCII.GetString(decrypted);
}
else
{
jwt = Encoding.ASCII.GetString(buffer);
}
var arc = NatsJwt.DecodeClaims<NatsAuthorizationRequestClaims>(jwt);
return arc.AuthorizationRequest;
}
}
Contribution
No response
Proposed change
Provide the NatsHeaders to the Deserialize method.
Provide the ability for the Serialize to provide the headers for the serialized payload.
Use case
The current INatsDeserialize interface only gives you the payload bytes, and so there is no way (that i can see) to implement a clean message handler when you need header information for deserializing.
This would improve the code readability and maintainability, and allow it to be implemented like other "simple" messages.
Because currently the code for $SYS.REQ.USER.AUTH would have to do:
If the headers were available, it would allow for Serialization/Deserialization to be handled the same way other "simple" messages are.
Contribution
No response