首先,假设我们有个查询用户的 GraphQL 如下:

query getUsers {
  users {
      id
      firstName
      lastName
      phone
      email
      username
      role
  }
}

从上面 GraphQL 中我们能看到,这是一个 query 类型的请求,我们给定了一个 getUsers 请求名称,调用了 users 这个接口来得到一些用户数据

假设我们得到的数据如下:

{
  "data": {
    "users": [
      {
        "id": 1,
        "firstName": "Berniece",
        "lastName": "Kris",
        "email": null
      },
      {
        "id": 2,
        "firstName": "Bradly",
        "lastName": "Lind",
        "email": null
      },
      {
        "id": 3,
        "firstName": "Leila",
        "lastName": "Schowalter",
        "email": null
      },
      {
        "id": 4,
        "firstName": "Laila",
        "lastName": "Breitenberg",
        "email": null
      },
      {
        "id": 5,
        "firstName": "Joe",
        "lastName": "Crist",
        "email": null
      },
      {
        "id": 6,
        "firstName": "Bettye",
        "lastName": "Bartoletti",
        "email": null
      }
    ]
  }
}

那么 GraphQL 中的别名(aliases)到底怎么用呢?

现在我们还是这个查询用户接口,不过后端提供了一个 role 参数可以使我们查询出不同角色的用户,如下所示:

query getUsers {
  users(role: ADMIN) {
    id
    firstName
    lastName
    phone
    username
  }
  users(role: ACCOUNTANT) {
    id
    firstName
    lastName
    phone
    username
  }
}

有些朋友可能看出来了不同,呀?你这 GraphQL 还能这么查的?好家伙,两个不同参数然后直接查询两个 users 接口?直呼学到了

先别急,我们先查询看看?

{
  "errors": [
    {
      "message": "Fields "users" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.",
      "locations": [
        {
          "line": 2,
          "column": 3
        },
        {
          "line": 9,
          "column": 3
        }
      ]
    }
  ]
}

是的,你没猜错就是报错了。从逻辑上来说就完全走不通呀,你看 GraphQL 数据是根据查询来返回数据格式的,也就是说你查询用的是 users 那么返回的数据也是在 users 字段下面的,不信的话你滑上去看看我们之前请求的返回的数据

那么有啥办法能够不影响我一次查两个而且要传不同参数的神仙操作呢?没错 ApolloGraphQL 团队已经在 error 的 message 中给出我们想要的答案了,那就是今天的主角 aliases(别名),看看下面的查询,相信我很快你也能掌握这神仙般的操作

query getUsers {
  admins: users(role: ADMIN) {
    id
    firstName
    lastName
    phone
    username
  }
  accountants: users(role: ACCOUNTANT) {
    id
    firstName
    lastName
    phone
    username
  }
}

现在我们发起请求看看?

{
  "data": {
    "admins": [
      {
        "id": 1,
        "firstName": "Berniece",
        "lastName": "Kris",
        "phone": "021.807.6991 x10598",
        "username": "Ana_Quigley"
      },
      {
        "id": 2,
        "firstName": "Bradly",
        "lastName": "Lind",
        "phone": "863.803.0636 x9247",
        "username": "Winona_Kulas12"
      },
      {
        "id": 3,
        "firstName": "Leila",
        "lastName": "Schowalter",
        "phone": "1-425-625-3887",
        "username": "Isabell.Kautzer"
      },
      {
        "id": 4,
        "firstName": "Laila",
        "lastName": "Breitenberg",
        "phone": "155.714.0635 x741",
        "username": "Christophe.Oberbrunner"
      },
      {
        "id": 5,
        "firstName": "Joe",
        "lastName": "Crist",
        "phone": "895-077-1248",
        "username": "Dahlia.Gerhold56"
      },
      {
        "id": 6,
        "firstName": "Bettye",
        "lastName": "Bartoletti",
        "phone": "1-610-898-0105",
        "username": "Thad_Mayert"
      }
    ],
    "accountants": [
      {
        "id": 7,
        "firstName": "Laila",
        "lastName": "Breitenberg",
        "phone": "155.714.0635 x741",
        "username": "Christophe.Oberbrunner"
      },
      {
        "id": 8,
        "firstName": "Joe",
        "lastName": "Crist",
        "phone": "895-077-1248",
        "username": "Dahlia.Gerhold56"
      },
      {
        "id": 9,
        "firstName": "Bettye",
        "lastName": "Bartoletti",
        "phone": "1-610-898-0105",
        "username": "Thad_Mayert"
      }
    ]
  }
}

没错,正如你所看到的,GraphQL Aliases 其实就是在接口名前面加上你所定义的名字和一个冒号,然后返回的数据格式会以你定义的别名来代替掉接口名。

好了,今天的小知识就到这里。最后声明一下,本博客参考于 @David Mráz 的:https://atheros.ai/blog/how-to-use-graphql-aliases

大量数据和请求全部来自原博客,有兴趣的小伙伴可以看看原文

最后留下作者的示例代码仓库地址,同样适用于本文:https://github.com/atherosai/graphql-gateway-apollo-express