Yii RESTFul API 实战

用 Yii 来实现 一个书籍管理的 RESTFul API

数据表结构

DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `book_name` varchar(255) CHARACTER SET utf8mb4 NOT NULL COMMENT '书籍名称',
  `image` text CHARACTER SET utf8mb4 COMMENT '图书封面',
  `images` text CHARACTER SET utf8mb4 COMMENT '相册',
  `describe` varchar(1000) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '描述',
  `content` text CHARACTER SET utf8mb4 COMMENT '图文介绍',
  `publish_date` date DEFAULT NULL COMMENT '发行时间',
  `pages` int(11) DEFAULT NULL COMMENT '页数',
  `price` double(9,2) DEFAULT NULL COMMENT '价格',
  `in_stock` int(11) DEFAULT NULL COMMENT '库存数量',
  `author_id` int(11) DEFAULT NULL COMMENT '作者',
  `publisher_id` int(11) DEFAULT NULL COMMENT '出版社',
  `isbn` bigint(20) DEFAULT NULL COMMENT '书号',
  `data` text COLLATE utf8_unicode_ci COMMENT '附加数据',
  `state` tinyint(3) DEFAULT '1' COMMENT '状态 0:隐藏 1:可见',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

控制器

实现 RESTFul API 的关键,只要 控制器继承 \yii\rest\ActiveController 就好

数据的查询,分页, 排序 完全不需要自己实现了

<?php

namespace app\modules\api\controllers;

use app\modules\api\resources\Book;

class BookController extends \yii\rest\ActiveController
{
    // 只需定义 模型类即可 这里 又加了一层 (资源 resources) 方便单独控制 API 的返回数据的字段
    public $modelClass = 'api\modules\v1\resources\Book';
}

配置部分

主要实现 REST API 的规则 不同的请求方法 GET/PUT/DELETE/POST 到对应 的控制器方法

    'components' => [
        // ...
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                // ..
                [
                    'class' => 'yii\rest\UrlRule',
                    'controller' => [
                        'api/book', // 控制器
                    ],
                    'pluralize' => false,
                ],
            ],
        ],

资源 resources 省略直接使用模型类,添加当前层是为了,方便单独控制 API 的返回数据的字段

<?php

namespace app\modules\api\resources;

/**
 * Book fields
 */
class Book extends \app\models\Book
{
    // 普通请求返回字段
    public function fields()
    {
        return [
            'id',
            'book_name',
            'image',
            'describe',
            'publish_date',
            'pages',
            'state',
        ];
    }

    // 添加查询参数 expand=images,content 可返回的额外字段
    public function extraFields()
    {
        return [
            'images',
            'content',
        ];
    }
}

模型

看到模型代码多的可以了解下 使用 Gii 生成代码

如果感觉复杂 可以尝试下 线上的 代码生成

只要数据表结构创建好,备注(字段)也添加好, 模型完全可以自动生成

<?php

namespace app\models;

use Yii;

/**
 * Book
 * 
 * 数据表 "{{%book}}" 的模型
 * 
 * @property int $id Id
 * @property string $book_name 书籍名称
 * @property string|null $image 图书封面
 * @property string|null $images 相册
 * @property string|null $describe 描述
 * @property string|null $content 图文介绍
 * @property string|null $publish_date 发行时间
 * @property int|null $pages 页数
 * @property float|null $price 价格
 * @property int|null $in_stock 库存数量
 * @property int|null $author_id 作者
 * @property int|null $publisher_id 出版社
 * @property int|null $isbn 书号
 * @property string|null $data 附加数据
 * @property int|null $state 状态 0:隐藏 1:可见
 */
class Book extends \yii\db\ActiveRecord
{
    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return '{{%book}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['book_name'], 'required'],
            [['content'], 'string'],
            [['pages', 'in_stock', 'author_id', 'publisher_id', 'isbn', 'state'], 'integer'],
            [['price'], 'number'],
            [['image', 'images', 'publish_date', 'data'], 'safe'],
            [['book_name'], 'string', 'max' => 255],
            [['describe'], 'string', 'max' => 1000],
            [['author_id'], 'exist', 'skipOnError' => true, 'targetClass' => BookAuthor::class, 'targetAttribute' => ['author_id' => 'id']], // 关联数据是否存在
            [['publisher_id'], 'exist', 'skipOnError' => true, 'targetClass' => BookPublisher::class, 'targetAttribute' => ['publisher_id' => 'id']], // 关联数据是否存在
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id'           => 'Id',
            'book_name'    => '书籍名称',
            'image'        => '图书封面',
            'images'       => '相册',
            'describe'     => '描述',
            'content'      => '图文介绍',
            'publish_date' => '发行时间',
            'pages'        => '页数',
            'price'        => '价格',
            'in_stock'     => '库存数量',
            'author_id'    => '作者',
            'publisher_id' => '出版社',
            'isbn'         => '书号',
            'data'         => '附加数据',
            'state'        => '状态', // 0:隐藏 1:可见
        ];
    }
}

然后就可以愉快的使用了

API 使用

请求 GET api/book

返回数据类似

[
    {
        "id": "",
        "book_name": "",
        "image": "",
        "describe": "",
        "publish_date": "",
        "pages": "",
        "state": "",
    }
    // ...
]

响应主体只有书籍的数据集,没有其他任何多余的包装

其中 接口 也支持 搜索 filter, 排序 sort, 分页 page, 分页大小 per-page 等参数

具体查询方法查看之前文章 Yii RESTful API 使用教程

Post Author: admin