阿波罗客户端:带有@client查询字段的codegen打字稿

时间:2018-12-18 19:23:09

标签: typescript graphql apollo

很抱歉,如果涉及到这一点,但我真的想关闭 能够将Apollo Client用于本地以及 服务器状态,到处都有自动Typescript。智慧地说,我有这样的查询:

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

那是由我的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.

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

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

这很好用,我可以获得TypeScript类型和所有内容。

但是,我想通过这样的查询包含一些本地状态:

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

如果我绕过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' }

解决方法是什么(如果有的话)?和往常一样,寻找例子。

3 个答案:

答案 0 :(得分:3)

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

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

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

extend type NavigationBar {
  showNavbarUserInfo: Boolean!
}

可选:如果您正在使用 VS Code 的 Apollo GraphQL 扩展,现在是时候通过将新 SDL 文件添加到 includesapollo.config.js中正确:

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

现在在您的查询之一中包含 showNavbarUserInfo @client 本地字段,然后运行您的代码生成命令以包含您的原始 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

答案 1 :(得分:1)

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

我的设置:

我有两个架构文件。

  • 从我的 GraphQL 服务器中下拉的一个
  • 包含用于在本地存储值的扩展属性的本地架构文件

依赖项

  • @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

  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!
}
  1. 一旦上述内容就位并取决于您的 IDE,intellisense 应该开始接受更改。您需要在查询中使用 @client 指令;像这样:
export const QUERY_USER_BY_ID = gql`
  query getUserDetails($Id: uuid!) {
    Users_by_pk(Id: $Id) {
      EmailAddress
      Id
      localState @client {
        companyId
        contactId
      }
    }
  }
`;
  1. 运行命令生成商品:
  • npx graphql-codegen --config codegen.yml

重要说明

  • 我注意到,如果您没有获得不正确的子架构文件 (client-schema.graphql) 的路径,则不会显示任何错误。但是,如果您没有看到生成的数据包含您的属性,您就会知道自己错了。

参考:

答案 2 :(得分:0)

为此,您需要使用客户端本地状态类型定义一个.graphql SDL文件。然后,代码生成功能将看到此文件并将其与您的主架构合并。有关更多信息,请参见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的使用。