从各种API端点提取可用数据可能很棘手。最近,当我想编写一个脚本来收集有关GitHub上某些用户和存储库的信息时,我遇到了这个问题。在过去,我使用过GitHub的RESTful API,并将我的数据从一系列端点拼凑起来。
尽管我对GraphQL的了解有限,但我还是决定学习GitHub的GraphQL API。
在这篇博文中,我描述了如何开始为GraphQL语法验证,模式验证和突出显示配置开发环境。
我的第一步是在API上发出一些测试查询。我很快发现GraphiQL是一个不可或缺的工具。重要的是,GraphiQL使用GraphQL的内省系统来提供内联文档和验证,这意味着您不必将上下文切换回Web浏览器以查看API文档。这很棒!
我在GraphiQL中使用了查询,并开始实现脚本。
专门建立的客户端
为了进行查询,我决定使用@ octokit / graphql,它提供了一个针对GitHub的瘦客户端。 @ octokit / graphql不提供面向对象的API;没有要实例化的类或要调用的方法。该模块导出单个异步函数,该函数接受查询,查询参数和标头(包括身份验证令牌)。
这是一个例子,取自文档:
const graphql = require('@octokit/graphql'); const {repository} = await graphql(`{ repository(owner:"octokit", name:"graphql.js") { issues(last:3) { edges { node { title } } } } }`, { headers: { authorization: `token secret123` } });
响应的内容:
{ "issues": { "edges": [ { "node": { "title": "An in-range update of webpack is breaking the build " } }, { "node": { "title": "An in-range update of webpack-bundle-analyzer is breaking the build " } }, { "node": { "title": "defaults() doesn't seem to work" } } ] } }
我将查询粘贴到VSCode中,并获取了我的数据。
但我的查询错了。 它确实有效,但它没有我需要的所有数据。 当我在编辑器中调整查询时,我意识到我遗漏了GraphiQL应该为我提供的三件事:
内省
语法突出显示
API验证
我以为我不是第一个遇到这个问题的人。 我知道我有一个特例,因为对于JavaScript,GraphQL查询只是一个字符串。 要执行验证,这样的工具需要知道任何给定的字符串是否包含GraphQL。
我开始寻找解决方案。
ESLint GraphQL 插件
正如所料,有人确实解决了这个问题。 Apollo平台上有一个ESLint插件,eslint-plugin-graphql可以执行验证。 它不仅验证语法,还针对特定的GraphQL架构进行验证。 所以,如果我拼错了一个GitHub API独有的GraphQL对象,比如下面的清单中的“ropesitory”:
ropesitory(owner:"octokit", name:"graphql.js")
ESLint会报告一个错误
无论如何,这个Promise。 它需要一些额外的设置来实现(取决于您的客户端),我在下面详述。 特别是,我的客户端(@ octokit / graphql)接受普通字符串作为查询。 无论客户端如何,您都需要提供ESLint GraphQL架构,它知道对象所在的正确位置。
配置eslint-plugin-graphql
要配置eslint-plugin-graphql,我需要获取GitHub v4 API的GraphQL架构。 模式是一个JSON文件,您可以从API中的内省系统派生出来。 因为我使用@ octokit / graphql,所以我能够在npm(@ octokit / graphql-schema)上使用关联的模式,所以我不必使用工具(例如graphql-cli)来下载或创建它。
1、我安装了这些模块以获得基本支持(包括graphql的对等依赖):
$ npm install eslint eslint-plugin-graphql --save-dev
在我的例子中,我还从@ octokit / graphql-schema中检索了schema.json:
$ npm install @octokit/graphql-schema --save-dev
2、我需要创建一个.graphqlconfig文件,它是一个包含schemaPath属性的JSON文件,其值是schema.json的相对路径:
{ "schemaPath": "node_modules/@octokit/graphql-schema/schema.json" }
3、我需要一个ESLint配置文件。 我偏爱使用YAML(对不起!),如:
plugins: - graphql parserOptions: ecmaVersion: 2015 # we need template strings rules: graphql/named-operations: error # requires each operation to be named graphql/capitalized-type-name: error # requires each type name is capitalizewd graphql/no-deprecated-fields: error # disallows use of deprecated fields graphql/template-strings: # defines how GraphQL is recognized - error - env: literal tagName: gql
注意:eslint-plugin-graphql模块不会导出任何“推荐”设置。 你需要列出每个规则(只有少数几个,所以这不是什么大问题)。这些规则 - 除了graphql / template-strings - 对我来说是非常简单的,即使是GraphQ的初学者也很容易掌握。
我知道graphql / template-strings规则定义了插件如何识别模板字符串中的GraphQL。 我知道除非我使用Apollo客户端,否则必须遵守此规则。 换句话说,graphql / template-strings不是一个ESLint规则,而是一个插件配置。graphql / template-strings规则的env属性是几个受支持的GraphQL客户端库的选择。 我的查询是原始的GraphQL(正如你在GraphiQL中使用的那样),所以我使用literal作为env值。
创建标记模板函数
由于我没有使用Apollo客户端,eslint-plugin-graphql需要另一种方法来确定我的哪些JavaScript字符串包含GraphQL查询。 毕竟,我不希望ESLint抱怨不是GraphQL查询的JavaScript字符串。 为此,我发现我需要使用(并实现)标记模板函数。
我需要将这个标记的模板函数添加到包含GraphQL查询的每个模板字符串。 例如,上面的查询看起来像这样,其中gql是标记的模板函数。
gql`{ repository(owner:"octokit", name:"graphql.js") { issues(last:3) { edges { node { title } } } } }`
幸运的是,eslint-plugin-graphql README提供了一个可以复制和粘贴的方法:
// does not need to be a global function! global.gql = (literals, ...substitutions) => { let result = ""; // run the loop only for the substitution count for (let i = 0; i < substitutions.length; i++) { result += literals[i]; result += substitutions[i]; } // add the last literal result += literals[literals.length - 1]; return result; }
这本质上是一个“标识”函数,它编译传递给它的模板字符串(和任何替换)。
我的代码中的其他字符串(例如,上面的结果)不会被解释为GraphQL查询,因为它们不使用此标记的模板函数。
请注意,您无需将函数命名为gql。 您可以使用任何名称,只要它是有效的函数名称并在graphql / template-strings规则的tagName prop中指定(返回ESLint配置文件)。
实现我的gql函数后,我准备使用eslint进行验证。
失败就是成功
我决定使用命名操作和拼写错误的对象验证我的脚本(script.js)容器:
gql`query LatestRepositoryIssues { ropesitory(owner:"octokit", name:"graphql.js") { issues(last:3) { edges { node { title } } } } }`
命令行:
$ eslint script.js 20:9 error Cannot query field "ropesitory" on type "Query". Did you mean "repository" or "repositoryOwner"? graphql/template-strings
现在这个工作正常,下面设置VSCode。
VSCode 配置
VSCode的ESLint扩展将处理GraphQL验证,但不会处理语法突出显示。 我为VSCode找到了一个很好的GraphQL扩展,它与我的gql函数一起工作。 事实上,鉴于我的设置包括.graphqlconfig,无需进一步配置:
总结:
我带您完成了获取语法验证,模式验证以及使用GraphQL进行突出显示的短暂过程。 虽然可能有点繁琐,但eslint-plugin-graphql是一个功能强大的工具,无论您使用哪个客户端,都能够验证您的查询。 快乐的查询