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

简介: Yii2实现RESTful架构配置最佳实践

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的好处在于更简洁的规范了数据请求的方式,通过资源来设计数据接口,方便客户端的调用,减少沟通成本。

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

😃

参考资料

相关文章
|
1月前
|
JSON 算法 安全
探索RESTful API设计的最佳实践
【9月更文挑战第2天】在数字化时代的浪潮中,后端开发如同搭建一座桥梁,连接着用户与数据的无限可能。本文将深入探讨如何打造高效、可维护的RESTful API,从资源命名到状态码的巧妙运用,每一个细节都隐藏着提升用户体验的智慧。你将学会如何在浩瀚的代码海洋中,用简洁明了的设计原则,引领用户安全抵达数据的彼岸。让我们一起启航,探索API设计的奥秘,让后端开发成为艺术与科学的完美结合。
|
18天前
|
消息中间件 缓存 监控
优化微服务架构中的数据库访问:策略与最佳实践
在微服务架构中,数据库访问的效率直接影响到系统的性能和可扩展性。本文探讨了优化微服务架构中数据库访问的策略与最佳实践,包括数据分片、缓存策略、异步处理和服务间通信优化。通过具体的技术方案和实例分析,提供了一系列实用的建议,以帮助开发团队提升微服务系统的响应速度和稳定性。
|
20天前
|
JSON 前端开发 API
打造高效后端:RESTful API 设计的最佳实践
【9月更文挑战第14天】在数字化时代,后端开发是构建强大、灵活和可维护应用程序的基石。本文将深入探讨如何设计高效的RESTful API,包括清晰的资源定义、合理的HTTP方法使用、URL结构规划、状态码的准确返回以及数据格式的设计。通过这些实践,开发者能够创建出既符合行业标准又易于维护和扩展的API,为前端提供强大的数据支持,确保整个应用的稳定性和性能。
157 74
|
12天前
|
API 网络架构 UED
构建RESTful API的最佳实践
【8月更文挑战第54天】在数字化时代,RESTful API已成为连接不同软件系统、提供数据服务的关键桥梁。本文将深入探讨如何构建高效、可维护的RESTful API,涵盖设计原则、安全策略和性能优化等关键方面。通过具体代码示例,我们将一步步展示如何实现一个简洁、直观且功能强大的API。无论你是新手还是有经验的开发者,这篇文章都将为你提供宝贵的指导和启示。
62 33
|
1天前
|
API 开发者 UED
构建高效RESTful API的最佳实践
【9月更文挑战第33天】在数字化时代,后端开发不仅仅是关于代码的编写。它是一场架构艺术的演绎,是性能与可维护性之间的舞蹈。本文将带你深入理解RESTful API设计的精髓,探索如何通过最佳实践提升API的效率和可用性,最终实现后端服务的优雅蜕变。我们将从基础原则出发,逐步揭示高效API设计背后的哲学,并以实际代码示例为路标,指引你走向更优的后端开发之路。
|
8天前
|
缓存 监控 测试技术
深入理解RESTful API设计原则与最佳实践
【9月更文挑战第26天】在数字化时代,API(应用程序编程接口)已成为连接不同软件和服务的桥梁。本文将深入浅出地介绍RESTful API的设计哲学、六大约束条件以及如何将这些原则应用到实际开发中,以实现高效、可维护和易于扩展的后端服务。通过具体实例,我们将探索如何避免常见设计陷阱,确保API设计的优雅与实用性并存。无论你是API设计的新手还是经验丰富的开发者,这篇文章都将为你提供宝贵的指导和启示。
|
10天前
|
缓存 前端开发 API
深入浅出:RESTful API设计的最佳实践
【9月更文挑战第24天】在数字化浪潮中,API作为连接不同软件组件的桥梁,其设计质量直接影响到系统的可维护性、扩展性及用户体验。本文将通过浅显易懂的语言,结合生动的比喻和实例,带领读者深入理解RESTful API设计的核心原则与最佳实践,旨在帮助开发者构建更加健壮、灵活且用户友好的后端服务。
|
13天前
|
API
构建高效RESTful API的最佳实践
【9月更文挑战第21天】在数字化时代,API已成为软件应用间沟通的桥梁。本文将探讨如何设计和维护一个高效的RESTful API,确保它不仅能够快速响应,同时也易于扩展和维护。我们将通过实际的代码示例来揭示这些最佳实践背后的逻辑和原理,帮助你构建一个既稳定又灵活的后端服务。
|
22天前
|
Kubernetes Docker 微服务
构建高效的微服务架构:基于Docker和Kubernetes的最佳实践
在现代软件开发中,微服务架构因其灵活性和可扩展性而受到广泛青睐。本文探讨了如何利用Docker和Kubernetes来构建高效的微服务架构。我们将深入分析Docker容器的优势、Kubernetes的编排能力,以及它们如何结合实现高可用性、自动扩展和持续部署。通过具体的最佳实践和实际案例,读者将能够理解如何优化微服务的管理和部署过程,从而提高开发效率和系统稳定性。
|
29天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
58 2
下一篇
无影云桌面