CodeIgniter框架下HATEOAS规范POST/PUT/DELETE接口开发问题求助
CodeIgniter HATEOAS接口异常解决方案
问题根因总览
- POST返回
Column 'AuthorID' cannot be null:通常是模型未配置允许写入AuthorID字段、主键自增配置错误、请求参数未正确解析三类原因,导致CI自动过滤了传入的AuthorID值 - PUT返回成功但数据未修改:核心原因是未指定更新条件、PUT请求参数未正确获取、允许写入字段未配置三类,导致实际执行的是无更新内容的空操作
- DELETE返回成功但数据未移除:多是删除条件未正确传入、模型开启软删除未做硬删配置导致
完整实现代码
1. 模型配置(AuthorModel.php)
namespace App\Models; use CodeIgniter\Model; class AuthorModel extends Model { protected $table = 'author'; protected $primaryKey = 'AuthorID'; // 若AuthorID为用户手动传入而非数据库自增,必须设为false protected $useAutoIncrement = false; protected $returnType = 'array'; // 不需要软删除则关闭,开启状态下删除仅会标记deleted_at字段不会真删数据 protected $useSoftDeletes = false; // 必须包含所有需要插入/更新的字段,未配置的字段会被CI自动过滤 protected $allowedFields = ['AuthorID', 'BookID', 'name', 'age', 'gender']; protected $useTimestamps = false; }
2. 控制器实现(Api/Author.php)
namespace App\Controllers\Api; use CodeIgniter\RESTful\ResourceController; use App\Models\AuthorModel; class Author extends ResourceController { protected $modelName = 'App\Models\AuthorModel'; protected $format = 'json'; // 已正常运行的列表查询接口,保留HATEOAS链接逻辑 public function index() { $authors = $this->model->findAll(); $data = []; foreach ($authors as $author) { $author['_links'] = [ 'self' => base_url('api/author/' . $author['AuthorID']), 'book' => base_url('api/book/' . $author['BookID']), 'collection' => base_url('api/author') ]; $data[] = $author; } return $this->respond($data); } // POST创建接口,解决参数丢失问题 public function create() { // 兼容表单和JSON两种请求格式 $data = $this->request->getJSON(true) ?? $this->request->getPost(); if (!isset($data['AuthorID']) || empty($data['AuthorID'])) { return $this->failValidationError('AuthorID为必填参数'); } if ($this->model->save($data)) { $newAuthor = $this->model->find($data['AuthorID']); $newAuthor['_links'] = [ 'self' => base_url('api/author/' . $newAuthor['AuthorID']), 'book' => base_url('api/book/' . $newAuthor['BookID']), 'collection' => base_url('api/author') ]; return $this->respondCreated($newAuthor); } return $this->failValidationErrors($this->model->errors()); } // PUT更新接口,解决空更新问题 public function update($id = null) { if (!$id) return $this->failValidationError('URL中必须携带AuthorID参数'); $author = $this->model->find($id); if (!$author) return $this->failNotFound('对应作者不存在'); // PUT请求不能用getPost()取参数,需用getJSON或getRawInput解析 $data = $this->request->getJSON(true) ?? $this->request->getRawInput(); // 禁止更新主键,可根据业务调整 if (isset($data['AuthorID'])) unset($data['AuthorID']); if ($this->model->update($id, $data)) { $updatedAuthor = $this->model->find($id); $updatedAuthor['_links'] = [ 'self' => base_url('api/author/' . $updatedAuthor['AuthorID']), 'book' => base_url('api/book/' . $updatedAuthor['BookID']), 'collection' => base_url('api/author') ]; return $this->respond($updatedAuthor); } return $this->failValidationErrors($this->model->errors()); } // DELETE删除接口,解决假删除问题 public function delete($id = null) { if (!$id) return $this->failValidationError('URL中必须携带AuthorID参数'); $author = $this->model->find($id); if (!$author) return $this->failNotFound('对应作者不存在'); if ($this->model->delete($id)) { // 校验实际影响行数,避免无意义的删除成功返回 if ($this->model->db->affectedRows() > 0) { return $this->respondDeleted(['message' => '删除成功']); } } return $this->failServerError('删除失败'); } }
附加验证说明
- 路由配置需添加资源路由规则:
$routes->resource('author');自动映射请求方法到对应控制器逻辑 - JSON格式请求必须携带请求头:
Content-Type: application/json否则CI无法正确解析参数 - 外键约束校验:提交的BookID必须已存在于book表中,否则会触发数据库外键约束报错
内容的提问来源于stack exchange,提问作者Xianying
相关产品推荐
相关产品推荐

