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; | |
| } | |
| } |