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插上一对翅膀的更多相关文章

  1. 插上翅膀,让Excel飞起来——xlwings(二)

    在上一篇插上翅膀,让Excel飞起来——xlwings(一)中提到利用xlwings模块,用python操作Excel有如下的优点: xlwings能够非常方便的读写Excel文件中的数据,并且能够进 ...

  2. Spring Boot (六): 为 JPA 插上翅膀的 QueryDSL

    在前面的文章中,我们介绍了 JPA 的基础使用方式,<Spring Boot (三): ORM 框架 JPA 与连接池 Hikari>,本篇文章,我们由入门至进阶的介绍一下为 JPA 插上 ...

  3. 时序数据库(TSDB)-为万物互联插上一双翅膀

    本文由  网易云发布. 时序数据库(TSDB)是一种特定类型的数据库,主要用来存储时序数据.随着5G技术的不断成熟,物联网技术将会使得万物互联.物联网时代之前只有手机.电脑可以联网,以后所有设备都会联 ...

  4. 在Ubuntu上快速搭建基于Beego的RESTful API

    最近在研究Go,打算基于Go做点Web API,于是经过初步调研,打算用Beego这个框架,然后再结合其中提供的ORM以及Swagger的集成,可以快速搭建一个RESTful API的网站. 下面是具 ...

  5. restful api上传文件(基础)-springboot

    基于restful api格式的文件上传(只是上传到本地): package com.nxz.controller; import com.nxz.entity.FileInfo; import or ...

  6. 请求与上传文件,Session简介,Restful API,Nodemon

    作者 | Jeskson 来源 | 达达前端小酒馆 请求与上传文件 GET请求和POST请求 const express = require('express'); const app = expre ...

  7. Flask RESTful API搭建笔记

    之前半年时间,来到项目的时候,已经有一些东西,大致就是IIS+MYSQL+PHP. 所以接着做,修修补补,Android/iOS与服务器数据库交换用PHP, Web那边则是JS+PHP,也没有前后端之 ...

  8. 使用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 ...

  9. elasticsearch查询所有数据restful api以及java代码实现

    原文:http://blog.java1234.com/blog/articles/366.html restful api实现如下: get http://192.168.1.111:9200/fi ...

随机推荐

  1. Hibernate核心配置文件

    Hibernate.cfg.xml是Hibernate操作数据库的核心配置文件 *********************************************** 作用 01.管理实体类的 ...

  2. ADO.NET 数据库操作类

    操作数据类 避免代码重用.造对象太多.不能分工开发 利用面向对象的方法,把数据访问的方式优化一下,利用封装类   一般封装成三个类: 1.数据连接类 提供数据连接对象 需要引用命名空间: using ...

  3. 制作jar文件

    一.制作可运行jar文件 使用java的swing.awt制作了一个简单的界面交互模块.程序打成jar包后,能双击运行,制作过程: 1.eclipse →properties →Export,选择ja ...

  4. Java性能优化_转载

    一.避免在循环条件中使用复杂表达式 1.在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快. 2.不可使用多层循嵌套. 二.集合大 ...

  5. C++虚表(V-Table)解析

    C++中的虚函数的作用主要是实现了多态,本人通过代码验证的方式了解虚表的结构及在多种继承方式下通过虚表访问子类函数.验证结果如下: 1)无虚函数覆盖的一般继承:可以通过子类的虚表访问父类的函数 2)虚 ...

  6. ASP.NET连接数据库配置文件

    // Web.Config <?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NE ...

  7. 矩阵求逆的几种方法总结(C++)

    矩阵求逆运算有多种算法: 伴随矩阵的思想,分别算出其伴随矩阵和行列式,再算出逆矩阵: LU分解法(若选主元即为LUP分解法: Ax = b ==> PAx = Pb ==>LUx = Pb ...

  8. VMware WorkStation9.0虚拟机如何运行WINPE

    VMware WorkStation9.0虚拟机如何运行WINPE...我们在使用VMware的过程中,有些时候需要让VMware来运行WINPE系统,比如在使用VMware进行系统封装的过程中,其中 ...

  9. Unity播放Gif动画

    Unity目前对图形图像的支持还不是很完善,支持的图形文件格式有 PSD, TIFF, JPG, TGA, PNG, GIF, BMP, IFF, PICT等,但却不支持Gif动画.但是经过查阅资料发 ...

  10. 解决CenOS 7下启动ActiveMQ时报错

    基于 CentOS 7,ActiveMQ 5.9.1 问题重现 在 CentOS 7 下安装好ActiveMQ后,执行 /usr/local/apache-activemq-5.9.1/bin/act ...