Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/Core/Services/MetadataProviders/SqlMetadataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1474,7 +1474,7 @@ private async Task PopulateSourceDefinitionAsync(
&& IsGraphQLReservedName(entity, columnName, graphQLEnabledGlobally: runtimeConfig.IsGraphQLEnabled))
{
throw new DataApiBuilderException(
message: $"The column '{columnName}' violates GraphQL name restrictions.",
message: $"The column '{columnName}' from '{entityName}' violates GraphQL name restrictions.",
statusCode: HttpStatusCode.ServiceUnavailable,
subStatusCode: DataApiBuilderException.SubStatusCodes.ErrorInInitialization);
}
Expand Down Expand Up @@ -1584,7 +1584,8 @@ public static bool IsGraphQLReservedName(Entity entity, string databaseColumnNam
}
}

return IsIntrospectionField(databaseColumnName);
// Possible naming violations are if the field starts with '__' or if it contains whitespace characters.
return IsIntrospectionField(databaseColumnName) || IsGraphQLNameWhiteSpace(databaseColumnName);
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/Service.GraphQLBuilder/GraphQLNaming.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public static class GraphQLNaming
/// <seealso cref="https://spec.graphql.org/October2021/#sec-Names.Reserved-Names"/>
public const string INTROSPECTION_FIELD_PREFIX = "__";

public const string INVALID_EMPTY_SPACE = " ";

public const string LINKING_OBJECT_PREFIX = "linkingObject";

public const string PK_QUERY_SUFFIX = "_by_pk";
Expand Down Expand Up @@ -96,6 +98,20 @@ public static bool IsIntrospectionField(string fieldName)
return fieldName.StartsWith(INTROSPECTION_FIELD_PREFIX, StringComparison.Ordinal);
}

/// <summary>
/// Per GraphQL specification:
/// A name can only start with a letter or an underscore, and can only
/// contain letters, numbers, and underscores. It is not able to contain whitespaces
/// This helper function identifies whether the provided name contains whitespaces.
/// </summary>
/// <seealso cref="https://spec.graphql.org/October2021/#sec-Names"/>
/// <param name="fieldName">Field name to evaluate</param>
/// <returns>True/False</returns>
public static bool IsGraphQLNameWhiteSpace(string fieldName)
{
return fieldName.Contains(INVALID_EMPTY_SPACE, StringComparison.Ordinal);
}

/// <summary>
/// Attempts to deserialize and get the SingularPlural GraphQL naming config
/// of an Entity from the Runtime Configuration and return the singular name of the entity.
Expand Down
2 changes: 1 addition & 1 deletion src/Service.Tests/Configuration/ConfigurationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5651,7 +5651,7 @@ public async Task TestAutoentitiesWithSameObjectDifferentSchemas()
"PublisherAutoEntity", new Autoentity(
Patterns: new AutoentityPatterns(
Include: null,
Exclude: new[] { "dbo.GQLmappings", "dbo.graphql_incompatible", "dbo.brokers" },
Exclude: new[] { "dbo.GQLmappings", "dbo.brokers" },
Name: null
),
Template: new AutoentityTemplate(
Expand Down
Loading