SPL 轻量级多源混算实践 3 - 查询 Restful/JSON 数据
Restful 数据源也很常见,而且 Restful 的数据几乎都是 json 格式的,所以这两个放在一起来讲。
Rest 服务和数据格式
访问http://192.168.2.52:8503/orders可以获得订单数据:
Orders 采用多层 json 存储了订单产品等相关信息,结构如下:
[
{
"order_id": "ORD001",
"order_date": "2025-03-01",
"customer": "Alice Johnson",
"order_details": [
{
"detail_id": "D001",
"quantity": 2,
"price": 50.0,
"product": {
"product_id": "P001",
"name": "Wireless Mouse",
"category": "Electronics"
}
},
{
"detail_id": "D002",
"quantity": 1,
"price": 120.0,
"product": {
"product_id": "P002",
"name": "Mechanical Keyboard",
"category": "Electronics"
}
}
]
},
…
]
计算用例
筛选包含某个分类(如 Electronics),且订单金额不低于 200 的订单。
Restful
设置脚本参数:
编写脚本:
A |
|
1 |
=httpfile("http://192.168.2.52:8503/orders").read() |
2 |
=json(A1) |
3 |
=A2.select(order_details.select@1(product.category==categ) && order_details.sum(price*quantity)>200) |
4 |
=A3.new(order_id,order_date,customer,order_details.sum(price*quantity):amount) |
A3 进行条件过滤,这里直接用点(.)操作符引用下一层级的数据,多层就直接点下去就可以,表达很清晰。
执行可以看到各步骤运行结果:
还可以写成一句:
=json(httpfile("http://172.20.10.7:8503/orders").read()).select(order_details.select@1(product.category==categ) && order_details.sum(price*quantity)>200). new(order_id,order_date,customer,order_details.sum(price*quantity):amount)
JSON
如果数据是以 json 文件的形式提供,那么只需要把第一句改成:
=file(“orders.json”).read()
就可以,后续代码都是一样的。
我们使用 json 数据根据客户消费金额划分客户等级。
A |
|
1 |
=json(file("orders.json").read()) |
2 |
=A1.groups(customer;order_details.sum(quantity*price):amt) |
3 |
=A2.derive(if(amt>300:"Platinum",amt>200:"Gold",amt>100:"Silver";"Normal"):tier) |
读入 JSON 后按照客户汇总订单金额,A3 根据汇总后的订单金额来划分客户等级,可以得到这样的结果:
安全控制
为了数据的安全性,有些 REST 服务器会对访问数据者的身份进行认证,只有通过认证的访问才能读取到数据。常用的身份认证分为两大类,一类是用户访问认证页面后,服务器将认证后的信息记录在 Session 并将 Session 号发回客户端的 Cookie 中,或者将认证信息也发回客户端的 Cookie 中。当要访问有权限控制的页面数据时,需要将 Cookie 中保存的内容放在申请头中,服务器就能判断出访问者的身份,从而决定是否允许访问此页数据。另一类是用户访问认证页面后,服务器返回一个访问令牌 Token,在令牌有效期内,访问有权限控制页面数据时将 Token 作为参数传回就可以了。
这里给出两个示例。
服务器以 Session 或 Cookie 保存身份认证
A |
|
1 |
=httpfile("https://192.168.2.52:8503/login4get?nameOrEmail=tom&userPassword="+md5("mypass")+"&rememberLogin=true") |
2 |
=A1.read() |
3 |
=A1.property("Set-Cookie") |
4 |
=httpfile("https://192.168.2.52:8503/dataid/1628656263716";"Cookie":A3) |
5 |
=A4.read() |
服务器返回 Token
A |
|
1 |
=httpfile("https://192.168.2.52:8503","{\"userId\":\"abc\",\"password\":\"sdfikje87kd908\"}";"Content-Type":"application/json") |
2 |
=A1.read() |
3 |
=json(A2).accessToken |
4 |
=httpfile("https://192.168.2.52:8503","{\"accessToken\":\""+A3+"\",\"other\":\"xxx\"}";"Content-Type":"application/json") |
5 |
=A4.read() |