dotansimha / dotansimha/graphql-code-generator
Fragment names as "magic strings" (no hard references)
- Dominant language
- TypeScript
- Stars
- 11.3k
- Forks
- 1.4k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 23
Description
### Is your feature request related to a problem? Please describe.
I've been concerned by the fact that we can't embed fragments with template string interpolation, as it breaks TypeScript type-inference, as mentioned in the documentation of `gql-tag-operations`.
Currently, the suggested approach is to spread fragments as "magic strings", meaning there's no hard reference to the fragment itself. We need to find the right name (and make sure of it!), be aware that fragments are generated with a `Fragment` suffix, then spread it. All fragments are defined "globally" or within the same file (`graphql.ts`), so all fragments are accessible.
```tsx
const allFilmsWithVariablesQueryDocument = graphql(/* GraphQL */ `
query allFilmsWithVariablesQuery($first: Int!) {
allFilms(first: $first) {
edges {
node {
...FilmItem
}
}
}
}
`);
```
It is worth mentioning that spreading a non-existing fragment will lead to an error within the codegen step. However, not having hard references (e.g., importing the fragment) could hurt the application's maintainability.
Another concern is that name conflicts between operations or fragments are possible, but again, the codegen will warn us against it. My concern is mainly for grown applications, it could be possible to spread the wrong existing fragment via a typo (e.g., `WorkspacesCard` instead of `WorkspaceCard`).
I would like to have the ability the rely on hard references for fragments, I don't mean to make it mandatory, but having the ability to would be interesting.
### Describe the solution you'd like
Currently, there's no way to easily extract the name of a generated fragment.
One solution could be to make that possible so that we could at least rely on a hard reference on the name rather than the fragment definition (to mitigate the related issue). So implementing a helper to extract the fragment's name from the `DocumentNode` object via some AST utils.
E.g., with the following helper: `getFragmentName()`, return the name of the generated fragment as a string so we can compose fragments or queries with it.
```tsx
import { graphql, getFragmentName } from './gql';
export const FilmFragment = graphql(/* GraphQL */ `
fragment FilmItem on Film {
id
title
releaseDate
producers
}
`);
const fragmentName = getFragmentName(FilmFragment); // 'FilmItemFragment'
// ^? const fragmentName = "FilmItemFragment"
```
> **Note**: There's still an unanswered question about how to expose fragment names?
We could either:
- export it as a `const`
- expose fragments as before (via imports), and call `getFragmentName` from consumers
- Use [Apollo Client's naming convention](https://www.apollographql.com/docs/react/data/fragments#creating-colocated-fragments) to retrieve a component's fragments given the component, but instead of retrieving fragment definitions, it will be exposing fragment names
So we could do something like:
```tsx
const allFilmsWithVariablesQueryDocument = graphql(/* GraphQL */ `
query allFilmsWithVariablesQuery($first: Int!) {
allFilms(first: $first) {
edges {
node {
...${getFragmentName(FilmItemFragment)}
}
}
}
}
`);
```
See the proposed implementation in https://github.com/dotansimha/graphql-code-generator/pull/9056.
### Describe alternatives you've considered
I've considered looking into why we can't embed fragments and what we could do not to make them "global", but I felt like it was not moving this project in the right direction and settled on adding an optional utility for people that share my concern.
### Is your feature request related to a problem? Please describe.
_No response_
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.