Restful

thinkjs可以非常方便的支持Restful类的接口,假如现在有个名为article的Resource想提供Restful接口,可以通过下面的方式进行。

关于Restful的介绍可以见这里 http://www.ruanyifeng.com/blog/2011/09/restful.html

配置路由

Restful类的接口需要借助自定义路由来使用,可以在路由配置文件中Conf/route.js配置如下的规则:

  1. module.exports = [
  2. [/(article)(?:\/(\d*))?/, 'restful']
  3. ]

这个规则表示:

  • /article/article/10类的接口标记为Restful接口
  • 需要对资源articleid使用正则分组功能,方便后续能够取到对应的值

建立对应的资源数据表

在数据库中添加对应的资源数据表think_article,其中think_为数据表前缀,需要改为实际项目中的数据表前缀。

添加相关的字段和添加数据。

访问Restful接口

有对应的资源数据表后,无需添加任何的Controller文件,即可通过下面的地址访问:

  • GET /article 获取所有的article列表
  • GET /article/10 获取id为10的article详细信息
  • POST /article 添加一个article
  • PUT /article/10 更新id为10的article数据
  • DELETE /article/10 删除id为10的article数据

定制Restful接口

上面的方式虽然无需写任何Controller文件即可访问article资源,但有时候我们希望加一些限制,如:有些字段不输出,权限控制等功能,那么可以通过自定义Controller来进行。

Controller文件

创建App/Lib/Controller/Restful/ArticleController.js文件,并使用如下的内容:

  1. module.exports = Controller('RestController', {
  2. })
  • Restful默认的分组是Restful,可以通过配置C('restful_group')来修改
  • Restful类的Controller需要继承自RestController

限制部分字段

如果有些字段不想输出,那么可以通过下面的方式来隐藏:

  1. module.exports = Controller('RestController', {
  2. __before: function(){
  3. this.model.field('content', true);
  4. }
  5. })

这里表示不输出content字段。

实际上这里的this.model即为D('article'),这样不仅可以限制字段,也可以限制条数,还可以分页。

权限控制

如果需要进行权限校验,那么也可以在__before里进行,如:

  1. module.exports = Controller('RestController', {
  2. __before: function(){
  3. if(!this.hasPermission()){
  4. return this.error('no permission');
  5. }
  6. }
  7. })

接口对应

请求类型GET, POST, PUT, DELETE对应的Action为getAction, postAction, putAction, deleteAction。如果还需要进行更强的定制,可以重写这几个方法。

getAction的实现为:

  1. getAction: function(){
  2. var self = this;
  3. if (this.id) {
  4. return getPromise(this.model.getPk()).then(function(pk){
  5. return self.model.where(getObject(pk, self.id)).find();
  6. }).then(function(data){
  7. return self.success(data);
  8. }).catch(function(err){
  9. return self.error(err.message);
  10. })
  11. }
  12. return this.model.select().then(function(data){
  13. return self.success(data);
  14. }).catch(function(err){
  15. return self.error(err.message);
  16. });
  17. },