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 ...
随机推荐
- log4jdbc打印完整SQL
一.log4jdbc简单介绍: log4jdbc是工作在jdbc层的一个日志框架,能够记录SQL及数据库连接执行信息. 一般的SQL日志会把占位符和参数值分开打印,log4jdbc则会记录数据库执行的 ...
- Python学习--13 文件I/O
Python内置了读写文件的函数,用法和C是兼容的. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系 ...
- 蓝桥网试题 java 基础练习 矩形面积交
------------------------------------------------------------------------------------------- 思路见锦囊2 - ...
- We Chall-Training: Stegano I-Writeup
MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...
- 微端游戏启动器launcher的制作之下载篇(系列一)
首先第一篇先讲一讲launcher最核心的功能---下载功能. 这个部分估计得好几篇才能写完,东西比较多也比较杂,慢慢来吧,我的东西也在继续改进中...... 从web上下载文件需要用到几个类,Htt ...
- view里面的tableview顶部被view的导航栏盖住了的问题
在你要显示的控制器的viewDidLoad中添加代码 self.edgesForExtendedLayout = UIRectEdgeNone; 另外记住tableView要遵循代理cell才能显示. ...
- C#用DesignSurface实现一个简单的窗体设计器
System.ComponentModel.Design.DesignSurface是为设计组件提供一个用户界面,通过它可以实现一个简单的窗体设计器. 在构建之前,我们需要引入System.Desig ...
- 在Express的页面模板中的变量的定义与使用总结
前言 最近在使用Express框架中的ejs页面模板趟了些许坑,仅以本文记录总结. 本文简述的均为ejs页面模板. 创建ejs变量的各种方法 1. 在Nodejs定义的ejs变量 ejs由是在node ...
- Codeforce 水题报告
最近做了好多CF的题的说,很多cf的题都很有启发性觉得很有必要总结一下,再加上上次写题解因为太简单被老师骂了,所以这次决定总结一下,也发表一下停课一星期的感想= = Codeforces 261E M ...
- BZOJ 1898: [Zjoi2004]Swamp 沼泽鳄鱼(矩阵乘法)
可以发现,如果没有鳄鱼,那么就是裸地一道题,但是可以发现鳄鱼最多每12次重复,那么就少于12的那部分dp,其他的就矩阵乘法就行了 PS:第一次吧矩阵乘法AC了好开心QAQ CODE: #include ...