graphql - apollo klient:codegen typescript med @client frågefält


Förlåt om detta är lite invecklat, men jag försöker verkligen att slutföra det sista steget för att kunna använda Apollo Client för både lokal och serverstatus, med automatisk Typescript överallt. Nämligen, jag har en fråga som denna:

query NavigationBarQuery($userId: Int, $portfolioCompanyId: Int!) {
  user(id: $userId) {
    id
    firstName
    lastName
    company {
      ... on CompanyInterface {
        companyType
      }
    }
  }
}

Det importeras av min NavigationBar-komponent på följande sätt:

import { NavigationBarQuery, NavigationBarQueryVariables } from '../../../graphql/generated/NavigationBarQuery';
import NAVIGATION_BAR_QUERY from '../../../graphql/NavigationBarQuery.graphql';

const NavigationBar = (vars: NavigationBarQueryVariables) => (
  <Query query={NAVIGATION_BAR_QUERY} variables={vars}>
    {({ loading, error, data, client }: QueryResult<INavigationBarClientQuery>) => {

     // etc.

Generering utförs med en lokal schemafil (dumpad från Graphene) på följande sätt:

apollo client:codegen --localSchemaFile ./build/schema.json --includes './src/graphql/**' --target typescript

Detta fungerar utmärkt, jag får TypeScript-typer och allt.

Jag skulle dock vilja inkludera lite lokalt tillstånd, med en fråga som denna:

query NavigationBarQuery($userId: Int, $portfolioCompanyId: Int!) {
  user(id: $userId) {
    id
    firstName
    lastName
    company {
      ... on CompanyInterface {
        companyType
      }
    }
  }
  showNavbarUserInfo @client
}

Denna fråga fungerar helt okej om jag kringgår TypeScript, men när jag försöker generera TypeScript-definitioner för den, ger genereringsskriptet detta fel:

.../client/src/graphql/NavigationBarQuery.graphql: Cannot query field "showNavbarUserInfo" on type "Query".
{ ToolError: Validation of GraphQL query document failed
    at Object.validateQueryDocument (/Users/gavin/.config/yarn/global/node_modules/apollo-language-server/lib/errors/validation.js:32:19)
    at Object.generate [as default] (/Users/gavin/.config/yarn/global/node_modules/apollo/lib/generate.js:19:18)
    at write (/Users/gavin/.config/yarn/global/node_modules/apollo/lib/commands/client/codegen.js:64:54)
    at Task.task (/Users/gavin/.config/yarn/global/node_modules/apollo/lib/commands/client/codegen.js:83:46) name: 'ToolError' }

Vad, om något, är en lösning på detta? Som vanligt, letar efter exempel.

Svar #1

Jag har precis gått igenom detta så förhoppningsvis kommer det att hjälpa någon. Och om ditt namn faktiskt är "Someone" och du råkar leta efter denna information; detta ÄR helt för dig!

Min uppställning:

Jag har två schemaveckor.

  • En som hämtas från min GraphQL-server
  • En lokal schemafil som innehåller de utökade egenskaperna för att lagra värden lokalt

Beroenden

  • @apollo/client": "^3.3.11"
  • @apollo/react-hooks": "^4.0.0"

DevDependencies

  • @graphql-codegen/add": "^2.0.2"
  • @graphql-codegen/cli": "^1.20.1"
  • @graphql-codegen/typescript-apollo-client-helpers": "^1.1.2"
  • @graphql-codegen/typescript-operations": "^1.17.14"
  • @graphql-codegen/typescript-react-apollo": "^2.2.1"
  1. För bättre användning rekommenderar jag att skapa en codegen.yml-fil (om du inte har sett många hackerfilmer och tycker att det är MYCKET coolare att använda konsolen för alla dessa alternativ. Eller, om du bara vill... jag dömer inte.)
#./codegen.yml
See: https://graphql-code-generator.com/docs/getting-started/codegen-config
overwrite: true
schema:
  - "https://my-dev-server.com/v1/graphql":
      headers:
        'Authorization': 'Bearer [TOKEN]'
generates:
  graphql/generated/generated.ts:
    # This is the defined client side schema file. It will first load the root schema defined above, and then load this (see: https://graphql-code-generator.com/docs/getting-started/schema-field#local-graphql-files)
    schema: graphql/client-schema.graphql
    # This is where the gql queries/subscripts/mutations reside
    documents: "graphql/queries/**/*.ts"
    plugins:
      - add:
          content: /* eslint-disable */
      - typescript
      - typescript-operations
      - typescript-react-apollo
    config:
      withHooks: true

  1. Ställ in en lokal schemafil. Kalla den vad du vill, bara se till att du anger värdet korrekt i codegen.yml. Jag har kallat min client-schema.graphql eftersom jag är superklok....
#./client-schema.graphql

see: https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/
directive @client on FIELD

type LocalStateType {
  companyId: String
  contactId: String
}

extend type Users {
  localState: LocalStateType!
}
  1. När ovanstående är på plats och beroende på din IDE, bör intellisense börja plocka upp ändringarna. Du kommer behöva använda @client-direktivet på dina förfrågningar; så här:
export const QUERY_USER_BY_ID = gql`
  query getUserDetails($Id: uuid!) {
    Users_by_pk(Id: $Id) {
      EmailAddress
      Id
      localState @client {
        companyId
        contactId
      }
    }
  }
`;
  1. Kör kommandot för att generera varorna:
  • npx graphql-codegen --config codegen.yml

NYCKELNOTER

  • Jag har märkt att det inte visas några fel om du anger fel sökväg för klientfilen (client-schema.graphql). Men du kommer att veta att du har fel om du inte ser de genererade uppgifterna i utdata som refererar till @client-data.

Referenser:

  • https://graphql-code-generator.com/docs/getting-started/codegen-config
  • https://graphql-code-generator.com/docs/getting-started/schema-field#local-graphql-files
  • https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/

Svar #2

Ger ett uppdaterat svar här eftersom @cnp:s svar saknar exempel och innehåller trasiga länkar.

Mina exempel använder den nya Apollo CLI (https://github.com/apollographql/apollo-tooling) med npx, även om det också kan installeras lokalt och användas utan npx-kommandot.

Du behöver utöka ditt schema med lokala fält genom att lägga till en ny SDL-fil. Med hjälp av exempelqueries från den ursprungliga frågan skulle du lägga till en fil (t.ex. schema.graphql) med följande innehåll:

extend type NavigationBar {
  showNavbarUserInfo: Boolean!
}

Valfritt: om du använder VS Codes Apollo GraphQL-tillägg, är det nu ett bra tillfälle att låta det veta var det nya SDL-filen finns genom att lägga till den i includes på rätt sätt i apollo.config.js:

module.exports = {
  client: {
    includes: ['./schema.graphql'],
  },
};

Inkludera nu det lokala fältet showNavbarUserInfo @client i en av dina frågor, och kör sedan din kodgenereringskommando för att inkludera din ursprungliga schema.json-fil och din nya schema.graphql-fil:

npx apollo codegen:generate --localSchemaFile=schema.json,schema.graphql --target=typescript --includes=src/**/*.tsx --tagName=gql --addTypename --globalTypesFile=src/types/global-types.ts types

Relaterade artiklar