今天在家呆着,重拾好久不碰的代码,完善一下,就增加自动的RESTful支持吧
目标
当配置RESTful=on时,使用者无需编写任何代码,框架会自动完成基本的RESTful API,包括:
- GET /:Resource/[:Id] 获取资源
- POST /:Resource 创建资源
- PUT /:Resource/:Id 修改资源
- DELETE /:Resource/:Id 删除资源
当需要更复杂的处理,框架的自动化无法满足时,使用者也可以自由定制。
实现方式
- 修改Request的路径解释,得到Resource,Id 和Method
- 先判断是否有自定义的控制器实现,如有,则使用用户自定义的控制器方法来替换自动的实现。
- 无自定义进入系统自动实现: 根椐Method对Resource(与数据库的一个表关联)进行相关处理
核心代码
ResourceDao, err := this.NewMySQLDao(this.Resource) if err != nil { this.ShowErr(500, fmt.Sprintf("%v", err)) return } switch this.Method { case "GET": if this.Pk == 0 { //get All if this.Get["limit"] != "" { ResourceDao.SetLimit(this.Get["limit"]) } if this.Get["order"] != "" { ResourceDao.SetOrder(this.Get["order"]) } if this.Get["field"] != "" { ResourceDao.SetField(this.Get["field"]) } if this.Get["where"] != "" { //add others where } result, daoErr = ResourceDao.Get(wh) } else { result, daoErr = ResourceDao.GetRow(wh) } case "POST": data := make(map[string]interface{}) for k, v := range this.Post { data[k] = v } result, daoErr = ResourceDao.Insert(data) case "PUT": data := make(map[string]interface{}) for k, v := range this.Post { data[k] = v } if this.Get["where"] != "" { //add others where } fmt.Printf("%s", this.Post) result, daoErr = ResourceDao.Update(data, wh) case "DELETE": result, daoErr = ResourceDao.Delete(wh) default: this.ShowErr(400, fmt.Sprintf("method %s not support", this.Method)) return }
以上代码以mysql为存储,修改ResourceDao也可方便的替换为redis等。
自由定制的实现
框架提供的自动实现,会假设要操作的资源只对应数据库中的一个表,且必须有名为id的自增id字段。
在某些情况下,如果框架内部提供的自动实现无法满足需求(比如删除时,需要同时删除多张表的数据),也可以自由定制相关的控制器方法来实现(框架会根椐请求方法和资源名称先搜索是否存在该控制器方法)
比如: 用自定义的删除用户方法代替系统自动实现
func(this *Controller) DeleteUser(){ //删除处理}
注: 代码已更新至github的dev分支