Skip to content

Conversation

@FionaBronwen
Copy link

@FionaBronwen FionaBronwen commented Jul 7, 2025

Overview

This PR adds a new GraphQLTSPDenormalizer class that is responsible for handling the denormalization of a TSP namespace for GraphQL purposes. The GraphQLTSPDenormalizer is essentially a preprocessing step that transforms the TypeSpec types into a more GraphQL friendly shape.

The resulting TypeSpec denormalized for GraphQL can then be used as input for multiple different emitters that are related to GraphQL for example:

  • GraphQL Schema Emitter: Which would emit a GraphQL schema based on the denormalized TSP
  • Python Emitter: Which could emit Python server code based on the denormalized TSP

This unified denormalization approach allows us to reuse transformation logic and ensure consistency across emitters working in the same domain (in our case GraphQL).

This PR focuses on only the first denormalization step, creating input specific types for models used as inputs to operations.

Example

TypeSpec Input

        namespace TestNamespace {
          model Address {
            street: string;
            city: string;
          }
          
          model User {
            name: string;
            homeAddress: Address;
            workAddress: Address;
          }
          
          op CreateUser(user: User): User;
        }

TypeSpec Output

        namespace TestNamespace {
          model Address {
            street: string;
            city: string;
          }

          model AddressInput {
            street: string;
            city: string;
          }
          
          model User {
            name: string;
            homeAddress: Address;
            workAddress: Address;
          }

          model UserInput {
            name: string;
            homeAddress: AddressInput;
            workAddress: AddressInput;
          }
          
          op CreateUser(user: UserInput): User;
        }

Following Work

The following GraphQL normalization steps will be addressed subsequently:

  • Resolve model property error handling and related GraphQL decorators
  • Rename identifiers to comply with GraphQL naming rules
  • Transform basic types into scalars
  • Transform intrinsic types
  • Transform record types
  • De-anonymize unions
  • Materialize implicit Query/Mutation/Subscription types
  • Resolve sub-schema selection (duplicate types into every schema/namespace that uses them)
  • Remove null types from unions

@FionaBronwen FionaBronwen marked this pull request as ready for review July 7, 2025 21:20

Choose a reason for hiding this comment

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

I think this is a classic visitor pattern problem.
We should define a series of denormalizations as visitors that can be applied to the TypeSpec program.
TypeSpec is already essentially structured for this using navigateProgram and friends.

But I'm not 100% sure how this interacts with TypeKit, so let me know if I am missing something there cc @swatkatz

@FionaBronwen FionaBronwen marked this pull request as draft December 21, 2025 16:22
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.

3 participants