Skip to content

Commit a5c1cb1

Browse files
Allow to incrementally adopt new ID format in distributed system (#7343)
1 parent 5ca1d87 commit a5c1cb1

File tree

6 files changed

+57
-8
lines changed

6 files changed

+57
-8
lines changed

src/HotChocolate/Core/src/Execution/DependencyInjection/RequestExecutorBuilderExtensions.IdSerializer.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public static partial class RequestExecutorBuilderExtensions
1818
/// <param name="maxIdLength">
1919
/// The maximum allowed length of a node id.
2020
/// </param>
21+
/// <param name="outputNewIdFormat">
22+
/// Whether the new ID format shall be used when serializing IDs.
23+
/// </param>
2124
/// <returns>
2225
/// Returns the request executor builder.
2326
/// </returns>
@@ -26,7 +29,8 @@ public static partial class RequestExecutorBuilderExtensions
2629
/// </exception>
2730
public static IRequestExecutorBuilder AddDefaultNodeIdSerializer(
2831
this IRequestExecutorBuilder builder,
29-
int maxIdLength = 1024)
32+
int maxIdLength = 1024,
33+
bool outputNewIdFormat = true)
3034
{
3135
if (builder == null)
3236
{
@@ -47,7 +51,7 @@ public static IRequestExecutorBuilder AddDefaultNodeIdSerializer(
4751
builder.Services.TryAddSingleton<INodeIdSerializer>(sp =>
4852
{
4953
var allSerializers = sp.GetServices<INodeIdValueSerializer>().ToArray();
50-
return new DefaultNodeIdSerializer(allSerializers, maxIdLength);
54+
return new DefaultNodeIdSerializer(allSerializers, maxIdLength, outputNewIdFormat);
5155
});
5256

5357
builder.ConfigureSchemaServices(
@@ -76,7 +80,7 @@ public static IRequestExecutorBuilder AddDefaultNodeIdSerializer(
7680
}
7781
}
7882

79-
return new OptimizedNodeIdSerializer(boundSerializers, allSerializers, maxIdLength);
83+
return new OptimizedNodeIdSerializer(boundSerializers, allSerializers, maxIdLength, outputNewIdFormat);
8084
});
8185
});
8286
return builder;

src/HotChocolate/Core/src/Types/Types/Relay/Serialization/DefaultNodeIdSerializer.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ namespace HotChocolate.Types.Relay;
1111

1212
public sealed class DefaultNodeIdSerializer(
1313
INodeIdValueSerializer[]? serializers = null,
14-
int maxIdLength = 1024)
14+
int maxIdLength = 1024,
15+
bool outputNewIdFormat = true)
1516
: INodeIdSerializer
1617
{
1718
private const byte _delimiter = (byte)':';
@@ -42,6 +43,11 @@ public string Format(string typeName, object internalId)
4243
throw new ArgumentNullException(nameof(internalId));
4344
}
4445

46+
if (!outputNewIdFormat)
47+
{
48+
return LegacyNodeIdSerializer.FormatInternal(typeName, internalId);
49+
}
50+
4551
var runtimeType = internalId.GetType();
4652
var serializer = TryResolveSerializer(runtimeType);
4753

src/HotChocolate/Core/src/Types/Types/Relay/Serialization/LegacyNodeIdSerializer.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ internal sealed class LegacyNodeIdSerializer : INodeIdSerializer
2121
private static readonly Encoding _utf8 = Encoding.UTF8;
2222

2323
public string Format(string typeName, object internalId)
24+
=> FormatInternal(typeName, internalId);
25+
26+
internal static string FormatInternal(string typeName, object internalId)
2427
{
2528
if (string.IsNullOrEmpty(typeName))
2629
{
@@ -186,7 +189,7 @@ private static NodeId Parse(string formattedId)
186189
}
187190
}
188191

189-
internal static object ParseValueInternal(ReadOnlySpan<byte> formattedId)
192+
private static object ParseValueInternal(ReadOnlySpan<byte> formattedId)
190193
{
191194
object value;
192195

src/HotChocolate/Core/src/Types/Types/Relay/Serialization/OptimizedNodeIdSerializer.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ internal sealed class OptimizedNodeIdSerializer : INodeIdSerializer
2727
private readonly SpanSerializerMap _spanSerializerMap;
2828
private readonly INodeIdValueSerializer[] _serializers;
2929
private readonly int _maxIdLength;
30+
private readonly bool _outputNewIdFormat;
3031

3132
internal OptimizedNodeIdSerializer(
3233
IEnumerable<BoundNodeIdValueSerializer> boundSerializers,
3334
INodeIdValueSerializer[] allSerializers,
34-
int maxIdLength = 1024)
35+
int maxIdLength = 1024,
36+
bool outputNewIdFormat = true)
3537
{
3638
#if NET8_0_OR_GREATER
3739
_stringSerializerMap =
@@ -48,20 +50,28 @@ internal OptimizedNodeIdSerializer(
4850
}
4951

5052
_maxIdLength = maxIdLength;
53+
_outputNewIdFormat = outputNewIdFormat;
5154
}
5255

5356
public string Format(string typeName, object internalId)
5457
{
55-
if (typeName is null)
58+
if (string.IsNullOrEmpty(typeName))
5659
{
57-
throw new ArgumentNullException(nameof(typeName));
60+
throw new ArgumentException(
61+
"Value cannot be null or empty.",
62+
nameof(typeName));
5863
}
5964

6065
if (internalId is null)
6166
{
6267
throw new ArgumentNullException(nameof(internalId));
6368
}
6469

70+
if (!_outputNewIdFormat)
71+
{
72+
return LegacyNodeIdSerializer.FormatInternal(typeName, internalId);
73+
}
74+
6575
if (!_stringSerializerMap.TryGetValue(typeName, out var serializer))
6676
{
6777
throw new NodeIdMissingSerializerException(typeName);

src/HotChocolate/Core/test/Types.Tests/Types/Relay/DefaultNodeIdSerializerTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ public void Format_Small_StringId()
2727
Assert.Equal("Rm9vOmFiYw==", id);
2828
}
2929

30+
[Fact]
31+
public void Format_Small_StringId_Without_Outputting_New_Format()
32+
{
33+
var serializer = new DefaultNodeIdSerializer(
34+
serializers: [new StringNodeIdValueSerializer()],
35+
outputNewIdFormat: false);
36+
37+
var id = serializer.Format("Foo", "abc");
38+
39+
Assert.Equal("Rm9vCmRhYmM=", id);
40+
}
41+
3042
[Fact]
3143
public void Parse_Small_StringId()
3244
{

src/HotChocolate/Core/test/Types.Tests/Types/Relay/OptimizedNodeIdSerializerTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ public void Format_Small_StringId()
2626
Assert.Equal("Rm9vOmFiYw==", id);
2727
}
2828

29+
[Fact]
30+
public void Format_Small_StringId_Without_Outputting_New_Format()
31+
{
32+
var stringSerializer = new StringNodeIdValueSerializer();
33+
var serializer = new OptimizedNodeIdSerializer(
34+
[new BoundNodeIdValueSerializer("Foo", stringSerializer)],
35+
[stringSerializer],
36+
outputNewIdFormat: false);
37+
38+
var id = serializer.Format("Foo", "abc");
39+
40+
Assert.Equal("Rm9vCmRhYmM=", id);
41+
}
42+
2943
[Fact]
3044
public void Parse_Small_StringId()
3145
{

0 commit comments

Comments
 (0)