Skip to content

Commit

Permalink
[Fusion] Added pre-merge validation rule "QueryRootTypeInaccessibleRule"
Browse files Browse the repository at this point in the history
  • Loading branch information
glen-84 committed Jan 1, 2025
1 parent 1a6811b commit a163802
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static class LogEntryCodes
public const string KeyInvalidSyntax = "KEY_INVALID_SYNTAX";
public const string OutputFieldTypesNotMergeable = "OUTPUT_FIELD_TYPES_NOT_MERGEABLE";
public const string ProvidesDirectiveInFieldsArg = "PROVIDES_DIRECTIVE_IN_FIELDS_ARG";
public const string QueryRootTypeInaccessible = "QUERY_ROOT_TYPE_INACCESSIBLE";
public const string RootMutationUsed = "ROOT_MUTATION_USED";
public const string RootQueryUsed = "ROOT_QUERY_USED";
public const string RootSubscriptionUsed = "ROOT_SUBSCRIPTION_USED";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,19 @@ public static LogEntry ProvidesDirectiveInFieldsArgument(
schema);
}

public static LogEntry QueryRootTypeInaccessible(
INamedTypeDefinition type,
SchemaDefinition schema)
{
return new LogEntry(
string.Format(LogEntryHelper_QueryRootTypeInaccessible, schema.Name),
LogEntryCodes.QueryRootTypeInaccessible,
LogSeverity.Error,
new SchemaCoordinate(type.Name),
type,
schema);
}

public static LogEntry RootMutationUsed(SchemaDefinition schema)
{
return new LogEntry(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using HotChocolate.Fusion.Events;
using static HotChocolate.Fusion.Logging.LogEntryHelper;

namespace HotChocolate.Fusion.PreMergeValidation.Rules;

/// <summary>
/// Every source schema that contributes to the final composite schema must expose a public
/// (accessible) root query type. Marking the root query type as <c>@inaccessible</c> makes it
/// invisible to the gateway, defeating its purpose as the primary entry point for queries and
/// lookups.
/// </summary>
/// <seealso href="https://graphql.github.io/composite-schemas-spec/draft/#sec-Query-Root-Type-Inaccessible">
/// Specification
/// </seealso>
internal sealed class QueryRootTypeInaccessibleRule : IEventHandler<SchemaEvent>
{
public void Handle(SchemaEvent @event, CompositionContext context)
{
var schema = @event.Schema;
var rootQuery = schema.QueryType;

if (rootQuery is not null && !ValidationHelper.IsAccessible(rootQuery))
{
context.Log.Write(QueryRootTypeInaccessible(rootQuery, schema));
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
<data name="LogEntryHelper_ProvidesDirectiveInFieldsArgument" xml:space="preserve">
<value>The @provides directive on field '{0}' in schema '{1}' references field '{2}', which must not include directive applications.</value>
</data>
<data name="LogEntryHelper_QueryRootTypeInaccessible" xml:space="preserve">
<value>The root query type in schema '{0}' must be accessible.</value>
</data>
<data name="LogEntryHelper_RootMutationUsed" xml:space="preserve">
<value>The root mutation type in schema '{0}' must be named 'Mutation'.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ private CompositionResult<SchemaDefinition> MergeSchemaDefinitions(CompositionCo
new KeyInvalidSyntaxRule(),
new OutputFieldTypesMergeableRule(),
new ProvidesDirectiveInFieldsArgumentRule(),
new QueryRootTypeInaccessibleRule(),
new RootMutationUsedRule(),
new RootQueryUsedRule(),
new RootSubscriptionUsedRule()
Expand Down
Loading

0 comments on commit a163802

Please sign in to comment.