apollo客户端:带有@client查询字段的codegen typescript

Gav*_*vin 7 typescript apollo graphql

很抱歉,如果这有点涉及,但我真的想要关闭最后一英里能够使用Apollo Client本地和服务器状态,自动Typescript无处不在.也就是说,我有这样的查询:

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

这是我的NavigationBar组件导入的,如下所示:

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.
Run Code Online (Sandbox Code Playgroud)

使用本地模式文件(从Graphene转储)执行生成,如下所示:

apollo client:codegen --localSchemaFile ./build/schema.json --includes './src/graphql/**' --target typescript
Run Code Online (Sandbox Code Playgroud)

这很好用,我得到TypeScript类型和一切.

但是,我想要包含一些本地状态,查询如下:

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

如果我绕过TypeScript,此查询可以正常工作,但是当我尝试为它生成Typescript定义时,生成脚本会发出以下错误:

.../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' }
Run Code Online (Sandbox Code Playgroud)

什么,如果有的话,是解决方法吗?按照惯例,寻找例子.

anA*_*ent 15

我刚刚完成了这个工作,希望这会对某人有所帮助。如果您的名字实际上是“某人”,而您恰好正在寻找此信息;这完全适合你!

我的设置:

我有两个架构文件。

  • 从我的 GraphQL Server 中提取的一个
  • 本地架构文件,包含用于在本地存储值的扩展属性

依赖关系

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

开发依赖

  • @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. 为了更好地使用,我建议创建一个codegen.yml文件(除非您看过很多黑客电影并认为使用控制台来执行所有这些选项更酷。或者,如果您只是想...我不会评判.)
#./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

Run Code Online (Sandbox Code Playgroud)
  1. 设置本地架构文件。你喜欢怎么称呼它,只要确保你在codegen.yml. 我打电话给我的,client-schema.graphql因为我超级聪明......
#./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!
}
Run Code Online (Sandbox Code Playgroud)
  1. 一旦上述内容就位,并且根据您的 IDE,智能感知应该开始接收更改。您需要@client在查询中使用该指令;像这样:
export const QUERY_USER_BY_ID = gql`
  query getUserDetails($Id: uuid!) {
    Users_by_pk(Id: $Id) {
      EmailAddress
      Id
      localState @client {
        companyId
        contactId
      }
    }
  }
`;
Run Code Online (Sandbox Code Playgroud)
  1. 运行命令生成商品:
  • npx graphql-codegen --config codegen.yml

要点

  • 我注意到,如果您为客户端 ( client-schema.graphql) 文件设置了错误的路径,则不会显示任何错误。但是,如果您在输出中没有看到引用 @client 数据的生成数据,您就会知道自己错了。

参考:


Joh*_*ika 8

此处提供更新的答案,因为 @cnp 的答案缺少示例并且包含损坏的链接。

我的示例使用新的 Apollo CLI ( https://github.com/apollographql/apollo-tooling ) 和npx,尽管它也可以在本地安装并在没有npx命令的情况下使用。

您需要通过添加新的 SDL 文件来使用仅限本地的字段来扩展架构。使用原始问题中的示例查询,您将添加一个schema.graphql包含以下内容的文件(例如 ):

extend type NavigationBar {
  showNavbarUserInfo: Boolean!
}
Run Code Online (Sandbox Code Playgroud)

可选:includes如果您使用 VS Code 的 Apollo GraphQL 扩展,现在是将其添加到正确的位置,让它知道在哪里可以找到新的 SDL 文件apollo.config.js

module.exports = {
  client: {
    includes: ['./schema.graphql'],
  },
};
Run Code Online (Sandbox Code Playgroud)

showNavbarUserInfo @client现在,在您的查询之一中包含本地字段,然后运行 ​​code gen 命令以包含原始schema.json文件和新schema.graphql文件:

npx apollo codegen:generate --localSchemaFile=schema.json,schema.graphql --target=typescript --includes=src/**/*.tsx --tagName=gql --addTypename --globalTypesFile=src/types/global-types.ts types
Run Code Online (Sandbox Code Playgroud)


cnp*_*cnp 1

为了使其工作,您需要.graphql使用客户端本地状态类型定义一个 SDL 文件。然后,codegen 功能将看到该文件并将其与您的主架构合并。有关更多信息,请参阅https://github.com/apollographql/apollo-tooling/issues/949#issuecomment-459907307,示例链接: https: //github.com/apollographql/fullstack-tutorial/blob/master /final/client/src/resolvers.js#L4。注意使用extends Query.