GraphQL变得简单

GraphQL完全吸引了API世界,这在很大程度上要归功于其独特的表达性API查询语言。 但是,由于语言障碍的影响,从Java安全地使用它带来了挑战。 幸运的是, GraphQL集成块消除了语言鸿沟,从而为Java提供了全面的GraphQL流畅性。 斯科特·麦金尼(Scott McKinney)在此演示了这个开拓性的框架如何通过无缝的,类型安全的GraphQL支持提高您的生产率。

预习

这里有一个快速的截屏视频,让您大致了解所有工作原理。 本文介绍了这里发生的事情,但请仔细观察。 请注意, .graphql模式和查询文件直接从Java使用。 您可以进行类型安全的查询,而无需执行代码生成步骤,无需维护POJO以及无需在GraphQL更改之间进行编译。 IDE中的高集成度也许同样令人印象深刻-您可以直接从Java类型和方法导航到GraphQL文件中的相应定义,也可以从中导航。 您还可以确定性地搜索和重构用法。 本质上,与Manifold一起,您的Java项目会说流利的GraphQL,以提供真正无缝的开发人员体验。

注意,尽管预览版演示了IntelliJ IDEA的Manifold插件特有的一些功能,但是如果没有它,您仍然可以使用Manifold。 Manifold作为标准Java编译器插件完全支持GraphQL以及其他模式。

还请参见: 如何使用Angular和React开发GraphQL前端

设置客户端

我将在本文中使用Manifold的示例GraphQL应用程序,但通常,您可以按照以下简单步骤设置任何项目,并使用Manifold为GraphQL配置开发环境。

按照GraphQL 设置说明配置项目以使用Manifold。 manifold-graphql在您的构建中添加manifold-graphql依赖项并将Manifold插件参数添加至javac即可。 如果使用的是Maven或Gradle,则可以从示例中剪切并粘贴所需的内容。

尽管可以在不使用IDE的情况下使用Manifold,但使用IntelliJ IDEA的Manifold插件 ,您将获得最大收益。 您可以直接从IntelliJ 插件设置UI免费安装它。 如果尚未安装IntelliJ,则可以免费下载

在安装时, 也要安装JS GraphQL插件 。 它提供了可靠的GraphQL编辑支持,并且Manifold插件对非常出色。 就我个人而言,没有它我不会离开家。

标准的GraphQL模式文件定义了将在客户端中使用的API。 按照惯例,该文件名为schema.graphql ,可以使用对GraphQL服务器端点的自省查询来获取。 有一些可用的命令行工具 ,但是请帮帮忙 ,并为IntelliJ安装JS GraphQL插件,并对其进行配置以为您维护方案文件。 它确实是一个出色的插件。

GraphQL示例应用程序

Manifold的示例GraphQL应用程序提供了一种简单的电影服务,用于查询电影和撰写评论。 出于演示目的,它以简单的内存数据结构为后盾。 该项目包括客户端和服务器,还提供了一个模式文件movie.graphql 。 本文的重点是客户端。

克隆该应用程序以进行后续操作:

git clone https://github.com/manifold-systems/manifold-sample-graphql-app.git

或者,您可以直接从IntelliJ打开项目:

文件从版本控制 的Git 项目 ➜: https://github.com/manifold-systems/manifold-sample-graphql-app.git

请注意,示例应用程序使用Java 11,请确保相应地设置环境。

有关完整信息,请参见自述文件

编写和使用查询

设置了客户端应用程序并查询了GraphQL模式后,就可以开始编写和使用查询了。 您可以直接使用标准.graphql资源文件编写GraphQL查询。 这是上面预览中的查询:

query MoviesQuery($title: String, $genre: Genre) {
    movies(title: $title, genre: $genre) {
        title     
        genre
        releaseDate
        starring {
            ... on Actor {
                name
            }  
        }
    }
}

它位于资源目​​录中的querys.graphql文件中。 Java使用文件的限定名称可以直接且类型安全地访问文件中的所有查询,就像它是Java类一样。 例如,按名称访问MoviesQuery作为Java类型,如下所示:

import graphql.queries.MoviesQuery;

注意,您可以对资源目录和查询文件使用任何喜欢的名称,例如, graphql目录是此演示的选定名称。

您可以使用便捷的构建器模式创建MoviesQuery

var query = MoviesQuery.builder()
  .withGenre(Action)
  .build();

MoviesQuery上构建器方法的参数反映所需(非空)的参数中所定义的queries.graphql文件。 因此,由于MoviesQuery没有指定任何非null参数(使用运算符),因此builder方法具有空参数列表。 可选的(nullable)参数使用withXxx()方法(例如withGenGen())配置为可为空的$ genre参数。

与查询定义一样, movies.graphql模式中的GraphQL枚举定义直接映射到Action Java枚举常量,因此您可以像这样静态导入它:

import static graphql.movies.Genre.Action;

同样,Manifold将整个模式直接映射到Java的类型系统中-类型,输入,接口,枚举,联合,查询,突变等都可以从Java安全地进行类型访问。 重要的是,不涉及代码生成构建步骤,无需维护POJO,并且GraphQL更改之间无需编译。 而是将Manifold插入Java编译器以使其全部完成,就好像是魔术一样。 如上面的预览所示,您只需将模式文件放入项目中并开始对其进行编码。

您可以使用HTTP POST请求轻松地对服务器端点执行查询并接收结果。

var result = query.request("http://localhost:4567/graphql").post();

在这里,示例GraphQL应用程序服务器在端口4567上本地运行,并处理graphql端点。 注意,请求API方便地直接内置到查询模型中。

注意,这些示例使用Java 11随附的var关键字来利用类型推断。您也可以根据需要明确指定类型。

有了查询结果,您就可以键入安全地处理它们。

for (var actionMovie: result.getMovies()) {
  out.println( 
    "Title: " + actionMovie.getTitle() + "\n" +
    "Genre: " + actionMovie.getGenre()} + "\n" +
    "Year: " + actionMovie.getReleaseDate().getYear() + "\n" +
    "Starring: " + actionMovie.getStarring().getName() );
}

使用变异

GraphQL突变的外观和行为与查询相同。 这是示例应用程序在MovieClient.java中使用的ReviewMutation ,它是在query.graphql文件中定义的。

mutation ReviewMutation($movieId: ID!, $review: ReviewInput!) {
  createReview(movieId: $movieId, review: $review) {
    id
    stars
    comment
  }
}

变异通常需要三步过程。

  • 查询信息以标识要更新的对象,通常查询ID
  • 使用新的和/或更改的信息创建输入对象
  • 创建并发布使用您的ID和输入对象参数化的变异对象

您可以在检查ReviewMutation类型时收集此过程。 将createReview成员的参数设置为要查看的电影的ID ,以及带有 星级和可选注释ReviewInput类型。

通过示例应用程序,您可以看到如何为电影“勒芒”创建评论。

首先,找到电影“勒芒”

// Find the movie to review ("Le Mans")
var movie = MovieQuery.builder()
  .withTitle("Le Mans").build()
  .request(ENDPOINT).post()
  .getMovies().first();

接下来,使用ReviewInput定义的movie.graphql模式文件为“勒芒”创建评论。

input ReviewInput {
  stars: Int!
  comment: String
}

使用输入对象的方式与使用查询对象的方式相同。 在这里,我们使用builder()方法进行一个ReviewInput 。 在这种情况下,由于stars属性为非null,因此builder方法将其公开为非null参数,从而使其成为必需的属性。 comment属性是可为空的,因此使用了可选的withComment()方法。

var review = ReviewInput.builder(5)
  .withComment("Topnotch racing film.")
  .build();

构建了ReviewInput之后 ,下一步涉及再次使用builder()方法将其传递到ReviewMutation中 。 由于IDreview被定义为突变定义的非空参数,因此builder()方法将它们反映为必需参数。

var mutation = ReviewMutation.builder(movie.getId(), review).build();

就像查询一样,您可以使用HTTP POST请求调用变异。

var createdReview = mutation.request(ENDPOINT).post().getCreateReview();

该帖子返回您可以安全键入的结果Review对象。

out.println(
  "Review for: ${movie.getTitle()}\n" +
  "Stars: ${createdReview.getStars()}\n" +
  "Comment: ${createdReview.getComment()}\n"
);

请求认证

实际上,在向受保护资源发出请求时,GraphQL客户端通常需要指定某种形式的用户身份验证。 按照惯例,这是使用Authorization HTTP标头处理的。 集成块通过Request API方法(例如withBearerAuthorization())使此操作变得容易。

var result = query.request("https://api.github.com/graphql")                           
               .withBearerAuthorization("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
               .post();

本示例演示了如何使用Bearer身份验证方案配置带有安全令牌的请求。 注意承载身份验证只能在HTTPS(SSL)上使用。

还请参见: FaunaDB的GraphQL API不再有n + 1个问题

嵌入查询

如果您想尝试前沿技术,请查看歧管碎片 。 这项新的实验性功能使您可以直接将资源安全地将资源嵌入Java源代码中。 它对于一次性使用GraphQL查询特别有效,在这种情况下,您可以编辑和维护查询定义,使其更接近代码中的定义。

很简单 您将查询定义嵌入到这样的注释中:

图

[>MyQuery.graphql<]标记告诉Java,这是名称为MyQuery的资源类型graphql的嵌入式片段,就好像它是在同名的资源文件中定义的一样。 这样,您可以通过其声明的名称MyQuery引用该片段。

片段类型安全性尤其重要。 片段是静态类型的,这使编译器可以验证使用它们的代码。 正如代码片段用IDE插件说明的那样,您不仅在Java代码中具有代码完成等功能,而且在片段本身中还具有丰富的编辑功能!

与其他Manifold功能一样,您不需要IntellIJ使用片段,因为Manifold直接与Java Compiler作为插件一起工作。 这样,您可以使用文本编辑器或您喜欢的其他IDE。 但是,您可以想象,使用IntelliJ中启用的这些功能可以极大地提高整体开发经验。

新生活

API的API。 本质上就是GraphQL。 事后看来,这是解决困扰服务提供商的维护和性能疾病的明显补救方法-一种声明性语言,使服务使用者能够精确地构造他们所需的信息。 而且,重要的是,要安全地进行所有操作。

随着越来越多的服务提供商拥抱GraphQL,对于固态Java解决方案的压力越来越大,尤其是在客户端上。 在这里,我演示了GraphQL集成块如何超出预期,从而可以从Java提供真正无缝的,类型安全的GraphQL访问。 实际上,其非凡的元编程能力提供了通常为动态语言(如Javascript)保留的一定程度的灵活性。 最重要的是,这些功能在您最需要的时间和地点静态存在:在IDE中编写代码时! 结果,GraphQL感觉轻巧,连接且平易近人。

希望引起您的兴趣,并且您将对GraphQL集成块进行更深入的研究 。 谢谢阅读!

翻译自: https://jaxenter.com/graphql-made-easy-169181.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值