尝试使用 GraphQL

简要概述

由于我们在前端使用React,所以开始调查是否可以使用Relay进行通信,但意识到API不是REST而是GraphQL。因此,我们决定先尝试一些GraphQL语法。

因为在Relay的教程中,有一个可以执行GraphQL的UI,我会在那里尝试一下。

公式教程

完成宝藏游戏需要经过公式教程的一次完整操作。

我会边使用它边学习GraphQL。

开启服务器

我已经将教程后的代码图像提交到这里(标记教程)。

请按照以下方式启动。

npm install
npm run update-schema
npm start

在浏览器中打开http://localhost:3000,即可进行游戏。

GraphQL 的测试页面

可以通过在浏览器中打开根目录来显示用于测试的UI,GraphQL API位于http://localhost:8080。

graphql-ui.png

将会显示如上图所示的界面。

点击「>」按钮执行后,将以dada/schema.js中定义的模式对Docs进行格式化并显示。
此外,(虽然可能不太明显),点击左下方的查询变量QUERY VARIABLES可以输入查询的变量。

试用GraphQL

点击Docs,会出现一个查询和一个突变。查询用于获取数据,突变用于更新数据。

尝试获取游戏。
在左侧写有“欢迎~”的区域中输入 {game},然后点击执行(>)。

尽管结果在右侧显示,但这次会出现以下的错误提示。

{
  "errors": [
    {
      "message": "Field \"game\" of type \"Game\" must have a sub selection.",
      "locations": [
        {
          "line": 15,
          "column": 2
        }
      ]
    }
  ]
}

进一步输入的{game}也将被修改如下。

{game {
  id
}}

由于未指定要获取游戏中的哪个领域,所以会出现错误。同时,输入将在系统可以理解的范围内进行修正。
重新运行后,将显示查询的结果。

{
  "data": {
    "game": {
      "id": "R2FtZTox"
    }
  }
}

查看文件 Docs -> Query -> Game (或者 dada/schema.js),可以看到 Game 有三个字段,分别是 id、hidingSpots 和 turnsRemaining。

我尝试将输入更改如下。

{
  game {
    id
    turnsRemaining
  }
}

运行后,结果中也包含了 turnsRemaining。

进一步添加hidingSpots到查询中。

{
  game {
    id
    turnsRemaining
    hidingSpots
  }
}

又出现错误,查询将被修正如下。

{
  game {
    id
    turnsRemaining
    hidingSpots {
      edges {
        node {
          id
        }
      }
    }
  }
}

由于hidingSpots是一个对象列表,因此需要指定要提取的信息。

{
  game {
    id
    turnsRemaining
    hidingSpots {
      edges {
        node {
          id
          hasBeenChecked
          hasTreasure
        }
      }
    }
  }
}

可以获取到寻宝藏匿地(hidingSpot)的列表。

在这里先暂时回到游戏画面(http://localhost:3000)。
※ 如果您已经玩过游戏,请重新启动服务器,因为服务器上的状态仍然存在。

在游戏界面上点击任意一格。
重新执行上述查询,即可获取更新后的格子信息。

            :
          {
            "node": {
              "id": "SGlkaW5nU3BvdDox",
              "hasBeenChecked": false,
              "hasTreasure": null
            }
          },
          {
            "node": {
              "id": "SGlkaW5nU3BvdDoy",
              "hasBeenChecked": true,
              "hasTreasure": false
            }
          },
          {
            "node": {
              "id": "SGlkaW5nU3BvdDoz",
              "hasBeenChecked": false,
              "hasTreasure": null
            }
          },
            :

请记住 hasBeenChecked 值为 false 的节点的 id 值,以备在下一个更新查询中使用。(例如在上面的示例中,SGlkaW5nU3BvdDoz等)

更新查询

首先,我们会尝试执行更新查询。您只需按照以下方式输入:

mutation Mutation($input:CheckHidingSpotForTreasureInput!) {
  checkHidingSpotForTreasure(input:$input) {
    clientMutationId
  }
}

请在 QUERY VARIABLES(如果看不到输入框,请点击)中输入以下内容。

{
  "input":{
    "id":"SGlkaW5nU3BvdDoz",
    "clientMutationId":"0"
  }
}

请将变量id的值更改为之前记录的hidingSpot的id值。

当重新加载游戏画面或执行下一个查询时,可以看到更新。

{
  game {
    id
    turnsRemaining
    hidingSpots {
      edges {
        node {
          id
          hasBeenChecked
          hasTreasure
        }
      }
    }
  }
}

在Docs的CheckHidingSpotForTreasurePayload的字段中,更新查询的第三行clientMutationId可以指定在更新后要获取的字段,与数据获取查询相同。

mutation Mutation($input:CheckHidingSpotForTreasureInput!) {
  checkHidingSpotForTreasure(input:$input) {
    clientMutationId
  }
}

在查询变量中指定的值是CheckHidingSpotForTreasureInput的字段。

最后

在熟悉GraphQL之前,使用此用户界面并查看输出和文档来构建查询似乎是一种高效的方法。

我本来想用Elixir / Phoenix来实现服务器,但目前还没有相应的库,我觉得实现起来比较困难,所以打算再进一步提升技术之后再尝试一下。

由于 Relay 教程使用的是 ES7 编写的,所以很快 React 也可能会使用 ES6 的类来实现,因此我们计划查找可以替代 mixin 等功能的方法。

请提供更多的上下文以便我能更好地帮助您进行翻译。

    • Tutorial | Relay Docs

 

    graphql/README.md at master · facebook/graphql
广告
将在 10 秒后关闭
bannerAds