如何在Apollo graphql中添加联合类型

问题描述 投票:3回答:1

我创建了这个问题,以防有人对如何在Apollo中添加union / Polymorphic类型感到好奇。希望这会让他们更容易。

在这个例子中,我希望响应是WorksheetApiError

// typedefs.js
export default [`
  schema {
    query: Query
  }

  type Query {
    worksheet(id: String!): Worksheet | Error
  }

  type Worksheet {
    id: String!
    name String
  }

  type ApiError {
    code: String!
    message: String!
  }
`];

// resolvers.js
export default {
  Query: {
    worksheet(_, args, { loaders }) {
      return loaders.worksheet.get(args.id).catch(() => {
        // ApiError
        return {
          code: '1',
          message: 'test'
        }
      });
    }
  }
};

// Express Server 
import { graphqlExpress } from 'apollo-server-express';
import { makeExecutableSchema } from 'graphql-tools';
import typeDefs from './typedefs';
import resolvers from './resolvers';

...


app.post(
  '/graphql',
  graphqlExpress(req => ({
    makeExecutableSchema({ typeDefs, resolvers }),
    context: mkRequestContext(req.ctx, req.log),
    formatError: formatGraphQLError(req.ctx, req.log)
  }))
);
apollo react-apollo graphql-js apollo-server graphql-tools
1个回答
1
投票

在GraphQL中,要在typedef中添加联合类型,您必须定义联合

我是

union WorksheetOrError = Worksheet | ApiError

在解析器中,您必须为具有__resolveType属性的union类型定义解析器。这将有助于告诉GraphQL执行程序结果的类型。

// typedefs.js
export default [
  `
  schema {
    query: Query
  }

  type Query {
    worksheet(id: String!): WorksheetOrError
  }

  union WorksheetOrError = Worksheet | ApiError 

  type Worksheet {
    id: String!
    name String
  }

  type ApiError {
    code: String!
    message: String!
  }
`];

在Apollo Client中创建GraphQL查询

 // resolvers.js
export default {
  Query: {
    worksheet() {
      ... 
    }
  },
  WorksheetOrError: {
    __resolveType(obj) {
      if (obj.id) {
        return 'Worksheet';
      }

      if (obj.code) {
        return 'ApiError';
      }

      return null;
    }
  },
};

现在,您可以检查// Your application code. // This is my Worksheet Query in my React code. const WorksheetQuery = gql` query GetWorksheet($worksheetId: String!) { worksheet(id: $worksheetId) { ... on Worksheet { id name } ... on ApiError { code message } } } 以检查响应中的类型。

注意:对于那些想知道我为什么不使用GraphQL错误的人。这是因为Apollo在遇到graphQL错误时似乎没有很好地处理错误。因此,对于一个解决方案,我试图在我的回复中返回自定义__typename

使用具有错误类型的联合的原因有几个很好。

  1. 目前,如果您想要使用GraphQLError进行部分响应。 Apollo不会缓存错误,因此如果您想稍后重新使用缓存的响应,则会因为错误被删除而无法获得完整的响应。 (现在您无法显示有错误的正确UI)
  2. 在Apollo中返回GraphQLError将返回错误的平面列表,其中包含错误在数据中的路径。因此,您需要验证模式的哪个部分发生了错误。但是,如果您按照上面的说明操作,则会在模式中出现错误。这样你就已经知道错误发生在哪个模式部分。
© www.soinside.com 2019 - 2024. All rights reserved.