微服务架构下,原来一个完整的应用可能被拆分成若干个功能独立的服务,在PaaS的支撑下各自运行在独立的容器中。
服务之间的同步调用以REST请求为主,这里不讨论异步调用中的事件的发布订阅。
对于访问服务的调用者,首先要装配并发出HTTP请求,然后得到服务的响应后,还需要解析数据转换为内部数据对象。这个过程与业务逻辑无关,而且繁琐难以扩展。尤其是在微服务的架构中,涉及对多个服务的调用,聚合多个服务或一个服务的多次调用,处理十分冗余,而且与业务逻辑之间有gap。如何能够从业务需求的角度统一对服务的调用呢?
GraphQL是Facebook定义的描述与业务相关的数据模型的语言规范,并提供了多种编程语言的实现。看名字是期望能够比肩数据库领域的SQL,成为服务调用领域的标准。
GraphQL位于服务的调用者与服务的提供者之间,提供给调用者统一的、与业务逻辑相关的服务查询语言。
事实上,GraphQL提供了一个类型定义系统,就类似于数据库的Schema定义。通过GraphQL可以定义与业务逻辑相关的数据类型,并为每个类型提供数据访问函数(其实就是设置数据源)。GraphQL使得服务提供者的版本、API等对服务调用者变得透明。服务调用者只需要知道想要的GraphQL类型。
GraphQL可以与服务提供者一起部署,也可以以独立的服务的形式部署。
GitHub已经全面使用GraphQL API替代了原来的REST API。
既然是一种查询语言(类似SQL),就有查询相关的语句。
2. GraphQL支持的指令(Directives)
在定义数据类型时,通过指令可以设置一定的逻辑。
3. GraphQL Schema元数据
4. 示例
1). 定义类型
type Query {
me: User
}
type User {
id: ID
name: String
}
2).定义类型中属性的数据访问函数
public User Query_me(request) {
return request.auth.user;
}
public String User_name(user) {
return user.getName();
}
3).HTTP调用请求
对于GraphQL的query操作,可以是HTTP GET请求,也可以是HTTP POST请求,推荐HTTP POST。
请求的参数示例如下:
{
me {
name
}
}
对于HTTP GET请求,URI示例如下:
http://myapi/graphql?query={me{name}}
实践中,这条路没走通,发出HTTP GET请求时,服务器日志显示错误信息如下:
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
对于HTTP POST请求,body示例如下:
{
"query": "{me{name}}"
}
4).HTTP响应
GraphQL响应的body格式永远为JSON,标准格式如下:
{
"data": { ... },
"errors": [ ... ]
}
示例中的响应的body:
{"data":{"me":{"name": "Xiangbin HAN"}}}
参考链接:
http://graphql.cn/
http://graphql.org/
https://github.com/graphql
英文规范,http://facebook.github.io/graphql/
中文规范,http://spec.graphql.cn/
http://graphql.cn/code/
https://developer.github.com/