Skip to content

Commit

Permalink
Added support for middleware on introspection fields (#962)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored Aug 6, 2019
1 parent 89b0a5d commit eb3ddf1
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 4 deletions.
32 changes: 32 additions & 0 deletions src/Core/Core.Tests/Execution/IntrospectionTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Threading.Tasks;
using ChilliCream.Testing;
using HotChocolate.Configuration;
using HotChocolate.Types;
using Snapshooter.Xunit;
using Xunit;
Expand Down Expand Up @@ -117,6 +118,37 @@ public async Task FieldMiddlewareDoesNotHaveAnEffectOnIntrospection()
result.MatchSnapshot();
}

[Fact]
public async Task FieldMiddlewareHasAnEffectOnIntrospectIfSwitchedOn()
{
// arrange
string query = "{ __typename a }";

ISchema schema = SchemaBuilder.New()
.AddQueryType<Query>()
.Use(next => async context =>
{
await next.Invoke(context);
if (context.Result is string s)
{
context.Result = s.ToUpperInvariant();
}
})
.ModifyOptions(o =>
o.FieldMiddleware = FieldMiddlewareApplication.AllFields)
.Create();

IQueryExecutor executor = schema.MakeExecutable();

// act
IExecutionResult result = await executor.ExecuteAsync(query);

// assert
Assert.Empty(result.Errors);
result.MatchSnapshot();
}

[Fact]
public async Task DirectiveMiddlewareDoesWorkOnIntrospection()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Data": {
"__typename": "QUERY",
"a": "A"
},
"Extensions": {},
"Errors": [],
"ContextData": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace HotChocolate.Configuration
{
/// <summary>
/// This enum specified on which fields custom field
/// middleware is applied to.
/// </summary>
public enum FieldMiddlewareApplication : byte
{
/// <summary>
/// Custom field middleware is only applied to
/// user-defined fields and not to introspection fields.
/// </summary>
UserDefinedFields = 0,

/// <summary>
/// Custom field middleware is applied to all fields
/// (user-defined fields and introspection fields).
/// </summary>
AllFields = 1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,10 @@ public interface IReadOnlySchemaOptions
bool StrictValidation { get; }

bool UseXmlDocumentation { get; }

/// <summary>
/// Defines on which fields a middleware pipeline can be applied on.
/// </summary>
FieldMiddlewareApplication FieldMiddleware { get; }
}
}
2 changes: 2 additions & 0 deletions src/Core/Types/Configuration/Contracts/ISchemaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ public interface ISchemaOptions
new bool StrictValidation { get; set; }

new bool UseXmlDocumentation { get; set; }

new FieldMiddlewareApplication FieldMiddleware { get; set; }
}
}
3 changes: 3 additions & 0 deletions src/Core/Types/Configuration/ReadOnlySchemaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public ReadOnlySchemaOptions(IReadOnlySchemaOptions options)
?? "Subscription";
StrictValidation = options.StrictValidation;
UseXmlDocumentation = options.UseXmlDocumentation;
FieldMiddleware = options.FieldMiddleware;
}

public string QueryTypeName { get; }
Expand All @@ -31,5 +32,7 @@ public ReadOnlySchemaOptions(IReadOnlySchemaOptions options)
public bool StrictValidation { get; }

public bool UseXmlDocumentation { get; }

public FieldMiddlewareApplication FieldMiddleware { get; }
}
}
9 changes: 8 additions & 1 deletion src/Core/Types/Configuration/SchemaOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ public class SchemaOptions

public bool UseXmlDocumentation { get; set; } = true;

public FieldMiddlewareApplication FieldMiddleware
{
get;
set;
} = FieldMiddlewareApplication.UserDefinedFields;

public static SchemaOptions FromOptions(IReadOnlySchemaOptions options)
{
return new SchemaOptions
Expand All @@ -21,7 +27,8 @@ public static SchemaOptions FromOptions(IReadOnlySchemaOptions options)
MutationTypeName = options.MutationTypeName,
SubscriptionTypeName = options.SubscriptionTypeName,
StrictValidation = options.StrictValidation,
UseXmlDocumentation = options.UseXmlDocumentation
UseXmlDocumentation = options.UseXmlDocumentation,
FieldMiddleware = options.FieldMiddleware
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Core/Types/Types/Helpers/FieldMiddlewareCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static FieldDelegate Compile(
IReadOnlyList<FieldMiddleware> globalComponents,
IReadOnlyList<FieldMiddleware> fieldComponents,
FieldResolverDelegate fieldResolver,
bool isIntrospection)
bool skipMiddleware)
{
if (globalComponents == null)
{
Expand All @@ -23,7 +23,7 @@ public static FieldDelegate Compile(
throw new ArgumentNullException(nameof(fieldComponents));
}

if (isIntrospection
if (skipMiddleware
|| (globalComponents.Count == 0
&& fieldComponents.Count == 0))
{
Expand Down
9 changes: 8 additions & 1 deletion src/Core/Types/Types/ObjectField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,18 @@ private void CompleteResolver(
context.Type.Name, Resolver, resolver);
}

IReadOnlySchemaOptions options = context.DescriptorContext.Options;

bool skipMiddleware =
options.FieldMiddleware == FieldMiddlewareApplication.AllFields
? false
: isIntrospectionField;

Middleware = FieldMiddlewareCompiler.Compile(
context.GlobalComponents,
definition.MiddlewareComponents.ToArray(),
Resolver,
isIntrospectionField);
skipMiddleware);

if (Resolver == null && Middleware == null)
{
Expand Down

0 comments on commit eb3ddf1

Please sign in to comment.