优秀的编程知识分享平台

网站首页 > 技术文章 正文

eslint-plugin-graphql 插件验证 graphql

nanyue 2024-08-22 17:28:11 技术文章 6 ℃

从各种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是一个功能强大的工具,无论您使用哪个客户端,都能够验证您的查询。 快乐的查询

最近发表
标签列表