4.1.16 框架之网关协议-RQSL及扩展

一、RSQL / FIQL parser

RSQL是一种查询语言,用于对RESTful API中的条目进行参数化过滤。它基于FIQL(Feed Item Query Language)——一种URI友好的语法,用于跨Atom Feed中的条目表达过滤器。FIQL非常适合在URI中使用,没有不安全的字符,因此不需要URL编码。另一方面,FIQL的语法不太直观,URL编码也不总是那么重要,因此RSQL还为逻辑运算符和一些比较运算符提供了更友好的语法。

例如,您可以像这样查询资源:/movies?query=name=="Kill Bill";year=gt=2003 or /movies?query=director.lastName==Nolan and year>=2000。详见以下示例:

这是一个用JavaCC和Java编写的完整且经过彻底测试的RSQL解析器。因为RSQL是FIQL的超集,所以它也可以用于解析FIQL。

语法和语义

以下语法规范采用EBNF表示法(ISO 14977)编写。

RSQL表达式由一个或多个比较组成,通过逻辑运算符相互关联:

Logical AND : ; or and

Logical OR : , or or

默认情况下,AND运算符优先(即,在任何OR运算符之前对其求值)。但是,可以使用带括号的表达式来更改优先级,从而产生所包含表达式产生的任何结果。

input = or, EOF;

or = and, { "," , and };

and = constraint, { ";" , constraint };

constraint= ( group | comparison );

group = "(", or, ")";

比较由选择器、运算符和参数组成。

comparison=选择器、比较运算、参数;

选择器标识要筛选的资源表示形式的字段(或属性、元素…)。它可以是任何不包含保留字符的非空Unicode字符串(见下文)或空格。选择器的特定语法不由此解析器强制执行。

selector=未保留str;

比较运算符采用FIQL表示法,其中一些运算符还具有另一种语法:

· Equal to : ==

· Not equal to : !=

· Less than : =lt= or <

· Less than or equal to : =le= or <=

· Greater than operator : =gt= or >

· Greater than or equal to : =ge= or >=

· In : =in=

· Not in : =out=

您还可以使用自己的运算符简单地扩展此解析器(请参阅下一节)。

comparison-op = comp-fiql | comp-alt;

comp-fiql = ( ( "=", { ALPHA } ) | "!" ), "=";

comp-alt = ( ">" | "<" ), [ "=" ];

参数可以是单个值,也可以是用逗号分隔的括号中的多个值。不包含任何保留字符或空格的值可以不加引号,其他参数必须用单引号或双引号括起来。

arguments = ( "(", value, { "," , value }, ")" ) | value;

value = unreserved-str | double-quoted | single-quoted;

unreserved-str = unreserved, { unreserved }

single-quoted = "'", { ( escaped | all-chars - ( "'" | "\" ) ) }, "'";

double-quoted = '"', { ( escaped | all-chars - ( '"' | "\" ) ) }, '"';

reserved = '"' | "'" | "(" | ")" | ";" | "," | "=" | "!" | "~" | "<" | ">";

unreserved = all-chars - reserved - " ";

escaped = "\", all-chars;

all-chars = ? all unicode characters ?;

如果需要在带引号的参数中同时使用单引号和双引号,则必须使用\(反斜杠)转义其中一个引号。如果要按字面意思使用\,请将其加倍为\。反斜杠只有在引用的参数中才有特殊含义,而不是在未引用的参数。

示例

Examples of RSQL expressions in both FIQL-like and alternative notation:

  • name=="Kill Bill";year=gt=2003
  • name=="Kill Bill" and year>2003
  • genres=in=(sci - fi,action);(director=='Christopher Nolan',actor==*Bale);year=ge=2000
  • genres=in=(sci - fi,action) and (director=='Christopher Nolan' or actor==*Bale) and year>=2000
  • director.lastName==Nolan;year=ge=2000;year=lt=2010
  • director.lastName==Nolan and year>=2000 and year<2010
  • genres=in=(sci - fi,action);genres=out=(romance,animated,horror),director==Que*Tarantino
  • genres=in=(sci - fi,action) and genres=out=(romance,animated,horror) or director==Que*Tarantino

二、Oinone 拓展协议

正常类型

  • Is null : =isnull=
  • Not null : =notnull=
  • Like to : =like=
  • Not like to : =notlike=
  • Column equal to : =cole=
  • Not column equal to : =colnot=
  • like ‘xxxx%’ : =starts=
  • not like ‘xxxx%’ :=notstarts=
  • like ‘%xxxx’ : =ends=
  • not like ‘%xxxx’ : =notends=

二进制枚举

  • Intersect : =has=

  • Not Intersect : =hasnt=

  • Contain : =contain=

  • Not Contain : =notcontain=

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9291.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
史, 昂's avatar史, 昂数式管理员
Previous 2024年5月23日
Next 2024年5月23日

相关推荐

  • 3.5.6 DSL配置大全(略)

    因为默认视图很难满足客户的个性化需求,所以日常开发中view的配置是避免不了的。本系列篇是比较全面地介绍View配置的各个方面涉及:视图、字段、动作、布局等

    Oinone 7天入门到精通 2024年5月23日
    1.7K00
  • 6.2 集成平台(改)

    企业在数字化转型过程中内外部集成是一个必然需求、也是趋势 集成的诉求主要来自两个方面:1.企业的数字化改造是由外而内逐步进行的(内部异构集成)、2.企业数字化方向是朝越来越开放的方向发展(外部平台、工具集成)。总的来说企业在数字化转型过程中内外部集成是一个必然需求、也是趋势。所以我们不能简单地去理解做个API对接就结束了,而是要统一规划构建成企业的集成门户对API定义,安全、控制、记录等做全方位管理。oinone在下个版本规则中也纳入了基于集成平台之上做产品化配置的需求 概述 pamirs-eip为平台提供企业集成门户的相关功能,如请求外部接口使用的【集成接口】和对外开放被其他系统请求调用的【开放接口】功能。在请求外部接口时,还支持了多个接口调用(路由定义)、分页控制(paging)、增量控制(incremental)等功能。 准备工作 Step1 POM与模块依赖 pamirs-demo-api 和 pamirs-second-api 的pom文件中引入pamirs-eip2-api包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-eip2-api</artifactId> </dependency> DemoModule和SecondModule 增加对EipModule的依赖 @Module(dependencies = {EipModule.MODULE_MODULE}) pamirs-demo-boot和pamirs-second-boot工程的pom文件中引入pamirs-eip2-core包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-eip2-core</artifactId> </dependency> Step2 yaml配置文件参考 pamirs-demo-boot和pamirs-second-boot工程的application-dev.yml文件中增加配置pamirs.boot.modules增加eip,即在启动模块中增加eip模块 pamirs: boot: modules: – eip pamirs-demo-boot和pamirs-second-boot工程的application-dev.yml文件中增加eip模块的数据源与路由配置 pamirs: framework: data: ds-map: eip: eip datasource: eip: driverClassName: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://127.0.0.1:3306/eip_v3?useSSL=false&allowPublicKeyRetrieval=true&useServerPrepStmts=true&cachePrepStmts=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true username: root password: oinone initialSize: 5 maxActive: 200 minIdle: 5 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true asyncInit: true pamirs-demo-boot工程的application-dev.yml文件中修改eip的配置 pamirs: eip: open-api: enabled: false pamirs-second-boot工程的application-dev.yml文件中修改eip的配置 pamirs: eip: enabled: true open-api: enabled: true route: host: 127.0.0.1 port: 8094 aes-key: Nj5Thnxz4rV8Yy1FLGA2hUym3RepB8MKgafEaYC4GKo= 注: hosts配置在远程调用时不能使用127.0.0.1,可配置为0.0.0.0进行自动识别。若自动识别仍无法访问,请准确配置其他已知的可访问IP地址。 aes-key:用下面代码生成 附录:AES Key生成 pro.shushi.pamirs.core.common.EncryptHelper加解密帮助类,默认支持AES、RSA类型的数据加解密方法,也可自定义其他类型的加解密方法。 System.out.println(EncryptHelper.getKey(EncryptHelper.getAESKey())); Step3 在pamirs-second-api新建一个SessionTenantApi实现类 只要在我们公共的jar包中构建类似DemoSessionTenant类就可以了,之所以要构建SessionTenantApi实现类是因为EIP是以租户信息做路由的。所以这里我们写死返回一个“pamirs”租户就好了。 记得要重新mvn install second工程,再刷新demo工程 package pro.shushi.pamirs.second.api.tenant; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import pro.shushi.pamirs.framework.session.tenant.api.SessionTenantApi; import pro.shushi.pamirs.meta.api.core.session.SessionClearApi; import pro.shushi.pamirs.meta.common.spi.SPI; @Order(99) @Component @SPI.Service public class DemoSessionTenant implements SessionTenantApi, SessionClearApi { public String getTenant() { return "pamirs"; } public void setTenant(String tenant) { } public void clear() { } } 开放接口(举例) Step1 用于演示的模型定义 package pro.shushi.pamirs.second.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.IdModel; @Model.model(TestOpenApiModel.MODEL_MODEL) @Model(displayName = "演示开放接口模型") public class TestOpenApiModel extends IdModel { public static final String MODEL_MODEL = "demo.second.TestOpenApiModel"; @Field.String @Field(displayName = "名称") private…

    2024年5月23日
    1.8K00
  • 5.3 基础支撑之用户与客户域

    一、三户概念 三户由来 介绍下经典的三户模型,它是电信运营支持系统的基础。三户模型即客户、用户和帐户,来源于etom的模型。这三者之间的关系应该是一个相互关联但又是独立的三个实体,这种关联只是一个归属和映射的关系,而三个实体本身是相互独立的,分别是体现完全不同的几个域的信息,客户是体现了社会域的信息,用户体现了业务域的信息,帐户体现的是资金域的信息。 客户:它是个社会化的概念,一个自然人或一个法人 用户:它是客户使用运营商开发的一个产品以及基于该产品之上的增值业务时,产生的一个实体。如果说一个客户使用了多个产品,那么一个客户就会对应好几个用户(即产品) 账户:它的概念起源于金融业,只是一个客户在运营商存放资金的实体,目的是为选择的产品付费 Oinone的三户 在原三户模型中【用户】是购买关系产生的产品与客户关系的服务实例,在互联网发展中用户的概念发生了非常大的变化,【用户】概念变成了:使用者,是指使用电脑或网络服务的人,通常拥有一个用户账号,并以用户名识别。而且新概念在互联网强调用户数的大背景下已经被普遍介绍,再去强调电信行业的用户概念就会吃力不讨好。而且不管是企业应用领域和互联网领域,原用户概念都显得过于复杂和没有必要。也就有了特色的oinone的三户模型: 客户:它是个社会化的概念,一个自然人或一个法人 用户:使用者,是指使用电脑或网络服务的人,通常拥有一个用户账号,并以用户名识别 账户:它的概念起源于金融业,只是一个客户在运营商存放资金的实体,目的是为选择的产品付费 二、Oinone的客户与用户 三户模型是构建上层应用的基础支撑能力,任何业务行为都跟这里两个实体脱不了干系。以客户为中心建立商业关系与商业行为主体,以用户为中心构建一致体验与操作行为主体。在底层设计上二者相互独立并无关联,由上层应用自行作关联绑定,往往在登陆时在Session的处理逻辑中会根据【用户】去找到对应一个或多个【商业(主体)客户】,Session的实现可以参考4.1.20【框架之Session】一文。 图5-3-1 Oinone的客户与用户 客户设计说明 PamirsPartner作为商业关系与商业行为的主体,派生了两个子类PamirsCompany与PamirsPerson分别对应:公司(法人)客户、自然人客户 公司(法人)客户PamirsCompany对应多个组织部门PamirsDepartment,公司(法人)客户PamirsCompany对应多个员工PamirsEmployee 部门PamirsDepartment对应一个公司(法人)客户PamirsCompany,对应多个员工PamirsEmployee 员工PamirsEmployee对应多个部门PamirsDepartment,对应一个或多个公司(法人)客户PamirsCompany,其中有一个主的 用户设计说明 PamirsUser作为一致体验与操作行为主体,本身绑定登陆账号,并且可以关联多个三方登陆账户PamirsUserThirdParty 客户与用户如何关联(举例) 例子设计: 新建demo系统的PetComany和PetEmployee,用PetEmployee去关联用户。 当用户登陆时,根据用户Id找到PetEmployee,在根据PetEmployee找到PetComany,把PetComany放到Session中去 修改PetShop模型关联一个PamirsPartner,PamirsPartner的信息从Session取。 Step1 pamirs-demo-api工程增加依赖,并且DemoModule增加对BusinessModule的依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-business-api</artifactId> </dependency> 图5-3-2 pamirs-demo-api工程增加依赖 在DemoModule类中通过@Module.dependencies中增加BusinessModule.MODULE_MODULE @Module( dependencies = { BusinessModule.MODULE_MODULE} ) 图5-3-3 声明对BusinessModule的依赖 Step2 新建PetComany和PetEmployee,以及对应的服务 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.business.api.model.PamirsEmployee; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.user.api.model.PamirsUser; @Model.model(PetEmployee.MODEL_MODEL) @Model(displayName = "宠物公司员工",labelFields = "name") public class PetEmployee extends PamirsEmployee { public static final String MODEL_MODEL="demo.PetEmployee"; @Field(displayName = "用户") private PamirsUser user; } 图5-3-4 新建PetEmployee package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.business.api.entity.PamirsCompany; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; @Model.model(PetCompany.MODEL_MODEL) @Model(displayName = "宠物公司",labelFields = "name") public class PetCompany extends PamirsCompany { public static final String MODEL_MODEL="demo.PetCompany"; @Field.Text @Field(displayName = "简介") private String introductoin; } 图5-3-5 新建PetComany package pro.shushi.pamirs.demo.api.service; import pro.shushi.pamirs.demo.api.model.PetEmployee; import pro.shushi.pamirs.meta.annotation.Fun; import pro.shushi.pamirs.meta.annotation.Function; @Fun(PetEmployeeQueryService.FUN_NAMESPACE) public interface PetEmployeeQueryService { String FUN_NAMESPACE ="demo.PetEmployeeQueryService"; @Function PetEmployee queryByUserId(Long userId); } 图5-3-6 新建PetEmployee对应服务 package pro.shushi.pamirs.demo.core.service; import org.springframework.stereotype.Component; import pro.shushi.pamirs.demo.api.model.PetEmployee; import pro.shushi.pamirs.demo.api.service.PetEmployeeQueryService; import pro.shushi.pamirs.framework.connectors.data.sql.query.QueryWrapper; import pro.shushi.pamirs.meta.annotation.Fun; import pro.shushi.pamirs.meta.annotation.Function; @Fun(PetEmployeeQueryService.FUN_NAMESPACE) @Component public class PetEmployeeQueryServiceImpl implements PetEmployeeQueryService { @Override @Function public PetEmployee queryByUserId(Long userId) { if(userId==null){ return null; } QueryWrapper<PetEmployee> queryWrapper = new QueryWrapper<PetEmployee>().from(PetEmployee.MODEL_MODEL).eq("user_id", userId); return…

    2024年5月23日
    1.4K00
  • 4.1.15 框架之网关协议

    一、多端协议 协议内容格式 请求头 头信息 headerMap "sec-fetch-mode" -> "cors" "content-length" -> "482" "sec-fetch-site" -> "none" "accept-language" -> "zh-CN,zh;q=0.9" "cookie" -> "pamirs_uc_session_id=241af6a1dbba41a4b35afc96ddf15915" "origin" -> "chrome-extension://flnheeellpciglgpaodhkhmapeljopja" "accept" -> "application/json" "host" -> "127.0.0.1:8090" "connection" -> "keep-alive" "content-type" -> "application/json" "accept-encoding" -> "gzip, deflate, br" "user-agent" -> "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36" "sec-fetch-dest" -> "empty" 图4-1-15-1 头信息 headerMap 请求地址 requestUrl 例如 http://127.0.0.1:8090/pamirs/DemoCore?scene=redirectListPage HTTP参数键值对 parameterMap url中queryString在服务端最终会转化为参数键值对。 请求体格式 请求体格式采用GraphQL协议。请求体格式分为API请求和上下文变量。以商品的test接口为例,请求格式如下。 API请求格式 query{ petShopProxyQuery { queryPage(page: {currentPage: 1, size: 1}, queryWrapper: {rsql: "(1==1)"}) { content { income id code creater { id nickname } relatedShopName shopName petTalents { id name } items { id itemName } } size totalPages totalElements } } } 图4-1-15-2 API请求格式 上下文变量 variables 请求策略requestStrategy 名称 类型 说明 checkStrategy CheckStrategyEnum 校验策略:RETURN_WHEN_COMPLETED -?全部校验完成再返回结果RETURN_WHEN_ERROR -?校验错误即返回结果 msgLevel InformationLevelEnum 消息级别:DEBUG("debug", "调试", "调试"),INFO("info", "信息", "信息"),WARN("warn", "警告", "警告"),SUCCESS("success", "成功", "成功"),ERROR("error", "错误", "错误")不设置,则只返回错误消息;上方消息级别清单,越往下级别越高。只有消息的级别高于或等于该设定级别才返回,否则会被过滤。 onlyValidate Boolean 只校验不提交数据 表4-1-15-1 请求策略requestStrategy 上下文变量式例如下。 { "requestStrategy": { "checkStrategy": "RETURN_WHEN_COMPLETED", "msgLevel":"INFO" } } 图4-1-15-3 上下文变量式例 响应体格式 协议响应内容包括data、extensions和errors三部分,extensions和errors是可缺省的。data部分为业务数据返回值。应用业务层可以在extensions中添加API返回值之外的扩展信息。extensions中包含success、messages和extra三部分,success标识请求是否成功。如果业务正确处理并返回,则errors部分为空;如果业务处理返回失败,则将错误信息添加到errors中。 正确响应格式示例如下。 { "data": { "petShopProxyQuery": { "queryPage": { "content": [ { "id": "246675081504233477", "creater": { "id": "10001" }, "relatedShopName": "oinone宠物店铺001", "shopName": "oinone宠物店铺001", "petTalents": […

    Oinone 7天入门到精通 2024年5月23日
    1.3K00
  • 1.1 Oinone的萌芽

    在信息化时代,中国并没有涌现出一家世界知名的软件公司。这是因为像SAP、Oracle、IBM、Salesforce、NetSuite、Odoo等西方巨头所拥有的最佳实践在业务、技术和模式方面,给予了它们在企业信息化建设中高额利润的优势。中国软件业在这个时代的角色是学习和追随者,而最优秀的追随者是金蝶和用友,它们能在国家推行会计电算化的机遇中占据领先地位。但是,追随者始终只是追随者,没有真正的突破。 我自己进入软件行业的经历可以追溯到2015年。当时资本市场非常热门,大家都在创业。我认为这是一个时代的机会,就像国家改革开放一样。于是,我和很多同事一起开始了创业之旅。在数式之前,我加入并创办了三家公司:500mi、数列和端点。整个过程给了我宝贵的经验和启示,帮助我找到了最终想要的方向。 在500mi公司时,我从技术岗位转型为业务经营,起步并不顺利。然而,我从这份经历中获得了一堂重要的课:做自己擅长的事情,有助于渡过创业启动期最艰难的阶段。同时,市场调研为我提供了一个信号:传统企业对于IT的需求正逐渐向互联网靠拢。这个信号像注入了一剂强心剂,激励我继续前行。 2016年,我和三个曾在阿里工作的同事一起创办了一家新公司——数列,我们决定专注于我们最擅长的领域,即软件服务商。在没有任何商务资源的情况下,我们第一年就完成了1000多万的合同,这相较之前是一个非常成功的开端。然而,对于公司未来的发展方向,我们花费了长达大半年的时间进行思考:应该坚持做底层的PaaS还是专注于企业可见的上层应用和业务产品?我倾向于后者。尽管我们持续存在分歧,但凭借着多年的革命友情,最终我们友好地分道扬镳。数列此前的成功让我更加坚信:在数字化时代,软件需求将会有井喷式的增长,数字化软件服务将是未来5-10年的重要方向。而在这个领域,专业的技能将是应对未来不确定性的真正力量。 提到数字化,就不得不提阿里巴巴提出的中台理念。中台理念在15年前被阿里巴巴提出,当时引起了广泛的关注和讨论。企业之所以认同中台理念,是因为他们的核心需求已经从内部转向外部:从关注管理、流程、效率的提升,转向关注外部协同、运营、创新。他们已经不再只担心企业的效率和成本,而是担心自己是否有能力跟上时代的快速变化。现今做生意的渠道已经不再是单一的线下渠道,而是包括淘宝、天猫、京东、拼多多、抖音、快手等多个线上渠道,以及海外市场,这种变化速度非常快。而中台的核心理念是敏捷响应、低成本快速创新,正好解决了企业主的核心焦虑。 企业的视角正在从内部管理向业务在线和生态在线(协同)转变,这种转变带来了一系列新的需求(如下图1-1所示)。这种转变不仅是为了支持现有业务的发展,也为企业未来的业务发展和创新提供了支持,并将变化实时反映到上下游合作伙伴中。 图1-1 企业视角转变带来一系列新的诉求 在2017年下半年,阿里云收购了端点科技,打算重启阿里软件。那个时候,市场上涌现出一批中台厂商,整个行业也比较混乱,很多人对互联网架构本身的理解不够深入,快速学习拿到阿里云认证后就开始做定制化的中台架构开发,但最终的效果无法达到预期。因此,阿里云和端点科技的联姻是为了弥补阿里云没有向外输出上层应用产品能力的缺陷。多年来,软件市场一直被国外厂商掌控,中国一直缺乏一个强大的本土软件公司。阿里收购端点,承载着无数中国人的软件梦想。在这种背景下,我回到了阿里体系,加入了端点科技。后来,我参与了许多中台项目,深刻地认识到搭建中台技术架构和一些基础能力,为上层应用场景落地并不难。但是,当客户接手扩展中台能力和新的上层应用场景时,效果往往不尽如人意,这并不是中台架构理念的问题,而是因为传统企业客户的IT能力大多较弱,这是一个硬伤。许多文章都在讲述中台战略,长篇大论地描述组织中台、技术中台、业务中台、数据中台,我们不去评论这些方法论的对错,从技术角度回到初衷,我们只关注一个问题:技术是为商业服务的,中台如何快速满足企业业务多变的需求? 我们经历了多个行业的中台建设,每次都向客户强调第一阶段是打好基础,因此需要较长的周期,并且每个项目都需要顶级架构师来把控整体项目。如何找到互联网架构与传统软件良好结合点,降低对组织的要求,实现中台架构的标准化输出?这是我回归阿里后致力于解决的问题。然而,随着阿里云对端点战略发展思路的变化,阿里不再提供SaaS服务,而只愿意做平台被其他企业集成。因此,我离开了端点,并决定把自己的技术思考转化为现实,于是数式科技诞生了。 在数字化时代,无论是业务、技术还是商业模式的最佳实践,都源自中国。中国已经从追随者转变为互联网领域的全面引领者。我们有理由相信,中国一定会崛起一家世界级的软件公司,而Oinone将始终以此为愿景。

    2024年5月23日
    2.0K00

Leave a Reply

Please Login to Comment