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()