【问题标题】:How do I add union type in Apollo graphql如何在 Apollo graphql 中添加联合类型
【发布时间】:2018-10-03 00:05:17
【问题描述】:

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

在此示例中,我希望响应为 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】:

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

    union WorksheetOrError = Worksheet | ApiError

    // 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!
      }
    `];
    

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

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

    Apollo 客户端

    中创建 GraphQL 查询
    // 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
          }
        }
      }
    

    现在您可以检查__typename 以检查响应中的类型。

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

    使用带有错误类型的联合有几个原因。

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

    【讨论】:

      猜你喜欢
      • 2019-08-19
      • 2020-12-05
      • 2018-10-22
      • 2018-09-28
      • 2019-07-01
      • 2021-04-02
      • 2020-12-21
      • 2021-12-15
      相关资源
      最近更新 更多