【问题标题】:Is graphql's ID type necessary if I've set an unique identifier with dataIdFromObject in Apollo Client如果我在 Apollo Client 中使用 dataIdFromObject 设置了唯一标识符,是否需要 graphql 的 ID 类型
【发布时间】:2024-04-20 20:35:02
【问题描述】:

我正在使用 graphql + mysql + react-apollo,这是User table 的 graphql 类型之一:

type User {
  id: ID!
  name: String!
}

我对@9​​87654324@ 中的ID scalar type 的问题是,当mysql 中的主键为int 时,它作为字符串返回,并且它在前端与打字稿产生了一些类型冲突。

鉴于我已经为 Apollo 客户端中的每个对象设置了一个唯一标识符 dataIdFromObject,我是否可以根本不使用 ID 标量类型:

import {InMemoryCache} from 'apollo-cache-inmemory';

const apolloMemoryCache = new InMemoryCache(
    {
        dataIdFromObject: ({id,__typename}) => {

          return __typename+id

        }
    }
);

const client = new ApolloClient({
   link: ApolloLink.from([authLink, httpLink]),
   cache: apolloMemoryCache,
 });

您会保留 ID 类型还是放弃它?

【问题讨论】:

    标签: javascript reactjs graphql react-apollo apollo-client


    【解决方案1】:

    你问了

    你会保留 ID 类型还是放弃它

    我通常建议保留 ID 类型,而不是向客户端公开您正在使用的整数。如果这是一个新数据集,那么使用 uuids 作为偏移量的 PK 可能会更好。它将变得“更安全”和“更安全”,因为您不太可能不小心让某人访问其他人的资料。

    无论哪种方式,我都建议根据 Relay 规范将 ID 设置为“不透明”,以便您以后可以在更改数据存储时更改它们,而不会影响您的客户端。应用程序通常会进行自己的类型检查,因此您要确保您的内容在这方面不会发生任何可能的变化。

    【讨论】:

    • 我没有考虑 uuids,现在不让主键暴露给公众可能为时已晚。大多数 ID 仅用于产品数据、论坛帖子等。没有敏感内容。
    • PK 的安全问题是什么?
    【解决方案2】:

    您应该为您的解析器定义一个自定义标量。

    在您的解析器中,您应该为 ID 添加一个您期望 int 的位置,或者您可以在解析器中进行 int 和字符串之间的转换。

    import { GraphQLScalarType } from 'graphql';
    
    const resolverMap = {
      ID: new GraphQLScalarType({
        name: 'ID',
        description: 'Numeric custom scalar type',
        parseValue(value) {
          let result;
          // Implement your own behavior here by setting the 'result' variable
          return result;
        },
        serialize(value) {
          let result;
          // Implement your own behavior here by setting the 'result' variable
          return result;
        },
        parseLiteral(ast) {
          switch (ast.kind) {
          // Implement your own behavior here by returning what suits your needs
          // depending on ast.kind
          }
        }
      }),
    };
    

    https://github.com/apollographql/graphql-tools/blob/master/docs/source/scalars.md#custom-graphqlscalartype-instance

    【讨论】:

      【解决方案3】:

      试试这个 type User { id: Int! name: String! }

      【讨论】:

      • 是的,我正在考虑这个问题。有没有 mysql + graphql + apollo 用户根本不将主键定义为 ID 标量类型?