首页 文章

在GraphQL中,如何实现可选查询?

提问于
浏览
1

编辑:因为它似乎并不清楚,我特别询问我应该在后端的查询的解析函数内进行数据库请求 .

我正在实现GraphQL查询,我无法确切地了解在给定查询中应该进行多少次调用 . 例如,这是用户可以加入的用户和俱乐部的数据结构:

User {
  UserID
  Clubs
  OtherStuff
}

Club{
  ClubID
  ClubName
}

我可以对我的数据库进行以下调用:

  • 获取所有用户ID

  • 获取UserID的信息

  • 获取用户的所有ClubID

  • 获取ClubID的信息

我不明白的是,每次查询用户时是否应该进行所有这些调用 . 如果有人只查询UserID,那么检索其他所有内容似乎是一个巨大的浪费 . 如果用户俱乐部是一个完全独立的GraphQL查询,俱乐部是否应仅返回ClubID,或者是否有办法有效地允许俱乐部领域提供完整的俱乐部信息?

编辑2:好的,这是我的代码 . 我评论了我不知道该怎么做的部分 .

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    User: userQueryField,
    Club: clubQueryField
  }
});

const clubQueryField = {
  type: new GraphQLList(ClubType),
  args: {
    UserID: {
      description: 'Returns all clubs the user is a part of',
      type: GraphQLID
    }
  },
  resolve(root, {UserID}) {
    //.....
  }
};


const userQueryField = {
  type: new GraphQLList(UserType),
  args: {
    UserID: {
      description: 'If omitted, returns a list of all users. \
      Otherwise, returns the user with the provided ID',
      type: GraphQLID
    }
  },
  resolve(root, {UserID}) {
    if(UserID){
      return new Promise((resolve, reject) => {
        getUserInfo(UserID, function(response){

          //HERE: I have tried different things, like clubQueryField(UserID) and clubQueryField.resolve, but with no luck
          UserID.Clubs = clubQueryField
          resolve([response]);
        });
      });
    }
  }
};

编辑3:UserType定义 .

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    UserID: {
      type: GraphQLID
    },
    Clubs: {
      type: new GraphQLList(ClubType)
    }
  })
});

2 回答

  • 1

    GraphQL API按类型和字段进行组织,我建议为用户类型和俱乐部类型创建单独的查询,如果有人仅查询userIds,他们将使用用户查询 .

    查询用户:

    query {
      users {
       id
      }
    }
    

    查询俱乐部:

    query {
      club {
       clubID
       clubName
       userId
      }
    }
    

    如果有人试图查询用户/俱乐部,您可以将俱乐部类型添加到用户类型,如下所示:

    query {
      users {
       id
       club {
        clubID
        clubName
       }
      }
    }
    

    在你的用户类型中会有一个名为club的字段,它将成为类型俱乐部,在解析器中它将以 obj.userId 作为参数调用俱乐部查询,GraphQL的优点在于让客户决定要获取哪些字段 .

    你可以看到嵌套查询的例子here

    编辑:那么在你的情况下,你可以修改你的userType以包括用户所属的俱乐部,你不需要在你的 clubQueryField 条件将条件将在客户端正在进行的查询,所以说你的用户类型是这个:

    用户类型:

    export default new GraphQLObjectType({
      name: 'UserType',
      fields: {
        userId: {
          description: 'user id',
          type: GraphQLString
        },
        email: {
          description: 'user email',
          type: GraphQLString
        },
        clubs: {
          description: 'User clubs',
          type: new GraphQLList(ClubType),
          resolve: (obj, args, _) => {
            return getUserClubs(obj.userId);
          }
        },
      }
    });
    

    然后,如果您的客户只需要用户,它将请求这样的事情:

    query {
        User {
         userId
         email
         }
      }
    

    如果客户需要用户和俱乐部,它会要求这样的事情:

    query {
        User {
         userId
         email
         clubs {
            field1
            field2
           }
         }
      }
    
  • 1

    GraphQL具有延迟加载功能,可以处理查询中的其他字段 . 如果用户编写以下查询:

    query{
       users{
        id
       }
    }
    

    它获取用户ID,并且显然不会查找其他字段 . 这绝对取决于你的解析器 . 如果您编写如下解析器: users { resolve: body => get_user_id} ,它将从数据库中获取用户ID . 希望这可以帮助!

相关问题