<?php
class BaseModel extends EMongoDocument
{
public $_id;
public $created_time;
public $updated_time;
public $deleted;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function getCollectionName()
{
return null;
}
public function rules()
{
return array(
array('_id', 'default', 'value' => new MongoId()),
array('deleted', 'default', 'value' => Constant::UNDELETE),
array('created_time', 'default', 'value' => new MongoDate()),
array('updated_time', 'default', 'value' => new MongoDate()),
);
}
public function attributeLabels()
{
}
}
User类.
class User extends BaseModel {
public $name;
public $password;
public $nickname;
public $email;
public $height;
public $weight;
public $gender;
public $register_time;
public $last_login_time;
public static function model($className=__CLASS__) {
return parent::model($className);
}
/**
* @return string the associated collection name
*/
public function getCollectionName() {
return 'user';
}
public function rules() {
return array_merge(parent::rules(), array(
... //User类中属性的验证规则
));
}
}
Error Message的设计
作为API端,为移动端提供数据,在正常情况下会直接返回移动端所需要的数据。但由于其响应结果会受移动端传过来的参数,网络,Server等从多因素的影响,肯定会有Error Message的输出。很容易理解一个例子就是,当用户登录时,如果输错了用户名和密码,则不能进入系统,此时的API返回的便是一个user name or password error。
在Server端返回数据的时候,通常会返回一个json字符串,一般来讲我们会定义这个字符串的返回格式:
{status:"fail", error_code: 2010001, error_msg: "user name or pwd error"};
MongoDB与Yii搭建API服务-2
在上一篇文章中主要记录了Yii对MongoDB的基本操作,本文章主要记录整个API设计的一个大概结构。我做PHP较少,不知道更好的设计是什么样子,但是从觉得当前的设计来看,结构还是蛮清晰的,感觉还是不错的。以前做javaWeb的时候,结构差不多也是这样设计,但和PHP相比,java确实是重一些。在此之前,推荐一个不错的API设计的文章,点这里。
Model的设计
在上一篇文章中其实已经介绍过了Model的设计,此时再回顾一下。首先,我们会定义一个
BaseModel
,这个里面定义了一些公用的属性和rules,其它的实体类需要继承自它。通常在Model中会添加deleted
,created_time
,updated_time
。MongoDB
中的主键是_id
,这BaseModel
中定义了,其它子类中也不用再写了。由于BaseModel
没有对应的collection
,所以getCollectionName
方法必须返回null
。rules
里面定义的是一些基本的验证规则。在子类中,可以将这些rules
Merge进去。User
类.Error Message的设计
作为
API
端,为移动端提供数据,在正常情况下会直接返回移动端所需要的数据。但由于其响应结果会受移动端传过来的参数,网络,Server等从多因素的影响,肯定会有Error Message的输出。很容易理解一个例子就是,当用户登录时,如果输错了用户名和密码,则不能进入系统,此时的API返回的便是一个user name or password error
。 在Server端返回数据的时候,通常会返回一个json字符串,一般来讲我们会定义这个字符串的返回格式:error_code
:错误代码,在开发过程中可以约定,error_code由6位整数组成,第一位代表error的级别,如1表示系统级别的error(DB error), 2代表服务级别的错误。第二位和第三位代表某个feature, 如10代表用户模块。后三位代表具体的错误,001代表用户名和密码错误,002代表该帐号已锁定,等等。error_msg
:是对错误的简单描述,这个error_msg
通常是给程序员看的,所以里面的内容不太友好也没有关系。当移动端如果接收到这个error_msg
时,不会把它显示出来给最终用户,移动端的程序应该读取server端返回的error_code
, 然后根据这个error_code
加载相应的错误消息返回给最终用户。 所以一般来讲,我们会在{Yii}/protected/components
下定义两个类,一个是ErrorCode
, 一个是ErrorMsg
。两个类中的属性都是常量,如下:Controller的设计
Controller
是API端和移动端数据交换的接口,接收移动端的请求,并做相应处理后,将结果返回给移动端。作何一个项目会有多个Controller
, 在设计Controller
之前,我们可以分析一下,大部份Controller
都会做这么几件事:Controller
中的方法(对应的是一个URL),一定是只有用户登录后才可以访问,比如,修改密码。而大部份API不会做Session,此时可能就需要一个userId或者token之类的东西,表示当前用户的一个身份。于是,想着和
Model
设计一样的方式,也定义一个BaseController
,BaseController
是继承自CController
.针对以上的几个问题:
1.假设我们和移动端的开发约定,移动端如果需要传参数,只能发post请求,且请求体必须是格式良好的json, 于是我们就可以添加一个方法
getRequestParams()
来获取请求的数据.2.API返回给移动端的数据全部都是json格式,于是定义一个
response
方法。3.针对特定API的访问。在Yii的
CController
中有一个beforeAction
方法,从名字上看就知道这个方法一定是在每一个Actioin
调用之前执行。为此我们覆盖这个方法, 在里面定义我们自己的规则:在API的设计时,我们是将
user_id
这个参数直接带在url上,并没有做为请求体中的参数(json)传过来。如修改密码的url为/api/changpassword/ab33397997cd7989e9d0
。其中ab33397997cd7989e9d0
便是user_id
。在方法initRequestUser
中id的获取$id = Yii::app()->request->getQuery('user_id');
,是因为我们采用的URL重写规则是