Skip to content

Commit

Permalink
Payload now uses the GraphQLName of the result as field name (ChilliC…
Browse files Browse the repository at this point in the history
  • Loading branch information
PascalSenn authored Nov 30, 2021
1 parent 660d650 commit ee272f7
Show file tree
Hide file tree
Showing 11 changed files with 355 additions and 51 deletions.
29 changes: 14 additions & 15 deletions src/HotChocolate/Core/HotChocolate.Core.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29721.120
Expand Down Expand Up @@ -99,7 +98,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types.Mutation
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types.Mutations.Tests", "test\Types.Mutations.Tests\HotChocolate.Types.Mutations.Tests.csproj", "{F6FFA925-8C49-4594-9FF2-8F571C2D6389}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types", "src\Types\HotChocolate.Types.csproj", "{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types", "src\Types\HotChocolate.Types.csproj", "{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -627,18 +626,18 @@ Global
{F6FFA925-8C49-4594-9FF2-8F571C2D6389}.Release|x64.Build.0 = Release|Any CPU
{F6FFA925-8C49-4594-9FF2-8F571C2D6389}.Release|x86.ActiveCfg = Release|Any CPU
{F6FFA925-8C49-4594-9FF2-8F571C2D6389}.Release|x86.Build.0 = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x64.ActiveCfg = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x64.Build.0 = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x86.ActiveCfg = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x86.Build.0 = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|Any CPU.Build.0 = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x64.ActiveCfg = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x64.Build.0 = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x86.ActiveCfg = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x86.Build.0 = Release|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Debug|Any CPU.Build.0 = Debug|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Debug|x64.ActiveCfg = Debug|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Debug|x64.Build.0 = Debug|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Debug|x86.ActiveCfg = Debug|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Debug|x86.Build.0 = Debug|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Release|Any CPU.ActiveCfg = Release|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Release|Any CPU.Build.0 = Release|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Release|x64.ActiveCfg = Release|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Release|x64.Build.0 = Release|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Release|x86.ActiveCfg = Release|Any CPU
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -687,7 +686,7 @@ Global
{4AD904D1-7727-48EF-88D9-7B38D98EB314} = {7637D30E-7339-4D4E-9424-87CF2394D234}
{2B7E7416-E093-4763-B839-504CBFBC8F1C} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{F6FFA925-8C49-4594-9FF2-8F571C2D6389} = {7462D089-D350-44D6-8131-896D949A65B7}
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{151FB103-4BCA-41D2-9C8E-C5BDA7A68320} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E4D94C77-6657-4630-9D42-0A9AC5153A1B}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System.Reflection;
using HotChocolate.Types.Descriptors;

#nullable enable

namespace HotChocolate.Types;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System.Threading.Tasks;
using HotChocolate.Resolvers;

#nullable enable

namespace HotChocolate.Types;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using HotChocolate.Configuration;
using HotChocolate.Resolvers;
using HotChocolate.Types.Descriptors;
Expand All @@ -20,45 +21,60 @@ public override void OnBeforeRegisterDependencies(
return;
}

foreach (var field in def.Fields)
foreach (ObjectFieldDefinition? field in def.Fields)
{
if (field.ContextData.TryGetValue(PayloadContextData.Payload, out var contextObj) &&
contextObj is PayloadContextData context &&
field.Type is { })
if (!(field.ContextData.TryGetValue(PayloadContextData.Payload, out var contextObj) &&
contextObj is PayloadContextData context &&
field.Type is { }))
{
string name =
context.FieldName ??
field.ResultType?.Name.ToFieldName() ??
"payload";
continue;
}

ITypeReference? fieldType = field.Type;

FieldMiddlewareDefinition middlewareDefinition =
new(FieldClassMiddlewareFactory.Create<PayloadMiddleware>(),
false,
PayloadMiddleware.MiddlewareIdentifier);

field.MiddlewareDefinitions.Insert(0, middlewareDefinition);

ITypeReference? fieldType = field.Type;
NameString typeName =
context.TypeName ?? field.Name.ToTypeName(suffix: "Payload");

FieldMiddlewareDefinition middlewareDefinition =
new(FieldClassMiddlewareFactory.Create<PayloadMiddleware>(),
false,
PayloadMiddleware.MiddlewareIdentifier);
field.Type = new DependantFactoryTypeReference(
typeName,
fieldType,
CreateType,
TypeContext.Output);

field.MiddlewareDefinitions.Insert(0, middlewareDefinition);
TypeSystemObjectBase CreateType(IDescriptorContext descriptorContext) =>
new ObjectType<Payload>(descriptor =>
{
descriptor.Name(typeName);

NameString typeName = context.TypeName ?? field.Name.ToTypeName(suffix: "Payload");
const string placeholder = "payload";

field.Type = new DependantFactoryTypeReference(
typeName,
fieldType,
CreateType,
TypeContext.Output);
IObjectFieldDescriptor resultField =
descriptor.Field(x => x.Result).Name(placeholder);

TypeSystemObjectBase CreateType(IDescriptorContext descriptorContext) =>
new ObjectType<Payload>(descriptor =>
resultField.Extend().OnBeforeCreate(x => x.Type = fieldType);
resultField.Extend().OnBeforeNaming(OnBeforeNaming);

void OnBeforeNaming(
ITypeCompletionContext ctx,
ObjectFieldDefinition fieldDefinition)
{
descriptor.Name(typeName);
descriptor
.Field(x => x.Result)
.Name(name)
.Extend()
.Definition.Type = fieldType;
});
}
if (context.FieldName is not null)
{
fieldDefinition.Name = context.FieldName;
return;
}

IType type = ctx.GetType<IType>(fieldType);
fieldDefinition.Name = type.NamedType().Name.Value.ToFieldName();
}
});
}
}
}
150 changes: 150 additions & 0 deletions src/HotChocolate/Core/test/Types.Mutations.Tests/PayloadTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,115 @@ public async Task PayloadAttribute_Should_UserResultTypeForField_When_NoFieldNam
executor.Schema.Print().MatchSnapshot();
}

[Fact]
public async Task PayloadMiddleware_Should_TransformPayload_When_ItIsATask()
{
// Arrange
IRequestExecutor executor =
await new ServiceCollection()
.AddGraphQL()
.AddQueryType<Query>()
.AddMutationType<MutationTask>()
.EnableMutationConvention()
.BuildRequestExecutorAsync();

// Act
IExecutionResult res = await executor
.ExecuteAsync(@"
mutation {
createTask {
foo {
bar
}
}
createValueTask {
foo {
bar
}
}
createTaskNoName {
foo {
bar
}
}
createValueTaskNoName {
foo {
bar
}
}
}
");

// Assert
res.ToJson().MatchSnapshot();
SnapshotFullName fullName = Snapshot.FullName();
SnapshotFullName snapshotName = new(fullName.Filename + "_schema", fullName.FolderPath);
executor.Schema.Print().MatchSnapshot(snapshotName);
}

[Fact]
public async Task PayloadMiddleware_Should_TransformPayload_When_ItIsNullable()
{
// Arrange
IRequestExecutor executor =
await new ServiceCollection()
.AddGraphQL()
.AddQueryType<Query>()
.AddMutationType<MutationNullable>()
.EnableMutationConvention()
.BuildRequestExecutorAsync();

// Act
IExecutionResult res = await executor
.ExecuteAsync(@"
mutation {
nullableNumber {
foo
}
nullableNumberNoName {
int
}
}
");

// Assert
res.ToJson().MatchSnapshot();
SnapshotFullName fullName = Snapshot.FullName();
SnapshotFullName snapshotName = new(fullName.Filename + "_schema", fullName.FolderPath);
executor.Schema.Print().MatchSnapshot(snapshotName);
}

[Fact]
public async Task PayloadMiddleware_Should_TransformPayload_When_ObjectIsNamed()
{
// Arrange
IRequestExecutor executor =
await new ServiceCollection()
.AddGraphQL()
.AddQueryType<Query>()
.AddMutationType<MutationRenamed>()
.EnableMutationConvention()
.BuildRequestExecutorAsync();

// Act
IExecutionResult res = await executor
.ExecuteAsync(@"
mutation {
createBaz {
baz {
bar
}
}
}
");

// Assert
res.ToJson().MatchSnapshot();
SnapshotFullName fullName = Snapshot.FullName();
SnapshotFullName snapshotName = new(fullName.Filename + "_schema", fullName.FolderPath);
executor.Schema.Print().MatchSnapshot(snapshotName);
}

public class Foo
{
public Foo(string bar)
Expand All @@ -123,6 +232,23 @@ public Foo(string bar)
public string Bar { get; set; }
}

public class MutationRenamed
{
[Payload]
public BazDto CreateBaz() => new BazDto("Bar");
}

[GraphQLName("Baz")]
public class BazDto
{
public BazDto(string bar)
{
Bar = bar;
}

public string Bar { get; set; }
}

public class Query
{
public Foo GetFoo() => new Foo("Bar");
Expand All @@ -145,4 +271,28 @@ public class Mutation
[Payload("foo")]
public Foo CreateFoo() => new Foo("Bar");
}

public class MutationTask
{
[Payload("foo")]
public Task<Foo> CreateTask() => Task.FromResult(new Foo("Bar"));

[Payload("foo")]
public ValueTask<Foo> CreateValueTask() => new(new Foo("Bar"));

[Payload]
public Task<Foo> CreateTaskNoName() => Task.FromResult(new Foo("Bar"));

[Payload]
public ValueTask<Foo> CreateValueTaskNoName() => new(new Foo("Bar"));
}

public class MutationNullable
{
[Payload("foo")]
public int? NullableNumber() => null;

[Payload]
public int? NullableNumberNoName() => null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"data": {
"createTask": {
"foo": {
"bar": "Bar"
}
},
"createValueTask": {
"foo": {
"bar": "Bar"
}
},
"createTaskNoName": {
"foo": {
"bar": "Bar"
}
},
"createValueTaskNoName": {
"foo": {
"bar": "Bar"
}
}
}
}
Loading

0 comments on commit ee272f7

Please sign in to comment.