如何使用全球ID?

How to use global ID?

id 在每次加载时都不同时,我应该如何(重新)查询对象? 我错过了什么?

const {nodeInterface, nodeField} = nodeDefinitions(
  (globalId) => {
    const {type, id} = fromGlobalId(globalId);

    // This id is different every time (if page is reloaded/refreshed)
    // How am I suppose to use this id for database query (e.g by id)?
    // How do I get "the right ID"? (ID actually used in database)
    console.log('id:', id);

    // This is correct: "User"
    console.log('type:', type);

    if (type === 'User') {
        // Function that is suppose to get the user but id is useless ..
        return getUserById(id);
    } 
    return null;
  },

  (obj) => {
    if (obj instanceof User) {
        return userType;
    } 
    return null;
  }
);

const userType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
      id: globalIdField('User'),      // Relay ID
      _id:   { type: GraphQLString }, // MongoDB ID
      email: { type: GraphQLString },
      name:  { type: GraphQLString }    
  }),
  interfaces: [nodeInterface]
});

全局 ID 主要用于重新获取中继客户端存储中已有的对象。我会 DRY 并指向 ,它很好地解释了如何在 Relay 中使用全局 ID。

如果您使用库中的辅助函数,例如 JavaScript 中的 graphql-relay-js,处理全局 ID 变得非常简单:

  1. 您决定服务器端对象类型 X 对应于 GraphQL 对象类型 Y。
  2. 为X添加一个字段id。这个id是本地ID,对于任何类型X的对象,它必须是唯一的。如果X对应于MongoDB文档类型,那么一个简单的方法是将 _id 的字符串表示分配给这个 id 字段:instanceOfX.id = dbObject._id.toHexString().
  3. 使用 globalIdField 辅助函数向 Y 添加字段 idid 是全局 ID,它在所有类型和对象中都是唯一的。如何生成这个全局唯一 ID 字段取决于实现。 globalIdField 辅助函数根据对象 X 中的 id 字段和类型名称 X.
  4. 生成它
  5. nodeDefinitions 中,使用 fromGlobalId 辅助函数从全局 ID 中检索本地 ID 和类型。由于 X 中的 id 字段是 MongoDB 中的 _id 字段,您可以使用此本地 ID 执行数据库操作。首先从十六进制字符串转换为 MongoDB ID 类型。

本地 ID 分配(第 2 步)必须在您的实施中中断。否则,同一对象的 ID 在每次重新加载时都不会不同。