SQL 对大多数程序员来说都不陌生,但是 GraphQL 和 PRQL 对大多数程序员来说都是陌生的。本文将对三者进行对比介绍,方便大家在合适的业务场景进行选择。
SQL | PRQL | GraphQL | |
---|---|---|---|
Query | Y | Y | Y |
Update | Y | N | Y |
Subscription | N | N | Y |
几点注意事项:
http://localhost:8080/graphql
。数据库则为jdbc:postgresql://localhost:5432/postgres
。PRQL 可以被翻译为 SQL ,所以接入点跟 SQL 是一样的。SQL 大家都不陌生,举一个根据 ID 查找用户的简单例子来说明一下,查询如下:
select * from user where id = 1000
数据库的工具可以说是最丰富的,如开发者都喜欢的 O/R 映射框架,进行数据更新,可以说是简单的不能再简单了,开发者完全不需要了解具体的 SQL 语法。 当然 O/R 框架在查询方面稍微有点弱,但是在数据库更新操作上,O/R 框架是非常强大的。
GraphQL 是是一种基于类型系统,面向数据的 API 查询语言。 让我们看一下上述 SQL 对应的 GraphQL 查询语言,如下:
{
user(id: 1000) {
name
mobile
birth
}
}
很多同学将 GraphQL 和 HTTP REST API 进行对比,这里我们不做讨论,我们这里主要说明 GraphQL 查询语言的灵活性。
现在有非常多的工具可以为数据库添加 GraphQL 接入,非常简单。 我们都知道数据库连接是非常耗资源的,而 GraphQL over HTTP 则非常轻量级,这种方式在 Serverless 的场景中非常适合。
GraphQL 不足:从上述的样例中我们可以看出,对于一些复杂场景的查询,GraphQL 还是有点力不从心的,如果几个查询条件配合,这个时候 GraphQL 处理起来就比较难啦,要编写特定查询实现,这个和 REST API 实现也是一样的。
PRQL 是一种用于转换数据的现代语言,其主要的特性就是基于数据的管道操作。让我们看一下上述 SQL 对应的 PRQL 查询语言,如下:
from user | filter id == 1000
可以说 PRQL 在查询方面更简单明了,可以说比数据库 select 更强都不为过。
我们都知道架构设计中有一个读写分离(CQRS)原则,当然数据库更新,你选择 SQL ,O/R 框架这些都没有问题。但是在 Query 方面,你可以选择 PRQL ,这样可以让你的数据查询更简单,同时支持快速 JSON 输出。
PRQL 可以被编译为 SQL ,这样就可以在任何数据库上操作,但是其他诸如 NoSQL 产品,PRQL 也更合适。如你想操作 MongoDB ,对应的查询命令如下:
db.inventory.find( {
status: "A",
$or: [ { qty: { $lt: 30 } }, { price: { $gt: 100 } } ]
} )
如果换成 PRQL ,则如下:
from inventory
filter status = "A"
filter qty < 30 or price > 100
这两个谁更容易阅读和理解,我相信大家马上就有自己的答案。
此外 PRQL 还有一个非常强大的特性就是基于数据库的 dialect ,可以将 PRQL 编译为目标数据库的 SQL ,这样你只要关心更通用的 PRQL ,而不需要关注不同数据库的 SQL 差异,数据库的兼容完全不用担心。
回到 NoSQL 场景,虽然 PRQL 是支持编译为 SQL ,但是你也可以自行解析,将 PRQL 转换为为具体的 API 调用或者其他查询语言,从而实现对数据的查询,这个也是没有问题的。
注意: 如果你是基于 PRQL 实现自行解析,然后转换为具体的 API 调用,这种方式可能性能更高。从个人编写 PRQL 的 IDE 插件来看,对比 SQL 的解析,PRQL 的解析更快,这也是 PRQL 也适合 NoSQL 的原因。
目前来说,如果程序非常简单,那么使用 SQL + O/R 框架即可。如果你要为前端(FrontEnd)提供数据访问接口,那么 GraphQL 和 HTTP REST API 是一个不错的选择。 如果你的数据主要集中在查询,那么使用 PRQL 查询、O/R 框架更新可能更合适。另外如果你开发自有的 NoSQL 产品,在接入 SQL 支持前,添加一下 PRQL 的支持,可能也是一个不错的选择。
目前 PRQL 的编辑器支持比较弱一些,不过已经有 VS Code 的插件支持,如果你使用 JetBrains IDE 的话,你可以尝试一下JetBrains PRQL 插件, 语法高亮、代码提示、SQL 自动生成和数据库集成等特性都包含,功能非常不错。
欢迎大家关注我们公众号定期推荐有趣的开发者工具,也欢迎大家加入我们微信群一起讨论和交流:
广告: 开发者的万能工具箱 He3 也发布了新版本,欢迎试用: he3.app
1
zhlxsh 2023-01-13 10:27:27 +08:00 via iPhone
本人做 sre ,之前看到 GraphQL 也想在项目里用一下, 但是内部项目快速上线为主,出问题也是自己维护,所以拿以前的框架套上跑起来就行了😂
|
2
dragondove 2023-01-13 11:34:16 +08:00
@zhlxsh GraphQL 用起来感觉也挺麻烦的,但是可以学习一下他的设计来设计自己的 api ,举例你有一个表(比如叫做用户)关联多个表(比如关联钱包信息表,银行卡信息表),那么你可以这样设计接口
```json { "userId": 23, "returnWallet": true, "returnCards": false } ``` 这个查询条件就表示用户需要 userId 为 23 的这个人的基本信息+钱包信息,但是不需要银行卡列表信息。 你可以默认设置成所有的查询除了基本信息之外都不返回,用户需要的时候传入 returnXXX: true 就给他返回(我个人更喜欢叫做 withXXX ) 如果你的接口是个 RPC 接口,你还可以设计一下字段的设置方式,例如我使用 java ,针对这个入参可以设置几个方法 ```java public UserQuery withWallet() { returnWallet = true; return this; } public UserQuery userId(Long id) { userId = id; return this; } // 剩下省略 ``` 那么 RPC 查询就可以是 ```java UserDetailRes userDetail = userRPC.query(new UserQuery.userId(23).withWallet()); ``` 使用起来也比较流畅 |
3
chenlins 2023-01-14 05:45:57 +08:00 via iPhone
GraphQL 怎么做接口权限啊
|
4
superchijinpeng 2023-01-16 14:44:20 +08:00
@chenlins 参考 GitHub
|