Removes any fields that look to be internal based on presence of "dbId" in field name or arg.
services.
.AddGraphQLServer()
.AddTypeRewriter(new RemoveInternalFieldsRewriter())
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using HotChocolate.Language; | |
using HotChocolate.Stitching.Merge; | |
using HotChocolate.Stitching.Merge.Rewriters; | |
using HotChocolate.Types; | |
namespace MyCompany.GraphQLService.Stitching | |
{ | |
internal class RemoveInternalFieldsRewriter : ITypeRewriter | |
{ | |
public ITypeDefinitionNode Rewrite(ISchemaInfo schema, ITypeDefinitionNode typeDefinition) | |
{ | |
if (schema.Name.HasValue && | |
typeDefinition is ObjectTypeDefinitionNode otd) | |
{ | |
if (typeDefinition.Name.Value.Equals(GraphQLTypeNames.Query)) | |
{ | |
return RemoveFields(schema.Name, otd, _isInternalQueryTypeField, f => otd.WithFields(f)); | |
} | |
} | |
return typeDefinition; | |
} | |
/// <summary> | |
/// Essentially any field that accepts an argument that's an internal database id | |
/// can be considered an internal field. This way the field name doesn't matter | |
/// too much but we can still blanket notice them. | |
/// </summary> | |
private static readonly Func<string, FieldDefinitionNode, bool> _isInternalQueryTypeField = (schemaName, field) => | |
field.Arguments.Any(arg => | |
arg.Name.Value.EndsWith("DbId", StringComparison.Ordinal) || | |
arg.Name.Value.EndsWith("DbIds", StringComparison.Ordinal) || | |
arg.Name.Value.Equals("dbId", StringComparison.Ordinal) || | |
arg.Name.Value.Equals("dbIds", StringComparison.Ordinal) | |
) || | |
field.Name.Value.Equals("brandByName") || | |
(schemaName.StartsWith(SchemaNames.MyCompanyPrefix) && field.Name.Value.Equals("checksum")) || | |
(schemaName.StartsWith(SchemaNames.MyCompanyPrefix) && field.Name.Value.EndsWith("node")); | |
//private static readonly Func<FieldDefinitionNode, bool> _isForeignKeyField = field => | |
// field.Name.Value.StartsWith("_") && | |
// (field.Name.Value.EndsWith("DbId") || field.Name.Value.EndsWith("DbIds")); | |
private static T RemoveFields<T>( | |
string schemaName, | |
T typeDefinition, | |
Func<string, FieldDefinitionNode, bool> shouldRemove, | |
RewriteFieldsDelegate<T> rewrite) | |
where T : ComplexTypeDefinitionNodeBase, ITypeDefinitionNode | |
{ | |
var keptFields = new List<FieldDefinitionNode>(); | |
foreach (var field in typeDefinition.Fields) | |
{ | |
if (!shouldRemove(schemaName, field)) | |
{ | |
keptFields.Add(field); | |
} | |
} | |
return rewrite(keptFields); | |
} | |
internal delegate T RewriteFieldsDelegate<T>( | |
IReadOnlyList<FieldDefinitionNode> fields) | |
where T : ComplexTypeDefinitionNodeBase, ITypeDefinitionNode; | |
} | |
} |