GraphQL初探:Java服务示例及Yahoo/Elide
周末想理一理一件事可不可以干,大致上就是:假设存储各种各样的数据,如何保证读取是足够灵活的——用户只需声明式地说明需要什么内容,而接口就可以完成工作。简单理解就是一个接口完成所有功能。做了些GraphQL入门,初步感觉还不错。
1. 什么是GraphQL?
GraphQL本身只是个查询规范,管查询不管实现。自行搜索吧,本人已经对写入门文章不感冒了,网上的介绍一大堆。推荐How To GraphQL,只需要4个视频合计42分钟,就可以了解到GraphQL的方方面面,实现上的一些要点也是有所涉及。着重需要理解两点:
- Schema文件:不仅仅包含字段类型、关系,还包含查询方法,整体与thrift的RPC定义相似;Java中一般大量使用到Bean的映射,额外一份定义文件有点繁琐。
- Resolvers:拼接的每个字段都对应一个Resolver。这里就是服务优化的关键点了,GraphQL本身不关心后端需要进行什么操作,也有很大的优化空间。
2. GraphQL的基础Java服务
Java项目示例Getting Started with Spring Boot,项目可以从graphql-java/tutorials下载,代码有些特点:
- 需要一份
schema.graphqls
定义 - 需要一份Java Bean定义
- 需要对schema中的的每一个字段定义DataFetcher
- DataFetcher与shema中的内容做
Wiring
这样看来想做一个灵活的API查询还是很麻烦的。
3. 基于Elide的GraphQL服务
什么是Elide?(本人是从开源中国的日更中得知,看来对开拓眼界还是有帮助的)
Stand up {json:api} & GraphQL web services backed by JPA annotated models in 4 simple steps
特点:
- 无需重复的Schema定义,回到了人见人爱的Java Bean注解(JPA);
- 定义了一整套完整的查询/更新机制;
- Resolver相关的工作隐藏在了JPA背后,大大降低了代码难度。
从项目的介绍以及相关示例项目来看,基本可以推断:
- 在GraphQL推出的前后,各家公司包括Yahoo!在内,都在做着类似的事情,只不过Yahoo没有画大饼,只是想做一套灵活的Json API
- Json API这一套能够很容易地实现GraphQL
- Yahoo!没有死,技术仍然不弱
3.1 示例项目1:官方的elide-blog-example
体验GraphQL需要增加一点点内容开启:
-
Main.java
增加GraphQL的Endpoint// graphql final ServletHolder graphqlServletHolder = servletContextHandler.addServlet( ServletContainer.class, "/graphql/*"); graphqlServletHolder.setInitOrder(2); graphqlServletHolder.setInitParameter( "jersey.config.server.provider.packages", GraphQLEndpoint.class.getPackage().getName()); graphqlServletHolder.setInitParameter( "javax.ws.rs.Application", ElideResourceConfig.class.getCanonicalName());
-
pom中增加依赖
<dependency> <groupId>com.yahoo.elide</groupId> <artifactId>elide-graphql</artifactId> <version>4.4.5</version> </dependency>
测试需要使用 http://localhost:8080/api/graphql/v1
这个项目是极简的Servlet项目,可能整合其它的东西会有点麻烦(比如视spring为所有java web服务的我),这个时候可以使用elide-spring-starter来与spring进行整合。
3.2 示例项目2:elide-spring-boot-sample
检出illyasviel/elide-spring-boot整个项目,打开elide-spring-boot-sample,在pom中增加依赖开启GraphQL支持
<dependency>
<groupId>com.yahoo.elide</groupId>
<artifactId>elide-graphql</artifactId>
<version>${elide.version}</version>
</dependency>
测试使用http://localhost:8080/api/graphql/
3.3 Elide中的GraphQL查询
如果不认真读文档,可能真的话怎么都试不出来elide的url是什么,试出来url了又会觉得elide的查询怎么跟教学视频里面不一样,怎么都试不出一个正确的。
Elide的GraphQL不是那种很直观的,比如一个典型的查询是这样的。
{
user {
edges {
node {
id
username
password
}
}
}
}
这就涉及到Elide的设计和封装了
当然,graphql-playground这样的工具可以自动拉取schema(连上后服务会一直打日志,可别以为循环?报错了),如果能够通过schema写出上面的查询,也能说明对GraphQL查询的理解达标了(恭喜!)。
好好读文档还是有必要的。
3.4 Elide Datastore
Datastore 能与Hibernate OGM 结合,并没有找到一些案例,需要实验实验了。如果能够通过OGM再引入mongodb,应该还是非常不错的,值得研究研究。
4. GraphQL-playground
很方便的工具,输入完URL就会自动拉取schema并提供doc/schema的浏览(这个时候服务一直会打日志,没有问题的,别跟我一样大惊小怪),很方便。还有一些替代品可以使用,就不多介绍了。 下面是一个通过doc浏览来理解elide的内容查询的图,看看就好。
5. 小结
- GraphQL是一个查询规范,由客户端描述需要的资源,资源的拼接由服务端完成,并且只返回客户端所要求的;
- 实现GraphQL的服务包括schema和resolver两块
- 可以从graphql-java实现(可以了解更多细节,也更灵活),也可以基于Elide的JPA实现(如果正好符合需求就是非常幸运了)。