经历了从模板渲染到前后端分离的时代,一直在苦苦思考,怎么样才能少干点活(大笑).在某天与前端对接接口时,突然顿悟,既然数据都是从 json 回去的,为什么不能直接使用类似 json 这样的语法来查询呢.在大胆的设想下,设计并实现了一套查询语法,给它起名为 orql(Object Relational Query Language 关系对象查询语言缩写).
就以 V2EX 举例说明一下它的用法
查询首页帖子列表,包括帖子标题 发布时间 回复数量 发帖人名称和头像以及节点名称:query post: [id, title, createAt, commentNum, user: {id, name, avatar}, node: {id, name}].
查看某帖子,包括帖子标题 内容 回复和回复人信息:query post(id = $id): [*, comments: [id, content, createAt, user: {id, name, avatar}], user: {id, name, avatar}]
发布一个帖子:add post: {title, content, user}
当然还支持其他的操作 update delete count 等,在模型方面支持 1:1 1:N N:M N:M 关联,更多的用法也可以通过在 github 中查看 https://github.com/orql/orql-mapper .如有兴趣者可以私聊,加微信大家交流,希望大家可以点一个 star 支持.
我的梦想是做一个可以让编程也自动化的程序员,擅长代码抽象和生成,希望有共同兴趣的人大家能一起交流.
|  |      1binux      2019-03-03 11:21:18 +08:00 via Android  2 GraphQL | 
|  |      2qiuxiaojie OP @binux 是的呢,在写的时候也参考了 graphql,做了一些简化 | 
|  |      3J0G57faC6uPo75W0      2019-03-03 11:25:31 +08:00 via Android  2 GraphQL apijson 你可以去 Github 上看一下 和你的需求很像 | 
|      40ZXYDDu796nVCFxq      2019-03-03 11:27:29 +08:00 via Android  31 每个注册用户分配一个 MySQL 账号就行了 没有中间商赚差价,DBA: 前端后端你们都失业了,让我来 | 
|  |      5xianxiaobo      2019-03-03 11:27:51 +08:00  2 之前有个人天天打广告推荐 apiJson,跟你的想法一模一样,你跟他讨论一下? | 
|  |      6qiuxiaojie OP  1 @Tomotoes 是的,你可以比较一下与它们的门槛或者语法简洁度,我的更胜一筹(自信脸) | 
|      7alamaya      2019-03-03 11:29:30 +08:00 后端不用写 CRUD,那感觉大部分后端都可以下岗了 | 
|  |      8Cooky      2019-03-03 11:29:40 +08:00 via Android 你的梦想 = 失业( | 
|  |      9qiuxiaojie OP @gstqc 正在计划在这个基础上开发一个 baas 系统 | 
|      10lihongjie0209      2019-03-03 11:33:10 +08:00  11 一个软件是复杂度守恒的,你后端简单了, 那么前端的复杂度就增加了。 随便说几个问题: 事务怎么控制? 后续需要拓展怎么办?添加一个帖子的时候同时建立搜索索引? 改一个 BUG 前端发一个版本?小程序, 安卓,IOS 怎么办? | 
|      11limingjie138      2019-03-03 11:35:08 +08:00 via iPhone  1 还没实习的我即将感受到失业的压力 | 
|  |      12winglight2016      2019-03-03 11:36:04 +08:00  2 这想法太多重复了,做出成品的也有很多,发展到很大然后倒掉的也有,比如:parse-server。前端、后端、前后端、纯配置、配置加代码生成、拖拽 UI、拖拽 SQL,我都试过了,最终结论是,并不能省下多少时间,除非你的项目全部就是 CRUD,只要还想跟别的 feature 集成,那就准备好填坑吧 | 
|  |      13qiuxiaojie OP @lihongjie0209 在我自己的项目应用中目前来说,api 还是在后端,事务有默认查询不走,其他走,或者用调用函数来控制事务.复杂需求另外编写函数实现即可,一般来说一个项目中只有不到 5%的 api 需要另行编写函数支持. | 
|  |      14bumz      2019-03-03 11:37:10 +08:00 每当新技术出来的时候,都有失业论云云,然而事实往往是新技术导致对人力资源的需求反而增加了 | 
|  |      15qiuxiaojie OP @winglight2016 没有往可视化这方面,目前项目都是通过将这个作为 orm 来使用,但是后端云化和轻量化是一个必然的趋势 | 
|      16sunorg      2019-03-03 11:43:01 +08:00 via Android 脚手架概念了解一下,连界面都生成了 | 
|  |      17anteros      2019-03-03 11:44:46 +08:00 要有多简单,就有多复杂 | 
|  |      18msg7086      2019-03-03 11:47:45 +08:00 后端拿掉就等于没有了后端权限控制,拿到 ORM 就等于可以往数据库里随意写数据了。不知道这个怎么解决。 | 
|  |      19Junn      2019-03-03 11:48:48 +08:00 某天,“ XXX,没什么事,学一下前端,看前端最近挺忙的,到时候可以帮一下!” | 
|      20Cbdy      2019-03-03 11:48:59 +08:00 via Android 小心成为 IT 民科 | 
|  |      21qiuxiaojie OP @msg7086 目前准备设计的 baas 是通过路由来开控制权限,前端不能直接执行语句,很多 baas 厂商把权限全部下放的确会造成很多问题 | 
|      22hellowes      2019-03-03 11:54:47 +08:00 后端哪有这么简单,业务复杂度,还有各种权限的设置,你以为你能搞定全部?就算可以,那后期维护扩展,甚至微服务呢? | 
|  |      23askfilm      2019-03-03 12:02:50 +08:00  1 | 
|      24RqPS6rhmP3Nyn3Tm      2019-03-03 12:21:03 +08:00 protobuf? | 
|  |      25masker      2019-03-03 12:22:02 +08:00 via Android  5 怪不得前端圈那么乱,是个前端都想着重定义。 | 
|      26maemual      2019-03-03 12:25:28 +08:00 via iPhone 后端不用写了,前端不是还得写?有什么本质区别? | 
|  |      27hxt      2019-03-03 12:35:29 +08:00 值得鼓励,不过也是在为用的人挖坑。 | 
|  |      28qiuxiaojie OP | 
|  |      29qiuxiaojie OP @masker 设计风向都两年一大变了,前端业务比后端迭代快太多,ps 我是一个后端而已 | 
|  |      30qiuxiaojie OP @maemual 原则上全部的业务都是还需要开发,只是提升开发效率和减低开发门槛 | 
|  |      31hxt      2019-03-03 13:02:08 +08:00 mongodb、postgresql 是用 json 查询存储的,部分语法可以借鉴他们的。 | 
|  |      32qiuxiaojie OP @hxt 是的,最开始的时候一度考虑使用 mongodb 作为后端数据库,后来因为事务和关联查询原因最后放弃了 | 
|      33hellowes      2019-03-03 13:20:37 +08:00 @qiuxiaojie 可能对一些小项目玩玩还可以,但是对于一些特殊的场景,总是很难完全适用的。    比如大数据量拿出来要进行一些转换操作,你是放在前端一块块来处理,还是交给后台高性能服务器处理? 还有服务器性能有限,有一些接口处理的比较慢,除了你这个接口,还有没有更扩展的方式? | 
|      34hellowes      2019-03-03 13:22:16 +08:00 @qiuxiaojie 为什么很多人包括我都反感你这套东西呢?就是怕老板以为这个开源能替换后端,然后让我们都失业了,lol | 
|  |      35xuanbg      2019-03-03 13:26:10 +08:00  1 完全没必要排斥 CRUD。我现在基本都是复制一下另一个项目的代码,然后根据业务逻辑修改一下就交付。有时候改动比较少,有时候就改得比较多了,除了大的框架结构,基本上留不下多少。如果是前一种情况,搞个通用框架似乎也不错,但这种情况其实并不多,更多的是修改其中的约 40%的代码。这种情况,通用框架其实是很尴尬的,要满足需求,框架本身就会变得非常复杂,而且会越来越复杂。。。基本上会和你的初衷背道而驰。。。所以,你需要的其实不是一个通用框架,而是一个通用模板。只要模板设计得好,真的是无论什么需求都可以往上套的。 | 
|  |      36k9990009      2019-03-03 13:43:18 +08:00 via Android 简单的还好,需求复杂的,要深度使用的必然会有问题,需要定制。 | 
|  |      37qiuxiaojie OP @hellowes 这个只是一个用更简单的方法来操作数据库的框架,它并不包含其他的功能,有考虑在该基础上封装一个 baas,这个 baas 会比较适合数据类型的后端,对于其他功能还是需要靠写原生的代码函数来支持 | 
|  |      38qiuxiaojie OP @xuanbg 这个就涉及到静态抽象与动态抽象的问题,基本上复制的形式为导致维护困难,当然一次交付后续就不需要继续例会的情况下复制也是一种很好的选择 | 
|  |      39qiuxiaojie OP @k9990009 也支持原生 sql 的查询,有类似 mybatis 这种的映射机制 | 
|      40notreami      2019-03-03 14:40:35 +08:00 前端们,你们学前端的初心是什么? | 
|  |      42cpdyj0      2019-03-03 14:53:23 +08:00 会想起上古时代没有后端,客户端直接 ODBC 挂数据库,需要权限控制就拿存储过程+数据库系统权限实现 | 
|  |      43otakustay      2019-03-03 15:16:41 +08:00 光看标题感觉前端和你有仇…… | 
|  |      44qiuxiaojie OP @otakustay 有一些调皮的前端想自己折腾的时候,这个会帮到,哈哈 | 
|      45lynskylate      2019-03-03 15:33:55 +08:00 via Android parse server,leancloud 了解一下,我之前也写过类似的,对接内部多个存储源,发现理想很丰满,现实很骨感。难点不在于抽象 crud,而在于后端不仅仅是 crud,有些处理必须在后端做,你前端想描述这个处理,最终还是得用 dsl 来描述,最终并不能节省时间。最后那个系统用来抽象出多个数据源的接口用来离线处理了。 | 
|  |      46ipwx      2019-03-03 15:34:16 +08:00 @qiuxiaojie API 是抽象层。API 是抽象层。API 是抽象层。 因为很重要所以说三遍。 - - - - 现在很多人遇到的项目都是单机单数据库,久而久之,就以为后端就是 CRUD 这么简单的事情。 拿掉后端,先不说上面很多人提到的安全性怎么处理的问题。 如果如果你的用户增长了,系统要升级为数据库集群层 + 应用集群层 + 负载均衡层。 如果你前端只是负责 call API,那前端那坨复杂的代码就能不动,运维同学专心做负载均衡和数据库集群,写应用的同学可以保证 API 不变的情况下升级为应用集群。如果还不够,你还可以上自研数据库的道路,比如魔改一个版本的 MySQL。 但如果你前端全包了,你想像一下,你那坨代码该怎么改? | 
|  |      47qiuxiaojie OP @lynskylate @ipwx 目前来说我们自己应用这些是在服务器直接写的,只是说前端可以参与,他们并没有在前端的 js 里直接调用,暴露成 api 给前端,分库分表这方面有开始在着手了,会提供一个规则,然后在这里对生成的 sql 进行自动分库分表 | 
|  |      48janxin      2019-03-03 16:19:02 +08:00 分布式事务怎么做? | 
|  |      49xuanbg      2019-03-03 16:24:34 +08:00 @qiuxiaojie 通过模板建立项目怎么会导致维护困难?这个点无法理解。。。模板起的作用无非是提供一个规范的框架结构和一些可能用得上的代码而已,后面该怎么写还是怎么写。 | 
|  |      50qiuxiaojie OP @janxin 目前的计划是提供分库分表的简单支持,分布式事务得依赖第三方中间件或者使用 newsql 做后端数据库 | 
|  |      51qiuxiaojie OP @xuanbg 就像写代码写一个函数不用库使用复制的方式,一旦调整或者优化就会带来很大的麻烦 | 
|  |      52qiuxiaojie OP @janxin 分布式这块的愿景是做到透明化 | 
|  |      53janxin      2019-03-03 16:47:15 +08:00 @qiuxiaojie 目前看起来就是比较简单的业务是才能适用了...这种完全可以抛开后端简单方案实现 | 
|  |      54qiuxiaojie OP @janxin 目前这个是一个用 orql dsl 来查询的框架,还没有支持到抛开全部后端,现在项目也是通过后端编写函数来处理这样来运行,有计划在这个基础上开发一个 baas,然后复杂的业务通过函数来处理 | 
|      55nimrc      2019-03-03 17:09:31 +08:00 via iPhone 和我想法类似 之前也开发过 baas | 
|      56nimrc      2019-03-03 17:10:19 +08:00 via iPhone 难点在于权限控制 | 
|      57deletelazy      2019-03-03 17:10:22 +08:00 via iPhone serverless 了解一下 | 
|  |      58daryl      2019-03-03 17:12:39 +08:00 via iPhone 没有银弹 | 
|  |      59qiuxiaojie OP @nimrc 目前是通过路由直接控制权限,前端不能直接执行语句 | 
|  |      60qiuxiaojie OP @daryl 是的,没有银弹,现在只是一个对数据库操作的 dsl,专注的是提升效率和减低门槛,并不能解决全部问题 | 
|  |      61hikarugo      2019-03-03 17:24:10 +08:00 只有我觉得 nodejs 节点的配色风格还挺好看的吗。。。 | 
|  |      62Vegetable      2019-03-03 18:33:35 +08:00 复杂度守恒 | 
|      63bnlt      2019-03-03 18:42:23 +08:00 可以看一下 postgraphile,算是比较成熟,权限问题也基本解决了,但数据库必须是 postgresql。 一般项目已经可以不要后端,但是改要一个 DBA [手动狗头] https://www.graphile.org/postgraphile/ | 
|  |      64qiuxiaojie OP @Vegetable 还有的程序员认为只有打孔才是编程 | 
|  |      65akira      2019-03-03 18:50:13 +08:00 这不就是 rest 了么。。 | 
|  |      66qiuxiaojie OP @bnlt 有参考了 graphql 的语法,然后对它做了简化 | 
|      67jzmws      2019-03-03 19:14:10 +08:00 我的想法还是前端只展示,后端提供数据  , crud 可以在前端写,要是核心的部分是否容易被攻击 ? | 
|  |      68version      2019-03-03 19:31:23 +08:00 事务,并发,数据权限,限制是个问题.. nodejs 写 20 个 crud.不是很容易么 sequelize 那么强大.mongodb 也有 orm 前端传对象直接插入 json 就好.业务限制就覆盖判断 json 字段. 增加表字段就改 Schema nodejs 重启完事. 前后分离的时候.不能因为为了减少服务端自己的工作量而增加别人的逻辑负载 等你有一天写全栈就知道了..十几张表往上.或者 mongo..为了应对后期需求修改. crud:前端需要 80%, 服务端 20% 的时间分配. | 
|  |      69qiuxiaojie OP @jzmws 现在都是在后端编辑 orql 暴露成 api 给前端调用,然后前端可以根据他们需要自己去编写,在前端直接写会面临很多问题 | 
|  |      70xuanbg      2019-03-03 19:51:47 +08:00 @qiuxiaojie 模板不是你所想的这种场景使用的。。。公共的代码,自然是抽到一个公共的包里面提供 api 来调用的。模板解决的是那种结构相同、事物不同的问题。譬如你要管理客户数据、商品数据等等,都是简单的增删改查。这个时候,要做一个通用的增删改查组件是费力不讨好的,但模板就能派上用场了。复制一个服务实现类,基本上改改里面的实体类,再针对管理的数据特征,做一些特殊化的处理,就出来一个全新的服务了。 为什么说做通用组件不讨好,因为很难将这些不同对象的特性从逻辑上完全剥离,从而将共性抽象成一个公共组件。硬要割裂这些特性和共性之间的逻辑关系,只会把简单的事情搞复杂,这个是软件工程中应该首先避免的事情。 | 
|  |      71qiuxiaojie OP @version 我就是一个全栈,前端 app 都有开发,所以也很了解前后端数据对接是一件不容易的事情。这个框架的设计也站在前端这些需要使用数据的角度去考虑,前端根据 orql 就可以很容易知道返回的数据的结构,能节省很多的双方沟通时间。 | 
|  |      72richard1122      2019-03-03 20:41:06 +08:00 话说楼主有没有用过 leancloud 或者 firebase 的数据库,他们一大特点就是靠权限配置、直接让前端访问数据库,可以做到理论上无服务端开发。 https://leancloud.cn/docs/storage_overview.html https://firebase.google.com/docs/firestore/ 想听听楼主的看法? | 
|  |      73qiuxiaojie OP @richard1122 有试用过,权限这块怎么说呢,它们都是在每一个表甚至每一条记录里面去控制,但是实际使用的确会造成很多困扰,一不小心容易导致出现问题,而且 api key 这些直接暴露了,整个应用的数据都不安全. | 
|  |      74version      2019-03-03 20:59:52 +08:00 @qiuxiaojie  现在前端用 vue 或者 react 基本也是组件开发.其实组件抽象起来就是表的结构.一般给全部表字段或者数据库他们访问.或者服务端数据库定义 Schema 代码..基本对接 api 是能看懂的了.根本不需要那么复杂的了..你写一套框架.很多人不一定接受的呢.框架还要看 api....前端传的 key 和服务端和数据库不一样的时候.排查沟通也累.. 还有现在基本都是内部 rpc 微服务开发(特别是 nodejs) .给前端 sql 操作不符合,复杂业务需求解藕.分布式部署和某个小业务迁移重构 | 
|      75eurokingbai2      2019-03-03 21:10:43 +08:00 GraphQL 这种技术对 REST 架构约束造成了极大的破坏,长久的话可能不利于 Web 发展。我可以按照 Roy Fielding 博士论文的理论进行解释: 1 )破坏了缓存约束,最直接的后果是传统的分层代理、缓存中间件不能有效命中前端的查询结果,因此极其不利于系统的可扩展性。 2 )这个类似于远端执行( REV )约束了,而 Roy Fielding 早有断言该约束不可取,主要是破坏了可见性。一方面因为前端传来的代码愈发不可控不安全,后端审查起来存在较大苦难;另一方面,后端线程和进程间的代码可见性也被破坏,分布式事务等请求无法保证。 这类技术是个不错的 Trick,但不适合大范围使用。 | 
|  |      76qiuxiaojie OP @version @eurokingbai2  这个是在后端用的查询 dsl,并不像 graphql 那样做的是前端请求数据格式的描述,是发送给数据库的请求数据格式描述 | 
|      77eurokingbai2      2019-03-03 21:30:59 +08:00 @qiuxiaojie 一样的。莫非你的意思是完全不要 Web 了?直接让数据库做后端暴露接口? | 
|  |      78skadi      2019-03-03 22:09:23 +08:00 GraphQL | 
|  |      79qiuxiaojie OP @eurokingbai2 肯定不能这样,是这个 dsl 起到 sql 的作用 | 
|      80WispZhan      2019-03-03 22:46:59 +08:00 via Android OData | 
|      81xingxing09      2019-03-03 23:21:23 +08:00 永远信不了端上来的数据 | 
|  |      82qiuxiaojie OP @xingxing09 是的,所以没有在前端的代码里直接执行 | 
|  |      83kajweb      2019-03-04 00:14:58 +08:00 微信小程序云开发? | 
|  |      84gavinjou818      2019-03-04 08:18:55 +08:00 突然感觉不会是这好事。。如果命令在前端被修改了会怎么办?数据会不会泄漏问题 | 
|  |      85qiuxiaojie OP @kajweb 可以用于微信小程序开发 | 
|  |      86qiuxiaojie OP @gavinjou818 我在附言里面解释过了,这是一个 orm 框架,建议是在后端使用,当然如果前端非要用做好控制也不是不可能,但是不建议 | 
|  |      87passerbytiny      2019-03-04 09:06:59 +08:00 我以前见过更简单的,给了表结构,能自动生成全套 CRUD,包括界面,前端后端都可以扔了,弄个运维就够了。然而,绝大部分功能不是只有 CRUD,所以前后端还好好活着。 | 
|      88jxgccaaron      2019-03-04 09:08:44 +08:00 via iPhone 玩玩还行,真的用起来各种非 curd 场景不满足,而且为了满足一些小特性,开发起来还是蛮大工作量的,所以还比不上 curd 快 | 
|  |      89qiuxiaojie OP @passerbytiny @jxgccaaron 看一下附言,生成全套 curd 是不可能的事情,十几张表组合起来的数量就很惊人了,另外这是一个 orm 框架,非 curd 本身就是不支持的. | 
|  |      90reus      2019-03-04 09:33:27 +08:00 是 CRUD,不是 CURD | 
|  |      91fy      2019-03-04 09:39:41 +08:00 GraphQL 了解游戏王 另外我有过相关的实践,后端权限配置+Model 写好自动生成 api 接口,只不过没文档就不细说了 | 
|  |      93qiuxiaojie OP @reus 谢谢指正 | 
|  |      94qiuxiaojie OP | 
|  |      95t2doo      2019-03-04 10:08:07 +08:00 CURD 数据库增删改查,CRUD 计算处理时增删改查,这 2 种是 1 种东西还是 2 种东西,好苦恼:P | 
|  |      96kwanCCC      2019-03-04 10:12:59 +08:00 我有一个梦想是 前端 不用写 CRUD, 正在开发能大幅度减低 curd, 甚至让 后端 来写 curd 的框架,希望大家多多关注与支持 | 
|      97sarlanori      2019-03-04 10:41:47 +08:00 之前微博上有个数据库大神 **zhh-4096** 撸了个前端数据库操作框架 `lealone-js`,了解一下: https://github.com/lealone/Lealone-Platform/tree/master/lealone-js/src/test/js ``` <!doctype html> <html> <head> <script src="sockjs-1.1.2.js"></script> <script src="lealone-5.0.0.js"></script> <script src="generated/model/User.js"></script> </head> <body lang="en"> <h1>Frontend crud test, see console log</h1> <script> var cb = function(message) { console.log(message); } User.dao.delete(cb); // insert new User().name.set("zhh").phone.set(123).insert(cb); // find one record User.dao.where().name.eq("zhh").findOne(cb); // update User.dao.notes.set("a notes").phone.set(123).where().name.eq("zhh").update(cb); // delete User.dao.where().name.eq("zhh").delete(cb); new User().name.set("u1").phone.set(123).insert(cb); new User().name.set("u2").phone.set(123).insert(cb); User.dao.findCount(cb); User.dao.where().name.like("u%").findList(cb); </script> </body> </html> ``` | 
|  |      98fcoolish      2019-03-04 10:47:14 +08:00 把数据库查询放到前端来做,那事务控制,权限认证,和数据一致性怎么保证,还有后端高并发的限流熔断,你都直接查数据库了,后端怎么控制。这都是很常见的问题把,我觉得前端做好数据渲染和界面交互就行了。 | 
|  |      99xmbaozi      2019-03-04 10:51:55 +08:00 不会真都以为后端只写 curd 吧 | 
|  |      100qiuxiaojie OP @sarlanori 比较一下你就会发现这种链式的查询操作是很繁琐的 insert => add user: {name} update => update user(id = $id): {name} delete => delete user(id = $id) count => count user like => query user(name like 'u%'): [*] 我把你写的用 orql 写了一下 |