Jsonql——给RESTful API插上一对翅膀
RESTful API是目前比较成熟的一套互联网应用程序的API设计理论,规范了服务端资源的定义及访问。我们团队服务端就采用了RESTful。
可是在现实开发过程中,还是有些问题。
客户端在获取资源的时候,可能不同地方需要资源的不同的属性,而服务端常常会把几乎所有属性全部返回,这在App上会造成一些流量的浪费,譬如我要加载一个普通的产品列表,需要产品图片、产品名称、价格、库存等属性,而另一个浏览历史可能只需要名称和价格,这总不能写两个API吧?或者说附带一个请求参数告诉服务端要返回哪些属性,这倒行得通,可很不优雅。
重要的是客户端还会有一个界面可能需要调用多个不同类型的资源的情况,最经典的就是电商App,个人中心界面里,既需要用户的一些信息,又要查询收藏数量、关注数量、足迹数量,又要查询不同状态下的订单数量,或者下方还有推荐商品列表。客户端一个界面请求多个资源URI会降低客户端的体验自然不好,或者需要服务端需要额外提供适配客户端的API能解决,可一旦界面有变化这些接口也要重新做适配。
这些问题不是很重要,可问题多了,客户端开发和服务端开发要掐架。
有没有相对好的解决办法呢?
本人不才,搞了个 Jsonql(https://github.com/liyanjie8712/Jsonql),意图给RESTful按上一对翅膀。
Jsonql是什么,咱给它起了个高大上的名字,Jsonql = Responsive Json Query Language,响应式Json查询语言,客户端要什么样的数据,由客户端来决定。服务端只提供资源及支持的查询函数,客户端编写查询请求,服务端解析并组装数据返回给客户端。这下服务端一劳永逸,客户端界面及数据绑定随便折腾去吧,挖哈哈~
先来看看Jsonql的语法:
变量的定义:$变量名
变量必须先定义后使用,所有在定义前的引用都是错误的。
变量具有作用域,只在当前定义它的 “{}” 及嵌套的子 “{}” 内有效,同时子作用域会覆盖父作用域定义的同名变量。例:$abc。
资源的引用:资源名[]
资源名必须与服务端公开的资源列表中的名称一致并区分大小写。
例:users[]。
方法的调用:.方法名(参数)
例:.where(age>=18).count()。
字段的访问:.字段名
例:.user.name。
资源的枚举:=>$
使用资源访问符 “=>” 对资源进行枚举,“=>” 左侧定义资源的引用,右侧定义资源的输出(类似javascript对象)。
如果右侧定义以 “[]” 结尾,则表示遍历资源输出一个数组,否则表示只输出索引为0的元素。
“$” 表示对资源中元素的引用。
定义输出时,输出字段与元素字段名称一致时,可以省略 “$.”。例:users[] => { uuid:$.id, name, age }
使用表达式:{{表达式}}
使用表达式可以执行一些运算操作,包括四则运算、逻辑运算、位运算等。 表达式必须使用“{{}}”包括,其运算结果为一个值。 表达式中可以使用变量,可以访问属性,但不可使用资源,不可调用方法。
例:{{ 1 + 2 - 3 * 4 / 5 % 6 }}、{{ $abc > 0 }}、{{ true ? 1 : 0 }}
写个查询的Demo,就拿用户与订单来:
{
//获取用户信息
user: users[].where(id==1) =>
{
uuid: $.id, //ID
username, //用户名
avatar, //头像
account:
{
coins: $.account.coins,
points: $.account.points
}
},
//定义一个订单资源的变量
$orders: orders[].where(user.id==1),
//订单不同状态下的数量
orderCount:
{
created: $orders.count(status==1),
payed: $orders.count(status==2),
delivered: $orders.count(status==3),
completed: $orders.count(status==4)
},
//后去该用户的订单列表,前10条数据
orders: $orders.orderBy(createTime).skip(0).take(10) =>
{
uuid: $.id, //ID
serial, //订单号
status //订单状态
}[]
}
将要返回什么数据呢?来看看:
{
"user": {
"uuid": 1,
"username": "abcdefg",
"avatar": "http://img.xxxx.com/avatars/1.jpg",
"account": {
"coins": 8888,
"points": 9999
}
},
"ordercount": {
"created": 0,
"payed": 2,
"delivered": 1,
"completed": 18
},
"orders": [
{
"uuid": 1,
"serial": "00001",
"status": 2,
},
{
"uuid": 2,
"serial": "00002",
"status": 2,
},
//…………
]
}
查什么返回什么,是不是方便多了?并且支持Linq Method,搞C#的童鞋是不是很眼熟?当然还支持动态表达式计算,譬如:
{
$abc: 1,
$def: 2,
result: {{$abc + $def + 3}}
}
返回结果:
{
"result": 6
}
Jsonql只是为了让查询更好用,资源的增删改操作还交给RESTful吧。
就到这里。目前Jsonql支持AspNet与AspNetCore,GitHub里带有简单的Demo,有兴趣的童鞋可以下载下来玩一玩,相应的依赖包已发布到:http://myget.org/gallery/liyanjie。
觉得不错就给颗星吧,另外欢迎大牛指导一二,不胜感激。
Jsonql——给RESTful API插上一对翅膀的更多相关文章
- 插上翅膀,让Excel飞起来——xlwings(二)
在上一篇插上翅膀,让Excel飞起来——xlwings(一)中提到利用xlwings模块,用python操作Excel有如下的优点: xlwings能够非常方便的读写Excel文件中的数据,并且能够进 ...
- Spring Boot (六): 为 JPA 插上翅膀的 QueryDSL
在前面的文章中,我们介绍了 JPA 的基础使用方式,<Spring Boot (三): ORM 框架 JPA 与连接池 Hikari>,本篇文章,我们由入门至进阶的介绍一下为 JPA 插上 ...
- 时序数据库(TSDB)-为万物互联插上一双翅膀
本文由 网易云发布. 时序数据库(TSDB)是一种特定类型的数据库,主要用来存储时序数据.随着5G技术的不断成熟,物联网技术将会使得万物互联.物联网时代之前只有手机.电脑可以联网,以后所有设备都会联 ...
- 在Ubuntu上快速搭建基于Beego的RESTful API
最近在研究Go,打算基于Go做点Web API,于是经过初步调研,打算用Beego这个框架,然后再结合其中提供的ORM以及Swagger的集成,可以快速搭建一个RESTful API的网站. 下面是具 ...
- restful api上传文件(基础)-springboot
基于restful api格式的文件上传(只是上传到本地): package com.nxz.controller; import com.nxz.entity.FileInfo; import or ...
- 请求与上传文件,Session简介,Restful API,Nodemon
作者 | Jeskson 来源 | 达达前端小酒馆 请求与上传文件 GET请求和POST请求 const express = require('express'); const app = expre ...
- Flask RESTful API搭建笔记
之前半年时间,来到项目的时候,已经有一些东西,大致就是IIS+MYSQL+PHP. 所以接着做,修修补补,Android/iOS与服务器数据库交换用PHP, Web那边则是JS+PHP,也没有前后端之 ...
- 使用ASP.NET Core 3.x 构建 RESTful API - 1.准备工作
以前写过ASP.NET Core 2.x的REST API文章,今年再更新一下到3.0版本. 先决条件 我在B站有一个非常入门的ASP.NET Core 3.0的视频教程,如果您对ASP.NET Co ...
- elasticsearch查询所有数据restful api以及java代码实现
原文:http://blog.java1234.com/blog/articles/366.html restful api实现如下: get http://192.168.1.111:9200/fi ...
随机推荐
- Spring Boot踩坑之路一
Takes an opinionated view of building production-ready Spring applications. Spring Boot favors conve ...
- 未来手机Alo即将问世!全息投影手机的新高峰!全息3d 网
文章来源:网络 编辑:大熊 [摘要]全息投影手机很早就开始炒,网络上的概念机也是丛出不穷,那么这款出自法国的概念机又是多么的奇葩?全息 3d 网带你一探究竟. 据外媒报道,在不久将来语 ...
- Disruptor深入解读
将系统性能优化到极致,永远是程序爱好者所努力的一个方向.在java并发领域,也有很多的实践与创新,小到乐观锁.CAS,大到netty线程模型.纤程Quasar.kilim等.Disruptor是一个轻 ...
- OVS VxLAN Flow 分析 - 每天5分钟玩转 OpenStack(149)
OVS 的数据流向都是由 Flow 规则控制的,今天我们就来分析 VxLAN 的 Flow 规则.提个醒:这可能是本教程最烧脑的一节,let's rock it ! 下面分析控制节点上的 flow r ...
- 基于C++11的线程池,简洁且可以带任意多的参数
咳咳.C++11 加入了线程库,从此告别了标准库不支持并发的历史.然而 c++ 对于多线程的支持还是比较低级,稍微高级一点的用法都需要自己去实现,譬如线程池.信号量等.线程池(thread pool) ...
- Oracle索引语句整理
转载:http://www.cnblogs.com/djcsch2001/articles/1823459.html 索引,索引的建立.修改.删除 索引索引是关系数据库中用于存放每一条记录的一种对象, ...
- 从0到1学习node(七)之express搭建简易论坛
我们需要搭建的这个简易的论坛主要的功能有:注册.登录.发布主题.回复主题.下面我们来一步步地讲解这个系统是如何实现的. 总索引: http://www.xiabingbao.com/node/2017 ...
- 微信小程序 网络请求之re.request 和那些坑
微信小程序有四种网络请求类型,下面只详细介绍普通HTTPS请求(wx.request) 普通HTTPS请求(wx.request) 上传文件(wx.uploadFile) 下载文件(wx.downlo ...
- BZOJ 1228: [SDOI2009]E&D(SG定理)
这道嘛,很容易就看出是个nim和,然后问题就是怎么算子问题的sg函数了 先暴力个表看下规律,很容易就找出来了~~~(百度空间又渣了,图贴不出来= =) 32 0 1 0 2 0 1 0 3 0 1 0 ...
- 【CNMP系列】CentOS7.0下安装Nginx服务
话步前言,CNMP之路,系统起步:http://www.cnblogs.com/riverdubu/p/6425028.html 这回我来讲解下CentOS7.0下如何安装和配置Nginx服务 Ngi ...