超音速 启动
MicroProfile GraphQL现在包含在刚发布的Quarkus 1.5.0版本中。
现在,您可以使用code.quarkus.io开始使用Quarkus,并包括SmallRye GraphQL Extension 。
![](https://i-blog.csdnimg.cn/blog_migrate/da10021db612969badf7dbc8f3ad211b.png)
这将创建一个具有以下依赖关系的Quarkus启动器应用程序:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-graphql</artifactId>
</dependency>
注意:目前,创建的示例应用程序是一个JAX-RS应用程序。 允许扩展定义自定义示例应用程序的工作正在进行中,但是直到那时,我们始终会得到一个JAX-RS应用程序。 您可以删除quarkus-resteasy
依赖项,因为我们不需要JAX-RS。
您的第一个GraphQL端点。
让我们将ExampleResource
Rest服务更改为GraphQL端点。
- 用
@GraphQLApi
替换@Path("/hello")
类注释。 - 更换
@GET
与方法的注释@Query
。 - 删除
@Produces(MediaType.TEXT_PLAIN)
方法注释和所有JAX-RS导入。
这就对了! 您的ExampleResource
现在应该如下所示:
package org.acme; import org.eclipse.microprofile.graphql.GraphQLApi; import org.eclipse.microprofile.graphql.Query; @GraphQLApi public class ExampleResource {
@Query
public String hello() {
return "hello" ;
} }
现在,您可以使用Quarkus dev模式运行该应用程序:
mvn quarkus:dev
现在浏览到localhost:8080 / graphql-ui /并运行以下查询:
{
hello }
这将返回:
{
"data" : {
"hello" : "hello"
} }
另请参阅《 Quarkus GraphQL指南》
更详细的例子
让我们看一个更详细的示例,从该GitHub项目获取源代码
这是一个多模块应用程序。 首先编译所有模块。 在根中:
mvn clean install
现在浏览到quarkus示例:
cd quarkus-example
看ProfileGraphQLApi.java
被标记为@GraphQLApi
:
@Query ( "person" )
public Person getPerson( @Name ( "personId" ) int personId){
return personDB.getPerson(personId);
}
上面的方法将通过personId
获取一个人。 如您所见,该方法可通过@Query
注释进行查询。 您可以选择提供名称(在这种情况下为“ person”),但是默认情况下仍为“ person”(方法名称不带“ get”)。 您还可以选择命名参数,但默认名称为参数名称(“ personId”)。
人员对象是一个POJO,代表系统中的人员(用户或成员)。 它具有许多字段,其中一些是其他复杂的POJO:
![](https://i-blog.csdnimg.cn/blog_migrate/d1f7b7b1bb74ed793a1634958bcb0447.png)
但是,使用Query
批注可以查询我们感兴趣的确切字段。
运行示例应用程序:
mvn quarkus:dev
现在浏览到localhost:8080 / graphql-ui /并运行以下查询:
{
person(personId: 1 ){
names
surname
scores{
name
value
}
} }
请注意,您在编辑器中拥有“代码洞察力”。 这是因为GraphQL具有架构并且还支持自省。
我们只能请求我们感兴趣的字段,从而使有效负载小得多。
![](https://i-blog.csdnimg.cn/blog_migrate/0aa8ef0cc516999ac7d4099b90d35985.png)
我们还可以组合查询,即,假设我们要获得人员1的字段,如上所示,以及人员2的名称和姓氏,我们可以执行以下操作:
{
person1: person(personId: 1 ){
names
surname
scores{
name
value
}
}
person2: person(personId: 2 ){
names
surname
} }
这将返回:
{
"data" : {
"person1" : {
"names" : [
"Christine" ,
"Fabian"
],
"surname" : "O'Reilly" ,
"scores" : [
{
"name" : "Driving" ,
"value" : 15
},
{
"name" : "Fitness" ,
"value" : 94
},
{
"name" : "Activity" ,
"value" : 63
},
{
"name" : "Financial" ,
"value" : 22
}
]
},
"person2" : {
"names" : [
"Masako" ,
"Errol"
],
"surname" : "Zemlak"
}
} }
源字段
如果仔细查看我们的查询,您会看到我们要求提供人员的scores
字段,但是, Person
POJO不包含scores
字段。 我们通过向人员添加@Source
字段来添加scores
字段:
@Query ( "person" )
public Person getPerson( @Name ( "personId" ) int personId){
return personDB.getPerson(personId);
}
public List<Score> getScores( @Source Person person) {
return scoreDB.getScores(person.getIdNumber());
}
因此,我们可以通过添加与响应类型匹配的@Source
参数来添加合并到输出中的字段。
部分结果
上面的示例合并了两个不同的数据源,但是比分系统下降了。 然后,我们仍将返回我们拥有的数据以及分数的错误:
{
"errors" : [
{
"message" : "Scores for person [797-95-4822] is not available" ,
"locations" : [
{
"line" : 5 ,
"column" : 5
}
],
"path" : [
"person" ,
"scores2"
],
"extensions" : {
"exception" : "com.github.phillipkruger.user.graphql.ScoresNotAvailableException" ,
"classification" : "DataFetchingException"
}
}
],
"data" : {
"person" : {
"names" : [
"Christine" ,
"Fabian"
],
"surname" : "O'Reilly" ,
"scores2" : null
}
} }
纯模式
让我们以纯模式运行此示例(使用graalvm-ce-java11-19.3.2):
mvn -Pnative clean install
这将创建一个本机可执行文件,现在将很快启动该应用程序:
./target/quarkus-example- 1.0 . 0 -SNAPSHOT-runner
![](https://i-blog.csdnimg.cn/blog_migrate/7cd81532e4ecaa52f4c0fa37d0840e67.png)
在管线中
这是MicroProfile GraphQL Spec的第一个版本,管线中有很多东西。 其中之一是客户。 我们建议两种类型的客户:
动态
动态客户端将允许您使用构建器来构建查询:
// Building of the graphql document. Document myDocument = document(
operation(Operation.Type.QUERY,
field( "people" ,
field( "id" ),
field( "name" )
))); // Serialization of the document into a string, ready to be sent. String graphqlRequest = myDocument.toString();
有关更多详细信息,请参见: github.com/worldline/dynaql
输入安全
类型安全的客户端将更接近MicroProfile RESTClient。 查看与上述相同的示例,让我们看看如何使用它。 从项目的根目录,浏览到quarkus-client
文件夹。 本示例使用Quarkus命令模式进行查询。
客户端还不是Quarkus扩展,因此我们将其添加到我们的项目中,如下所示:
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-graphql-client</artifactId>
<version>${smallrye-graphql.version}</version> </dependency>
现在,我们可以创建一个POJO,该POJO仅包含我们感兴趣的字段。在客户端模块中查看Person
和Score
,它比服务器端的定义小得多:
![](https://i-blog.csdnimg.cn/blog_migrate/d17dbebb3cd48b649806fcbed55b91e4.png)
现在我们需要做的就是添加一个接口,该接口定义我们感兴趣的查询:
@GraphQlClientApi public interface PersonGraphQLClient {
public Person person( int personId); }
现在我们可以使用:
//@Inject
//PersonGraphQLClient personClient; or
PersonGraphQLClient personClient = GraphQlClientBuilder.newBuilder().build(PersonGraphQLClient. class );
// ...
Person person = personClient.person(id);
运行Quarkus客户端应用程序,我们现在可以调用服务器(确保它仍在运行)并打印响应:
java -jar target/quarkus-client- 1.0 . 0 -SNAPSHOT-runner.jar 2
在我们的示例中,数字(2)是personId
:
![](https://i-blog.csdnimg.cn/blog_migrate/e99294b4309302d091bc07c82ff0bd45.png)
摘要
这是MicroProfile GraphQL的简短介绍,现在Quarkus中可以使用。 还有更多功能 ,甚至还有更多计划 ,请继续关注。
翻译自: https://www.javacodegeeks.com/2020/06/supersonic-subatomic-graphql.html
超音速 启动