Month: 一月 2012

5分钟搞定你的Rest Server

在写了快10个Rest Server后,我实在无法忍受了。我是真心不想写Rest Server了。这并不是单纯的偷懒,而是因为Rest Server的开发工作实在很无趣。数据表的增删改查,输入和输出过滤。然后重复另一个表,再重复另一个表。

这都2012了啊,居然把宝贵的时间花在这么无聊的事情上。为了省下时间挣船票钱,我自己动手实现了一个Rest Server。它就是LazyRest。

先来看看它的特性:

  1. 对于常见的增删改查接口,不用写一行代码。只需要在Web界面上点点鼠标就好了。
  2. 对于基于token的接口认证,也不用写一行代码,只需要选中一个checkbox。
  3. 每个接口提供I/O过滤功能,你有机会直接过滤输入和修整输出。
  4. 对于不常用的特殊业务逻辑接口,你可以在浏览器上直接编写该接口的代码。
LazyRest的核心理念是
数据库+元数据 = Rest接口
LazyRest的工作方式是
读取数据库信息,让开发者指定对应的元信息;
通过元信息直接实现Rest接口,当元信息发生变动时,无需重新编码,接口直接可用

对关心效率的同学说一句,目前是实时拼接代码并执行,以后的版本会提供代码生成功能。

下边我们就以一个实例来看看,用它做Rest接口有多么快。

需求

我们先伪造一个需求:领导要求你花一天时间做一个手机版本的部门通讯录出来,你用LazyMobile的空白模板做好了前端显示,但是时间已经过去了半天,为了晚上不用加班(这样你才能陪妹子去逛街),你决定使用LazyRest来构造Rest Server。

步骤零:安装

为简化安装和方便调试,目前只放出LR的SAE版本,可以在SAE应用商店直接安装。

步骤一:建立数据表

首先,我们规划下MySQL的数据表,表名就用contact,字段包括姓名-name,email,手机号 – mobile, 家庭住址 – address, 邮编 – zipcode, 工号 – company_id。

用phpmyadmin建好这个表。

步骤二:配置接口

然后登录进入LazyRest首页。

很帅的,contact表已经被列出来了,点击【设置】进入接口设置界面。

这就是LazyRest最常用也是唯一的设置界面了。表格横向列出了所有数据库的字段;纵向列出了四个标准接口。

Insert 接口

首先我们开启Insert接口,点击Insert 下边的【设置】链接。

划上【开启】和【无需认证】两个复选框。

接着我们来指定输入字段。点每个字段表格中的【设置】进行指定。除了id以外,其他的字段都是输入字段,其中name,email和mobile是必填字段。配置完成后应该是这样的:

然后我们来指定返回字段。LazyRest默认采用twitter和weibo接口类似的规则,insert后会返回插入的那条记录信息。包括id字段,都是我们需要的。于是继续配置:

到这里,insert接口已经可用了。是的,我们没有写一行代码。点击粉红色的Insert链接,会进入这个接口的访问地址。

在LazyRest中,所有的接口都是按这个规则进行访问的:

LazyRest的URL/api/表名/接口名/字段1=值1&字段2&值2

在上边的图中,由于name字段被指定为必填,所以接口输出了对应的错误信息。我们来构造一个合法的输入

http://lazyrest.sinaapp.com/api/contact/insert/name=Easy&email=easychen@gmail.com&mobile=119

欧也,成功了。

步骤三:输入过滤

但是明显伪造的手机号码被输入了数据库,这显然是领导不愿意看到的。这个时候,我们用【I/O过滤】功能来处理。在【Insert】接口链接下方,【设置】链接旁边,就是我们的【I/O过滤】。

这里我写了几行简单的PHP脚本,检查mobile字段的长度是否为11位(懒得写正则了,那不是这里的重点)。

if( strlen($_REQUEST[‘mobile’]) != 11 )
return $this->send_error( 1002 , ‘BAD MOBILE NUMBER’ );

代码很简单,在输入过滤部分,我们可以通过$_REQUEST变量访问和修改输入。输入格式检查和转换都可以在这里做。在所有可以编写代码的地方,都建议使用LR的两个标准函数来处理返回值。

错误的情况使用:

$this->send_error( 错误码, 错误详细信息 );

正确的情况使用:

$this->send_result( 返回数据数组 );

保存后,我们再访问刚才的接口:

OK,接口已经能识别出位数不对的手机号了。

非常简单,而且快速。最重要的是你不用写那么多重复的代码了。

内置标准接口详解

下边我介绍下剩下的几个重点接口。

List接口

这个接口用于列表,它除了接受配置的字段外,还接受三个额外参数:max_id,since_id,count。熟悉微博接口的同学都很清楚他们的作用:

  • max_id: 从max_id开始(不含)返回比max_id小的记录,共count条。多用于获取更早数据的场景。
  • since_id:从since_id开始(不含)返回比since_id大的记录,共count条。多用于获取更新数据的场景。
  • count:返回记录数,默认为10,最大为100。

List接口的返回值默认为一个多维数组,其中items是命中的数据项,max_id和min_id项标示了返回的数据中最大和最小的id,方便追加读取。

如果不喜欢,可以通过输入过滤进行调整:

代码就一行,调整了下$data数组的结构:

if( isset( $data[‘items’] ) )  $data = $data[‘items’];

这就是I/O过滤模块的方便之处,因为能编写自定义代码,所以能处理所有情况。

Update和Remove接口

这两个接口比较正常,没有太多可说的,就是注意下记得配置好【%】和【=】,不要误删了数据⋯⋯

从SQL角度说明下:选上了【%】和【=】的字段只会出现在WHERE子句

这里给一个配置完成的典型设置:

自定义接口

点击标准接口表格下方的【添加自定义接口】就可以。注意接口代码不需要带上<?php 标签。I/O过滤部分也是。自定义接口可以处理复杂的业务逻辑,比如联表查询之类。

用户认证

开启用户认证

划上【接口设置】中的【用户认证】复选框即可。

获取token

LR默认【user】表为权限验证表,采用【用户名字段】+【密码字段】MD5进行匹配,成功则返回token。

其中【权限表】,【用户名字段】和【密码字段】在配置文件: app/config/app.config 中可修改。

获取token的接口地址如下:

LazyRest的URL/api/权限表/get_token/account=账号&password=密码

建议通过https访问,SAE上默认可用。开启了【用户认证】的接口,在请求中需要带上token,如:

http://lazyrest.sinaapp.com/api/contact/list/token=2314fdef32

其他注意点

LR是一个通过约定来简化开发的系统,所以有一些需要注意的约定:

  1. 每个数据表都应该包含id字段,LR的List接口对这个字段有依赖
  2. 不要用以下字符作为字段名: m,a,_action,_interface,count,max_id,since_id。
  3. 数据库中有__meta_code,__meta_user两张元数据表,不要删除,其中__meta_user中定义了登录LazyRest管理界面的用户。

最后说几句,LR目前刚写完,还需要一段时间的测试,不建议直接用于生产环境的大项目。等稳定后,我会加上代码生成功能,以处理高压力的情况。由于开发时间有限,所以很多交互细节没有深究(比如设置页面的checkbox之类),待以后逐渐完善吧。…