RESTful和REST-RPC接口风格的差异与实现

REST风格的接口设计是以资源为核心,这种设计风格非常简约,也利于理解,比如获取一个id为259的商户,其HTTP请求应该像这样:

GET /Store/259

REST-RPC风格则是以操作为核心,一般只使用HTTP谓词GET或POST,比如同样的操作,其HTTP请求像这样:

GET /Store.get?id=259

如果用接口原型来描述这一操作,则这两种风格都实现了同一个原型:

Store.get(id) -> Store

可见,对同一个操作来说,REST-RPC风格与REST风格的URL是很容易转换的;两者只是请求形式不同,对其处理是完全等价的。

REST风格通过以下HTTP谓词来表示对象CRUD(增删改查)操作:

  • GET - 获取对象列表或明细
  • POST - 添加对象
  • PATCH/PUT - 更新对象(前者只更新指定的字段,忽略未指定字段;后者对未指定的字段当作清空处理)
  • DELETE - 删除对象

筋斗云框架同时支持这两种风格的操作。除了上面已列举的获取对象明细操作,还有以下等价操作:

添加对象

接口原型:

Store.add()(name, addr?)

REST风格实现:

POST /Store

name=华莹小吃&addr=银科路99号

REST-RPC风格实现:

POST /Store.add

name=华莹小吃&addr=银科路99号

两种风格都是将对象的属性放在POST内容中。

更新对象

接口原型:

Store.set(id)(name?, addr?)

REST风格实现:

PATCH /Store/259

addr=银科路88号

REST-RPC风格实现:

POST /Store.set?id=259

addr=银科路88号

两种风格也都是将对象的待更新属性放在POST内容中。

注意:筋斗云框架中,如果使用REST风格接口,则更新对象操作只用PATCH操作做局部更新,而不使用PUT操作。

查询列表

接口原型:

Store.query() -> [ Store ]

REST风格:

GET /Store

GET /Store/

REST-RPC风格:

GET /Store.query

删除对象

接口原型:

Store.del(id)

REST风格:

DELETE /Store/259

REST-RPC风格:

GET /Store.del?id=259

RESTful或REST-RPC风格调用的实现

要支持这两种调用风格并不复杂,需要注意的是,使用php实现时,完整的URL需要带上脚本名,像这样:

GET /api.php/Store.get?id=259
或
GET /api.php/Store/259

一般需要对WEB服务器经过特殊的Rewrite设置,才能隐去URL中的脚本部分。如使用Apache时,可在入口脚本(如api.php)对应目录的.htaccess中设置:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ api.php [QSA,L]

这样才能在URL中隐藏脚本,实现简约调用:

GET /Store.get?id=259
或
GET /Store/259

在php中,只要取到HTTP谓词(如GET/POST/PATCH等)和URL中的对象调用信息:

$method = $_SERVER["REQUEST_METHOD"];
$path = $_SERVER["PATH_INFO"];

这时取到$method就是GET,而$path就是URL中脚本后面的内容(不包括URL参数),即/Store.get/Store/259,有了这些信息,接下来就是进行文本分析了。

还要注意的是,使用Javascript的AJAX方法访问服务端时,一般只支持GET/POST操作,要允许其它谓词,服务端应设置HTTP头,如:

Access-Control-Allow-Methods: POST, GET, OPTIONS

你可能感兴趣的:(筋斗云)