Skip to content

Conversation

@seantleonard
Copy link
Contributor

@seantleonard seantleonard commented Jan 7, 2023

Why make this change?

Every object type in your schema automatically has a field named __typename (you don't need to define it). The __typename field returns the object type's name as a String (e.g., Book or Author).
GraphQL clients use an object's __typename for many purposes, such as to determine which type was returned by a field that can return multiple types (i.e., a union or interface).

What is this change?

  • When a field with reserved GraphQL introspection naming is detected (__typename), ignore adding that field as a column in the SqlQueryStructure object. HotChocolate automatically resolved __typename into the proper value in its own engine and our resolver should not be concerned with it.
  • With this change, the generated database query is correctly authored as:
SELECT TOP 100 [table0].[id] AS [id] FROM [dbo].[books] AS [table0] WHERE 1 = 1 ORDER BY [table0].[id] ASC FOR JSON PATH, INCLUDE_NULL_VALUES

How was this tested?

  • Integration Tests, added for single result / single item query, and a list query where nested fields exist.
  • Unit Tests

Sample Request(s)

Request

query myPublisherQuery{
  publishers {
    __typename,
    items{
      __typename,
      name
    }
  }
}

Response

{
  "data": {
    "publishers": {
      "__typename": "PublisherConnection",
      "items": [
        {
          "__typename": "Publisher",
          "name": "The First Publisher"
        },
        {
          "__typename": "Publisher",
          "name": "Big Company"
        },
        {
          "__typename": "Publisher",
          "name": "Policy Publisher 01"
        },
        {
          "__typename": "Publisher",
          "name": "Policy Publisher 02"
        },
        {
          "__typename": "Publisher",
          "name": "TBD Publishing One"
        },
        {
          "__typename": "Publisher",
          "name": "TBD Publishing Two Ltd"
        },
        {
          "__typename": "Publisher",
          "name": "Small Town Publisher"
        }
      ]
    }
  }
}

…ity field. This is a reserved GraphQL field name used for introspection and is automatically handled by HotChocolate.
@ayush3797
Copy link
Contributor

ayush3797 commented Jan 7, 2023

Can a database table actually have a column with name __typename ? Does it mean using graphql we cannot query a column in a table which has a reserved name?

@seantleonard
Copy link
Contributor Author

Can a database table actually have a column with name __typename ? Does it mean using graphql we cannot query a column in a table which has a reserved name?

Can there be other introspection fields?
Should we extend this to go beyond just typename?

Good point, per GraphQL Specification, we should extend this logic to type references with double underscore (__).

Any Name within a GraphQL type system must not start with two underscores "__" unless it is part of the introspection system as defined by this specification.

Types and fields required by the GraphQL introspection system that are used in the same context as user-defined types and fields are prefixed with "" two underscores. This in order to avoid naming collisions with user-defined GraphQL types.
Otherwise, any Name within a GraphQL type system must not start with two underscores "
".

@seantleonard
Copy link
Contributor Author

SQL allows underscores in column names, so we may need to require aliases be used in our runtime config to enable those fields to be used in our GraphQL Endpoint https://learn.microsoft.com/en-us/sql/odbc/microsoft/column-name-limitations?view=sql-server-ver16

Copy link
Contributor

@aaronburtle aaronburtle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good just a nit and possible suggestion.

@yorek
Copy link
Contributor

yorek commented Jan 12, 2023

I think it is fine to require that exposed database columns or documents properties do not start with a double underscore. Make sure this requirement is documented. This shouldn't be big deal as using the mapping feature it will always be possible to change the name of a column or a property to something else.

Copy link
Collaborator

@Aniruddh25 Aniruddh25 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the quick fix!

Copy link
Contributor

@aaronburtle aaronburtle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Just some nits, and a couple comments about clarifying some large if statements.

@seantleonard seantleonard merged commit afeb315 into main Jan 26, 2023
@seantleonard seantleonard deleted the dev/seleonar/typenameCompatibility branch January 26, 2023 08:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

__typename mistakenly interpreted as table column on gql queries

6 participants