MRS 核心 REST API

本书提供了一些示例,说明了如何在启用 REST 后,对表和视图使用 MySQL REST 服务查询和其他操作。

章节概述


另请参阅


1 MRS 核心 REST API

本节提供了一些示例,说明了如何在启用 REST 后,对表和视图使用 MySQL REST 服务查询和其他操作。

本节中的示例深入介绍了可以直接针对 MySQL REST 服务进行的低级 REST API 调用。它们可以帮助您深入了解 MRS 的工作原理。

在使用 MRS 开发应用程序时,建议使用更高级别的 MRS 软件开发工具包 (SDK)。请检查您的编程语言和平台是否已提供 SDK

1.1 关于 MRS RESTful Web 服务

MRS 支持创建无限数量的不同 RESTful Web 服务。您也可以将它们称为 MRS 服务。每个 MRS 服务通常映射到一个(或多个)Web 应用程序。

创建 RESTful Web 服务后,您可以通过导航到以下 URL 来访问它。

模式

https://<HOSTNAME:PORT>/<MRS_SERVICE_PATH>/<MRS_DATABASE_SCHEMA_PATH>/<MRS_DATABASE_OBJECT_PATH>/
  • 主机名:端口/MRS_服务_路径:指定运行给定 MRS 服务的地址。您也可以将其称为 MRS 服务 URI。
  • MRS_数据库_架构_路径:指定您在启用数据库架构的 REST 功能时提供的路径。默认情况下,它是架构的名称。
  • MRS_数据库_对象_路径:指定您在启用数据库对象(表、视图或过程)的 REST 功能时提供的路径。

这些值共同构成了 MRS 端点 URL。

示例

https://127.0.0.1:8000/mrs/sakila/actor

1.2 关于请求路径语法要求

为了防止基于路径的攻击,MRS 要求每个请求 URL 的路径元素的语法符合以下规则

  • 不能为空或仅包含空格
  • 不能包含以下任何字符:?、#、;、%
  • 不能包含空字符 (000)
  • 不能包含范围在 001-031 之间的字符
  • 不能以空格或句点 (.) 结尾
  • 不能包含双正斜杠 (//) 或双反斜杠 (\\)
  • 不能包含两个或多个连续的句点 (..、… 等)
  • 总长度不能超过 {@value #MAX_PATH_LENGTH} 个字符
  • 不能与以下任何名称(不区分大小写)匹配,无论是否带有文件扩展名:CON、PRN、AUX、CLOCK$、NUL、COM0、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT0、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、LPT8、LPT9

如果您打算为数据库对象启用 REST 端点,请避免使用不符合这些要求的对象名称。例如,不要创建名为 #EMPS 的表。如果您确实希望自动为名称不符合要求的对象启用 REST 功能,则必须使用符合要求的别名。

这些要求适用于 URL 解码后的 URL 形式,以防止尝试绕过百分号编码。

1.3 关于 cURL 和测试 RESTful 服务

通常,您可以使用 Web 浏览器导航到 RESTful 服务的 URL。但是,另一种测试方法是使用命令行工具,例如 cURL。

使用 cURL,您可以查看和控制发送到 RESTful 服务和从 RESTful 服务接收的数据。

curl -i https://127.0.0.1:8000/mrs/sakila/actor/2

此示例生成如下所示的响应

{
    "links": [
        {
            "rel": "self",
            "href": "https://127.0.0.1:8000/mrs/sakila/actor/2"
        }
    ],
    "actor_id": 2,
    "last_name": "WAHLBERG",
    "first_name": "NICK",
    "last_update": "2006-02-15 03:34:33.000000"
}

-i 选项告诉 cURL 显示服务器返回的 HTTP 标头。

2 MRS REST 查询

MRS REST 服务提供对一个或多个架构(及其元数据)以及其包含的数据库对象(例如表、视图和过程)(及其元数据)的访问。

2.1 获取架构元数据

此示例检索通过指定的架构别名可用的资源列表。它显示了通过启用表、视图或过程创建的 RESTful 服务。

模式

GET http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/metadata-catalog/

示例

GET https://127.0.0.1:8000/mrs/sakila/metadata-catalog/

结果

{
    "items": [
        {
            "name": "/actor",
            "links": [
                {
                    "rel": "describes",
                    "href": "https://127.0.0.1:8000/mrs/sakila/actor"
                },
                {
                    "rel": "canonical",
                    "href": "https://127.0.0.1:8000/mrs/sakila/metadata-catalog/actor"
                }
            ]
        },
        {
            "name": "/address",
            "links": [
                {
                    "rel": "describes",
                    "href": "https://127.0.0.1:8000/mrs/sakila/address"
                },
                {
                    "rel": "canonical",
                    "href": "https://127.0.0.1:8000/mrs/sakila/metadata-catalog/address"
                }
            ]
        }
    ],
    "limit": 25,
    "offset": 0,
    "hasMore": false,
    "count": 2,
    "links": [
        {
            "rel": "self",
            "href": "https://127.0.0.1:8000/mrs/sakila/metadata-catalog/"
        }
    ]
}

每个可用资源都有两个超链接

  • 具有“describes”关系的链接指向实际资源
  • 具有“canonical”关系的链接指向资源元数据

2.2 获取对象元数据

此示例检索单个对象的元数据(描述该对象)。元数据的位置由规范链接关系指定。

模式

GET http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/metadata-catalog/<ObjectAlias>/

示例

GET https://127.0.0.1:8000/mrs/sakila/metadata-catalog/actor/

结果

{
    "name": "/actor",
    "primaryKey": [
        "actor_id"
    ],
    "members": [
        {
            "name": "actor_id",
            "type": "null"
        },
        {
            "name": "first_name",
            "type": "null"
        },
        {
            "name": "last_name",
            "type": "null"
        },
        {
            "name": "last_update",
            "type": "string"
        }
    ],
    "links": [
        {
            "rel": "collection",
            "href": "http://mrs.zinner.org/mrs/sakila/metadata-catalog",
            "mediaType": "application/json"
        },
        {
            "rel": "canonical",
            "href": "http://mrs.zinner.org/mrs/sakila/metadata-catalog/actor"
        },
        {
            "rel": "describes",
            "href": "http://mrs.zinner.org/mrs/sakila/actor"
        }
    ]
}

2.3 获取对象数据

此示例检索对象中的数据。对象中的每一行对应于 JSON 数组中嵌入的 JSON 对象

模式

GET http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/<ObjectAlias>/

示例

GET https://127.0.0.1:8000/mrs/sakila/actor/

结果

{
    "items": [
        {
            "links": [
                {
                    "rel": "self",
                    "href": "http://mrs.zinner.org/mrs/sakila/actor/1"
                }
            ],
            "actor_id": 1,
            "last_name": "GUINESSS",
            "first_name": "PENELOPE",
            "last_update": "2021-09-28 20:18:53.000000"
        },
        {
            "links": [
                {
                    "rel": "self",
                    "href": "http://mrs.zinner.org/mrs/sakila/actor/2"
                }
            ],
            "actor_id": 2,
            "last_name": "WAHLBERG",
            "first_name": "NICK",
            "last_update": "2006-02-15 03:34:33.000000"
        },
        {
            "links": [
                {
                    "rel": "self",
                    "href": "http://mrs.zinner.org/mrs/sakila/actor/3"
                }
            ],
            "actor_id": 3,
            "last_name": "CHASE",
            "first_name": "ED",
            "last_update": "2006-02-15 03:34:33.000000"
        },
        ...
    ]
}

2.3.1 使用分页获取表数据

我们可以指定用于结果数据分页的偏移量和限制参数。

模式

GET http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/<ObjectAlias>/?offset=<Offset>&limit=<Limit>

示例

GET https://127.0.0.1:8080/mrs/sakila/actor/?offset=10&limit=2

结果

{
    "items": [
        {
            "links": [
                {
                    "rel": "self",
                    "href": "http://mrs.zinner.org/mrs/sakila/actor/11"
                }
            ],
            "actor_id": 11,
            "last_name": "CAGE",
            "first_name": "ZERO",
            "last_update": "2006-02-15 03:34:33.000000"
        },
        {
            "links": [
                {
                    "rel": "self",
                    "href": "http://mrs.zinner.org/mrs/sakila/actor/12"
                }
            ],
            "actor_id": 12,
            "last_name": "BERRY",
            "first_name": "KARL",
            "last_update": "2006-02-15 03:34:33.000000"
        }
    ],
    "limit": 2,
    "offset": 10,
    "hasMore": true,
    "count": 2,
    "links": [
        {
            "rel": "self",
            "href": "http://mrs.zinner.org/mrs/sakila/actor/"
        },
        {
            "rel": "next",
            "href": "http://mrs.zinner.org/mrs/sakila/actor/?offset=12&limit=2"
        },
        {
            "rel": "prev",
            "href": "http://mrs.zinner.org/mrs/sakila/actor/?offset=8&limit=2"
        },
        {
            "rel": "first",
            "href": "http://mrs.zinner.org/mrs/sakila/actor/?limit=2"
        }
    ]
}

2.3.2 使用查询获取表数据

我们可以使用过滤器子句来限制返回的对象集。

模式

GET http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/<ObjectAlias>/?q=<FilterClause>

示例

GET https://127.0.0.1:8080/mrs/sakila/actor/?q={"last_name":{"$like":"WAW%"}}

结果

{
    "items": [
        {
            "links": [
                {
                    "rel": "self",
                    "href": "http://mrs.zinner.org/mrs/sakila/actor/97"
                }
            ],
            "actor_id": 97,
            "last_name": "HAWKE",
            "first_name": "MEG",
            "last_update": "2006-02-15 03:34:33.000000"
        }
    ],
    "limit": 25,
    "offset": 0,
    "hasMore": false,
    "count": 1,
    "links": [
        {
            "rel": "self",
            "href": "http://mrs.zinner.org/mrs/sakila/actor/"
        }
    ]
}

2.3.3 使用主键获取表行

此示例通过指定其标识键值来检索对象。

注意:表需要一个主键才能成为 REST 服务的一部分。

模式

GET http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/<ObjectAlias>/<KeyValues>

其中 <KeyValues> 是一个以逗号分隔的键值列表(按键顺序)。

示例

GET https://127.0.0.1:8000/mrs/sakila/actor/53

结果

{
    "links": [
        {
            "rel": "self",
            "href": "http://mrs.zinner.org/mrs/sakila/actor/53"
        }
    ],
    "actor_id": 53,
    "last_name": "TEMPLE",
    "first_name": "MENA",
    "last_update": "2006-02-15 03:34:33.000000"
}

2.4 插入表行

要将数据插入表中,请求正文应为包含要插入数据的 JSON 对象。

如果对象具有主键,则 POST 请求可以在正文中包含主键值。如果表具有 AUTO_INCREMENT 列,则可以省略主键列。

模式

POST http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/<ObjectAlias>/

示例

curl -i -H "Content-Type: application/json" -X POST -d "{ \"last_name\" : \"FOLEY\", \"first_name\": \"MIKE\" }" "https://127.0.0.1:8000/mrs/sakila/actor/" Content-Type: application/json

结果

{
    "links": [
        {
            "rel": "self",
            "href": "https://127.0.0.1:8000/mrs/sakila/actor/201"
        }
    ],
    "actor_id": 201,
    "last_name": "FOLEY",
    "first_name": "MIKE",
    "last_update": "2022-11-29 15:35:17.000000"
}

2.5 更新/插入表行

要插入、更新或“向上插入”(如果存在则更新,如果不存在则插入)表中的数据,我们可以发送一个请求,其中正文包含一个带有要插入或更新数据的 JSON 对象。

模式

PUT http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/<ObjectAlias>/<KeyValues>

示例

curl -i -H "Content-Type: application/json" -X PUT -d "{ \"last_name\" : \"FOLEY\", \"first_name\": \"JACK\" }" "https://127.0.0.1:8000/mrs/sakila/actor/201" Content-Type: application/json

结果

{
    "links": [
        {
            "rel": "self",
            "href": "http://mrs.zinner.org/mrs/sakila/actor/201"
        }
    ],
    "actor_id": 201,
    "last_name": "FOLEY",
    "first_name": "JACK",
    "last_update": "2022-11-29 15:45:10.000000"
}

2.6 使用过滤器删除

可以通过指定标识要删除的对象的过滤器子句来删除对象或其他数据库对象。

模式

DELETE http://<HOST>:<PORT>/<ServiceAlias>/<SchemaAlias>/<ObjectAlias>/?q=<FilterClause>

示例

curl -i -X DELETE "https://127.0.0.1:8000/mrs/sakila/actor/?q=\{\"actor_id\":201\}"

结果

{
    "itemsDeleted": 1
}

3 FilterObject 语法

FilterObject 必须是符合以下语法的 JSON 对象

    FilterObject { orderby , asof, wmembers }

orderby、asof 和 wmembers 属性是可选的,它们的定义如下

orderby
"$orderby": {orderByMembers}

orderByMembers
    orderByProperty
    orderByProperty , orderByMembers

orderByProperty
    columnName : sortingValue

sortingValue
"ASC"
"DESC"
"-1"
"1"
-1
1

asof
"$asof": date
"$asof": "datechars"
"$asof": scn
"$asof": +int

wmembers
    wpair
    wpair , wmembers

wpair
    columnProperty
    complexOperatorProperty

columnProperty
    columnName : string
    columnName : number
    columnName : date
    columnName : simpleOperatorObject
columnName : complexOperatorObject
    columnName : [complexValues]

columnName
"\p{Alpha}[[\p{Alpha}]]([[\p{Alnum}]#$_])*$"

complexOperatorProperty
    complexKey : [complexValues]
    complexKey : simpleOperatorObject 

complexKey
"$and"
"$or"

complexValues
    complexValue , complexValues

complexValue
    simpleOperatorObject
    complexOperatorObject
    columnObject

columnObject
    {columnProperty}

simpleOperatorObject
    {simpleOperatorProperty}

complexOperatorObject
    {complexOperatorProperty}

simpleOperatorProperty
"$eq" : string | number | date
"$ne" : string | number | date
"$lt" :  number | date
"$lte" : number | date
"$gt" : number | date
"$gte" : number | date
"$instr" : string 
"$ninstr" : string
"$like" : string
"$null" : null
"$notnull" : null
"$between" : betweenValue
"$like": string

betweenValue
    [null , betweenNotNull]
    [betweenNotNull , null]
    [betweenRegular , betweenRegular]

betweenNotNull
    number
    date
    
betweenRegular
    string
    number
    date

数据类型定义包括以下内容

string 
      JSONString
number
      JSONNumber
date
      {"$date":"datechars"}
scn
      {"$scn": +int}

其中

datechars is an RFC3339 date format in UTC (Z)
        

JSONString
        ""
        " chars "
chars
        char
        char chars
char
        any-Unicode-character except-"-or-\-or-control-character
        \"
        \\
        \/
        \b
        \f
        \n
        \r
        \t
        \u four-hex-digits


JSONNumber
    int
    int frac
    int exp
    int frac exp
int
    digit
    digit1-9 digits 
    - digit
    - digit1-9 digits
frac
    . digits
exp
    e digits
digits
    digit
    digit digits
e
    e
    e+
    e-
    E
    E+
    E-

FilterObject 必须根据 RFC3986 的第 2.1 节进行编码。

4 FilterObject 语法示例

4.1 ORDER BY 属性 ($orderby)

Order by with literals

{
  "$orderby": {"SALARY":  "ASC","ENAME":"DESC"}
}

Order by with numbers

{
  "$orderby": {"SALARY":  -1,"ENAME":  1}
}

4.2 ASOF 属性 ($asof)

With SCN (Implicit)

{
  "$asof": 1273919
}

With SCN (Explicit)

{
  "$asof": {"$scn": "1273919"}
}

With Date (Implicit)

{
  "$asof": "2014-06-30T00:00:00Z"
}

With Date (Explicit)

{
  "$asof": {"$date": "2014-06-30T00:00:00Z"}
}

4.3 等于运算符 ($eq)

Implicit (Support String and Dates too)

{
  "SALARY": 1000
}

Explicit

{
  "SALARY": {"$eq": 1000}
}

Strings

{
  "ENAME": {"$eq":"SMITH"}
}

Dates

{
  "HIREDATE": {"$date": "1981-11-17T08:00:00Z"}
}

4.4 不等于运算符 ($ne)

Number

{
  "SALARY": {"$ne": 1000}
}

String

{
  "ENAME": {"$ne":"SMITH"}
}

Dates

{
  "HIREDATE": {"$ne": {"$date":"1981-11-17T08:00:00Z"}}
}

4.5 小于运算符 ($lt)

(仅支持日期和数字)

Numbers

{
  "SALARY": {"$lt": 10000}
}

Dates

{
  "SALARY": {"$lt": {"$date":"1999-12-17T08:00:00Z"}}
}

4.6 小于或等于运算符 ($lte)

(仅支持日期和数字)

Numbers

{
  "SALARY": {"$lte": 10000}
}

Dates

{
  "HIREDATE": {"$lte": {"$date":"1999-12-17T08:00:00Z"}}
}

4.7 大于运算符 ($gt)

(仅支持日期和数字)

Numbers

{
  "SALARY": {"$gt": 10000}
}

Dates

{
  "SALARY": {"$gt": {"$date":"1999-12-17T08:00:00Z"}}
}

4.8 大于或等于运算符 ($gte)

(仅支持日期和数字)

Numbers

{
  "SALARY": {"$gte": 10000}
}

Dates

{
  "HIREDATE": {"$gte": {"$date":"1999-12-17T08:00:00Z"}}
}

4.9 字符串包含运算符 ($instr)

(仅支持字符串)

{
  "ENAME": {"$instr":"MC"}
}

4.10 字符串不包含运算符 ($ninstr)

(仅支持字符串)

{
  "ENAME": {"$ninstr":"MC"}
}

4.11 LIKE 运算符 ($like)

(支持字符串。不支持转义字符来尝试匹配包含 _ 或 % 字符的表达式。)

{
  "ENAME": {"$like":"AX%"}
}

4.12 BETWEEN 运算符 ($between)

(支持字符串、日期和数字)

Numbers

{
  "SALARY": {"$between": [1000,2000]}
}

Dates

{
  "SALARY": {"$between": [{"$date":"1989-12-17T08:00:00Z"},{"$date":"1999-12-17T08:00:00Z"}]}
}

Strings

{
  "ENAME": {"$between": ["A","C"]}
}

Null Ranges ($lte equivalent)
(Supported by numbers and dates only)

{
  "SALARY": {"$between": [null,2000]}
}

Null Ranges ($gte equivalent)
(Supported by numbers and dates only)

{
  "SALARY": {"$between": [1000,null]}
}

4.13 NULL 运算符 ($null)

{
  "ENAME": {"$null": null}
}

4.14 非 NULL 运算符 ($notnull)

{
  "ENAME": {"$notnull": null}
}

4.15 AND 运算符 ($and)

(支持所有运算符,包括 $and 和 $or)

Column context delegation
(Operators inside $and will use the closest context defined in the JSON tree.)

{
  "SALARY": {"$and": [{"$gt": 1000},{"$lt":4000}]}
}

Column context override
(Example: salary greater than 1000 and name like S%)

{
  "SALARY": {"$and": [{"$gt": 1000},{"ENAME": {"$like":"S%"}} ] }
}

Implicit and in columns

{
  "SALARY": [{"$gt": 1000},{"$lt":4000}]
}

4.16 高阶 AND

(JSON 第一级定义的所有第一列和/或高阶运算符($and 和 $or)都将被连接,并使用隐式 AND)

(Example: Salary greater than 1000 and name starts with S or T)

{
  "SALARY": {"$gt": 1000},
  "ENAME": {"$or": [{"$like":"S%"}, {"$like":"T%"}]}
}

Invalid expression (operators $lt and $gt lack column context)

{
  "$and": [{"$lt": 5000},{"$gt": 1000}]
}

Valid alternatives for the previous invalid expression

{
  "$and": [{"SALARY": {"$lt": 5000}}, {"SALARY": {"$gt": 1000}}]
}

{
  "SALARY": [{"$lt": 5000},{"$gt": 1000}]
}

{
  "SALARY": {"$and": [{"$lt": 5000},{"$gt": 1000}]}
}

4.17 OR 运算符 ($or)

(支持所有运算符,包括 $and 和 $or)

Column context delegation
(Operators inside $or will use the closest context defined in the JSON tree)

{
  "ENAME": {"$or": [{"$eq":"SMITH"},{"$eq":"KING"}]}
}

Column context override
(Example: name starts with S or salary greater than 1000)

{
  "SALARY": {"$or": [{"$gt": 1000},{"ENAME": {"$like":"S%"}} ] }
}

版权所有 (c) 2022、2023 年,Oracle 和/或其附属公司。