关闭

【RESTful】Yii2实现RESTful架构配置最佳实践

标签: yiiapirestrestfulyii2
6951人阅读 评论(1) 收藏 举报
分类:

Yii2实现RESTful架构配置最佳实践

为什么要用RESTful API

在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法,比如 GET、PUT、POST 和 DELETE。Hypermedia 是应用程序状态的引擎,资源表示通过超链接互联。

无状态,分层,可扩展

本文为原创博客,被收录在我自己的GitHub项目中点我查看项目文件

基于Yii2的RESTful API 的实现

不用自带的REST实现方式

首先,Yii2自带了实现RESTful api的方式,但是,官方的例子过于简单,把一个资源限定成了数据库中的一个表,这显然是和REST中定义的资源不相符的,并且实际的业务需求过于复杂,不能通过一个表进行数据的操作。

所以,我们采用了另一种方式,通过使用Yii2的不同组件,完成RESTful API的构建

路由

REST要求定义资源,采用不同HTTP方式进行访问。

这里用到了框架内部的路由

在项目的配置文件/config/web.php,中,对不同资源进行路由设置,从而达到同一个URL用不同的访问方式来处理不同业务的目的。

        //url配置对应规则
        'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [
                //配置规则,实现RESTful的方式
                'POST accounts'=>'account/login', // 登录
                'GET accounts'=>'account/get-avatar', //获取头像
                "GET accounts/status"=>'account/status', //查询登录状态

                //获取用户组信息
                "GET groups"=>"account/profile",

                //用户申请加入用户组的接口
                "GET users/ask"=>"user/apply", //申请列表
                "PUT users/<uid:\d+>"=>"user/pass", //通过
                "PATCH users/<uid:\d+>"=>"user/nopass", //不通过
                "GET users"=>"user/list",  //通过的用户列表
                "DELETE users/<uid:\d+>"=>"user/remove", //移除现有的用户
                "GET users/<uid:\d+>"=>"user/info", //网红的具体信息
                "GET users/serach"=>"user/serach", //搜索当前用户的用户


                //消息中心相关
                "GET  notices"=>"notice/list", //消息列表
                "PUT notices/<nid:\d+>"=>"notice/mark", //消息标记为已读
                "GET notices/status"=>"notice/status", //获取消息的概要
            ],

这部分的设计,参考官方文档对于RESTful实现的部分

  • GET /users: 逐页列出所有用户
  • HEAD /users: 显示用户列表的概要信息
  • POST /users: 创建一个新用户
  • GET /users/123: 返回用户 123 的详细信息
  • HEAD /users/123: 显示用户 123 的概述信息
  • PATCH /users/123 and PUT /users/123: 更新用户123
  • DELETE /users/123: 删除用户123
  • OPTIONS /users: 显示关于末端 /users 支持的动词
  • OPTIONS /users/123: 显示有关末端 /users/123 支持的动词

接收数据

我们需要获取客户端传递过来的GET,POST,Header的数据,框架自带了Yii::$app->request,可以直接得到客户端传过来的数据。

参考\yii\web\Request|\yii\console\Request $request The request component. This property is read-only.

处理数据

这部分和一般的项目一样,都用/models中的数据表对应的Model文件,继承了\yii\db\ActiveRecord的类,实现对数据表的CURD操作。

参考URL: http://www.yiichina.com/doc/guide/2.0/db-active-record

响应数据

我们在处理数据之后,需要返回给客户端对应的数据,在REST的设计规则里是这样处理的

  • Body只返回主要的数据,比如用户列表,用户的详细数据
  • Header返回其他的信息,包括页码信息,身份校验信息
  • 完全的使用HTTP状态码作为资源被请求状态的返回,比如404,403

HTTP状态码的说明如下

Code HTTP Operation Body Contents Description
200 GET,PUT 资源 操作成功
201 POST 资源,元数据 对象创建成功
202 POST,PUT,DELETE,PATCH N/A 请求已经被接受
204 DELETE,PUT,PATCH N/A 操作已经执行成功,但是没有返回数据
301 GET link 资源已被移除
303 GET link 重定向
304 GET N/A 资源没有被修改
400 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 参数列表错误(缺少,格式不匹配)
401 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 未授权
403 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 访问受限,授权过期
404 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 资源,服务未找到
405 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 不允许的http方法
409 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 资源冲突,或者资源被锁定
415 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 不支持的数据(媒体)类型
429 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 请求过多被限制
500 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 系统内部错误
501 GET,PSOT,PUT,DELETE,PATCH 错误提示(消息) 接口未实现

格式化数据,我们的返回数据的格式为JSON

$response= Yii::$app->response;
$response->format = \yii\web\Response::FORMAT_JSON; //返回json

错误处理

通过不同的错误码,返回不同的HTTP状态码。

由于的非常频繁的调用,所以对数据进行了封装。

错误处理类Error.php


/**
 * 错误处理类
 * 
 * ------------------------------------
 * 
 * 错误处理扩展 seaslog
 * 
 * http://www.oschina.net/news/50333/seaslog-0-21
 * 
 * http://neeke.github.io/SeasLog/
 *
 * ------------------------------------
 * 
 * @author Calvin 
 * @version 1.0
 * @copyright (c) 2016,
 */

namespace app\components\error;

use Yii;

class Error {

    /**
     * 公共的错误返回处理,通过传入参数,返回对应的错误代码,这里也定义了错误返回的格式,以及对日志的记录
     *
     * @param $error_code
     * @return array
     */
    public static function errorJson($error_code) {
        $requests = Yii::$app->request; //返回值
        $post = json_encode($requests->post());
        $get = json_encode($requests->get());
        $headers = json_encode($requests->getHeaders()->toArray());

        //带入记录错误代码的文件
        $error_file = require_once \Yii::$app->basePath . "/components/error/ErrorCode.php";
        //获取http状态码,以及文字说明
        $error_info = $error_file["$error_code"];


        $http_code = $error_info['http_code'];
        $error_text = $error_info['remark'];

        $error_body = [ //设置返回的格式
            'request' => $requests->getUrl(),
            'method'=>$requests->getMethod(),
            'error_code' => $error_code,
            'error' =>$error_text,
        ];

        $response = Yii::$app->response;
        $response->statusCode=$http_code;
        $response->format = \yii\web\Response::FORMAT_JSON;
        $headers = Yii::$app->response->headers;
        $headers->add('X-Halo-Result', 0);
//        $response->data = $error_body;


//        $userIP = $requests->userIP;
        //写入日志
//        \SeasLog::error('error === {error} && error_text === {error_text}  && userIP === {userIP} && post === {post}  && get === {get} && header === {header} ', [
//            '{error}' => $error,
//            '{error_text}' => $error_file["$error"],
//            '{post}' => $post,
//            '{get}' => $get,
//            '{userIP}' => $userIP,
//            '{header}' => $headers,
//                ], $request);
//        $appLog = \Alibaba::AppLog();
//        $appLog->debug("debug-log-emssage");
//        $appLog->info("info-log-emssage");
//        $appLog->warn("warn-log-emssage");
//        $appLog->error("error-log-emssage");

        return $error_body;
    }

}

错误代码文件ErrorCode.php

/**
 * 增加对不同类型的HTTP状态码的返回
 *
 * 错误码,HTTP状态码,返回值
 */
return [
    '1001'=>[
        'http_code'=>403,
        'remark'=>"Token验证失败",
    ],
    '1002'=>[
        'http_code'=>400,
        'remark'=>"参数错误",
    ],
    '1003'=>[
        'http_code'=>400,
        'remark'=>"参数不全",
    ],
    '2001'=>[
        'http_code'=>404,
        'remark'=>"用户不存在",
    ],

];

调用错误数据返回

return Error::errorJson(1002);

文档

有句话说得好,程序员不愿意写文档,但是看到没有文档的项目又会抓狂。。。。

概括结构

一个合格的API文档应该包含下面几项

  • 概括说明
  • 加密协议
  • 数据类型
  • 错误处理
  • 接口文档
  • 参考资料

接口文档

接口文档告诉客户端,调用什么数据,怎么掉,异常了咋办。。。

  • 简单说明
  • 访问地址
  • 请求方式
  • 返回结果
  • 返回结果字段说明
  • 错误代码
  • 更新记录

总结

RESTful API的好处在于更简洁的规范了数据请求的方式,通过资源来设计数据接口,方便客户端的调用,减少沟通成本。

不过协议毕竟只是个建议,我们可以根据自己项目的实际情况,有选择的满足协议的需求,更好的为自己的项目服务。

:)

参考资料

0
0
查看评论

yii2项目实战-restful api之授权验证

什么是restful风格的api呢?我们之前有写过大篇的文章来介绍其概念以及基本操作。 既然写过了,那今天是要说点什么吗? 这篇文章主要针对实际场景中api的部署来写。 我们今天就来大大的侃侃那些年api遇到的授权验证问题!独家干活,如果看完有所受益,记得不要忘记给我点赞哦。 ...
  • lhorse003
  • lhorse003
  • 2017-03-15 09:43
  • 5514

YII2 restful 试例

config['composer'] 的urlManager 配置'urlManager' => [ 'class' => 'yii\web\UrlManager', 'enablePret...
  • z330249949
  • z330249949
  • 2015-01-12 16:09
  • 7520

yii2之写一个最简单的restful 例子

yii2之写一个最简单的restful 例子 利用basic包,创建一个restful 例子        (1)首先将下载好的basic包放到服务器的根目录下,添加cookieValidationKey后,完成基本的配置后。按照上面的步骤配置yii2中的R...
  • aozeahj
  • aozeahj
  • 2016-09-03 22:55
  • 1874

Yii2快速构建RESTful Web服务功能简介

Yii2一个重要的功能升级是内置完整的RESTful支持。只需要简单的配置就可以为已有资源创建一整套服务,且包含开箱即用的安全(如OAuth2)、访问速率、定制字段、内容协商等等高级接口支持。
  • iefreer
  • iefreer
  • 2014-07-29 21:32
  • 31168

Yii2 使用 RESTful 写API接口 实例

Yii2 使用 RESTful? 其实 Yii2 框架本身就对 RESTful 是友好支持的,具体可以看官方文档(http://www.yiichina.com/doc/guide/2.0/rest-quick-start),或者去看源码,都是可以的 创建一个控制器  我的工作目录如图...
  • daxia_85
  • daxia_85
  • 2016-02-01 13:30
  • 15440

RESTful介绍和yii2中RESTful如何配置

RESTful介绍和yii2中RESTful如何配置   REST的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"。 从学术上来讲:   &...
  • aozeahj
  • aozeahj
  • 2016-09-02 22:21
  • 3687

Yii2 Restful API 原理分析

Yii2 有个很重要的特性是对 Restful API的默认支持, 通过短短的几个配置就可以实现简单的对现有Model的RESTful API 本文通过分析rest部分源码,简单剖析下yii2 实现 restful 的原理,并通过一些定制实现 对 关联模型的RESTful api 操作。 ~...
  • wjtlht928
  • wjtlht928
  • 2015-06-08 08:54
  • 802

Yii2.0 实现RESTful风格的简单API

一、创建数据库 首先,在mysql中创建一个名为yii2basic的数据库,并创建一张名为player的表。 二、配置 1.app/config/db.php <?php return [ 'class' => 'yii\db\Connecti...
  • AlanJager
  • AlanJager
  • 2016-05-10 10:48
  • 1898

yii2 RESTful api的详细使用

原文地址: http://www.manks.top/yii2-restful-api.html 什么是RESTful风格的API 对于各种客户端设备与服务端的通信,我们往往都通过API为客户端提供数据,提供某种资源。关于RESTful的概念,一查一大推,一两句也解...
  • lmjy102
  • lmjy102
  • 2017-02-16 15:50
  • 965

Yii2 基于RESTful架构的 advanced版API接口开发 配置、实现、测试

环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到下面的代码 LoadModule rewrite_module modules/mod_rewrite.so 将其前面的#去掉,如果没有找到则添加进去。 找到一下代码 ...
  • lmjy102
  • lmjy102
  • 2017-01-16 21:20
  • 2012
    个人资料
    • 访问:646003次
    • 积分:9078
    • 等级:
    • 排名:第2465名
    • 原创:297篇
    • 转载:13篇
    • 译文:4篇
    • 评论:82条
    博客专栏
    微信订阅号
    欢迎加入QQ群
    玩家老黄历(微信小程序)
    谢谢支持~
    最新评论