PHP 基于 SW-X 框架,搭建高性能API架构(一)

简介: 2022年PHP搭建API接口最优框架的选择

前言

官网地址:SW-X框架-专注高性能便捷开发而生的PHP-SwooleX框架

希望各大佬举起小手,给小弟一个star:https://github.com/swoolex/swoolex

架构图谱

版本更新规则

每个新版本迭代以v1.0.1的大中小版本起名,应用代码存储在/app/http/版本号目录下,.改为_

新版本需要拷贝上一个版本的可用代码,进行修改,并保留原代码。

版本发布

每个新版本开发完成后,需要在/box/route.php文件中,修改镜像路由地址,使其生效到对外接口地址中,如下:

use \x\Route;
// 对前端开放版本映射
Route::mirror([
    '/v1_0_1/controller/' => '/api/',
]);

控制器命名

控制器统一存储在/app/http/版本号/controller/目录下,以一个接口一个文件的方法进行定义。

例如,需要编写一个Shop模块的create接口,那应该创建文件如下:

文件地址:/app/http/版本号/controller/shop/create.php,代码如下:

namespace app\http\v1_0_1\controller\shop;
use x\controller\Http;
class create extends Http
{
    /**
     * index方法默认会在路由中忽略
    */
    public function index() {
  return $this->fetch('演示控制器');
    }
}

未通过镜像路由映射前的访问地址是:/v1_0_1/controller/shop/create

通过镜像路由映射后的访问地址是:/api/shop/create

请求类型限制

对于GET|POST|AJAX请求类型的限制,统一使用@Get@Post@Ajax的方式声明。

例如限制只允许POST-AJAX问题的接口:

namespace app\http\v1_0_1\controller\shop;
use x\controller\Http;
class create extends Http
{
    /**
     * index方法默认会在路由中忽略
     * @Post
     * @Ajax
    */
    public function index() {
  return $this->fetch('演示控制器');
    }
}

参数默认值预设

控制器中,禁止使用以下习惯申明参数默认值:

namespace app\http\v1_0_1\controller\shop;
use x\controller\Http;
class create extends Http
{
    /**
     * index方法默认会在路由中忽略
    */
    public function index() {
        $param = \x\Request::get();
        // 场景一
        if (!isset($param['status'])) $param['status'] = 1;
        // 场景二
        $param['status'] = (isset($param['status']) == false) ? 1 : $param['status'];
        // 场景三
        $param['status'] = $param['status'] ??1;
    }
}

对于以上isset()判断参数是否未传递后,设置默认值的场景,要统一使用@Param注解提前声明,例如:

namespace app\http\v1_0_1\controller\shop;
use x\controller\Http;
class create extends Http
{
    /**
     * index方法默认会在路由中忽略
    * @Param(name="status", value="1")
    */
    public function index() {
        $param = \x\Request::get();
        // 如果未提交的情况下,可以直接获取到默认值
        var_dump($param['status']);
    }
}

警告:@Param注解参数预设,只对isset()场景有效,empty()is_null()等为空场景无效。

表单校验

禁止在控制器中编写表单格式校验的任何代码,表单校验需要统一在/box/validate/目录中创建校验器。

校验器的具体使用方法,可以参考SW-X官网文档:校验器

例如创建一个司机相关的校验器,文件:/boxx/validate/Driver.php,代码如下,包含了3种校验场景:

namespace box\validate;
use x\Validate;
class Driver extends Validate
{
    // 定义字段对应的规则
    protected $rule = [
        'id'         => 'require|int',
        'driver_sn'  => 'require|between:1,120',
        'phone'      => 'require|phone'
    ];
    // 自定义错误值声明
    protected $message  =   [
        'id.require'          => '{:preset}未提交', 
        'id.int'              => '{:preset}不是整数格式',
        'driver_sn.require'   => '{:preset}未提交', 
        'driver_sn.between'   => '{:preset}长度只能在{0}-{1}位之间',
        'phone.require'       => '{:preset}未提交',
        'phone.phone'         => '{:preset}格式错误',
    ];
    // 可以设置message时的字段别名,会把{字段名}占位符替换后一起抛出
    protected $alias = [
        'id' => '司机ID',
        'driver_sn' => '司机编号',
        'phone' => '司机手机号码',
    ];
    // 场景定义
    protected $scene = [
        // 编辑
        'edit' => ['id','driver_sn', 'phone'], // 需要校验的字段
        // 新增
        'create' => ['driver_sn', 'phone'],
        // 查询表单
        'select' => [
            'field' => ['driver_sn', 'phone'], // 需要校验的字段
            'delete_rule' => [ // 删除校验规则
                'driver_sn' => 'require',
                'phone' => 'require',
            ],
        ],
    ];
}

创建完成后,使用@Validate注解,在控制器中进行场景绑定:

namespace app\http\v1_0_1\controller\shop;
use x\controller\Http;
class create extends Http
{
    /**
     * index方法默认会在路由中忽略
    * @Validate(class="\box\validate\Driver", scene="create")
    */
    public function index() {
  return $this->fetch('演示控制器');
    }
}

权限校验

API统一绑定了全局中间件/box/middleware/Auth.php,如果需要跳过权限校验的Api,需要修改该中间件内部的$_skip成员属性即可。

Api-Restful管理

API统一使用Restful模块进行管理,目录在/restful/目录下,状态码与返回值说明存放在/restful/default/目录下。

例如现在要添加一个DRIVER_ERROR的状态码,对应CODE30001MSG司机不存在

同时,该状态码下,还有一个MSG司机余额不足

那么应该这样定义,

修改/restful/default/code.php文件为如下代码:

return [
    'DRIVER_ERROR' => 30001, // 司机错误信息相关
];

再修改/restful/default/msg.php文件为如下代码:

return [
    // default表示默认使用的msg
    'DRIVER_ERROR' => [
        'default' => '司机不存在', // 默认值
        'balance_not' => '司机余额不足',
    ]
];

在控制器中就可以这样使用:

namespace app\http\v1_0_1\controller\shop;
use x\controller\Http;
use x\Restful;
class create extends Http
{
    /**
     * index方法默认会在路由中忽略
    */
    public function index() {
      // 会默认使用default的MSG
      return Restful::code(Restful::DRIVER_ERROR())->callback();
        // 也可以指定抛出的MSG
        return Restful::code(Restful::DRIVER_ERROR())->msg('balance_not')->callback();
        // 如果要抛出数据集
        return Restful::code(Restful::DRIVER_ERROR())->data('数据集')->callback();
    }
}

更多关于Restful的使用方法,可以参考SW-X官网文档:Restful支持

关于Restful返回值强类型转换

系统会自动把返回值中字符串类型(string)的intfloat数据转换回真实类型。

空字符串,转换回null

注意,如果是string*.00会被强制转换成int类型的*

也就是0.00会被转成018.00会被转成18,这是PHP数据结构的先天上问题。

例如:

{
  "code": 0,
  "msg": "请求成功",
  "data": {
    "user_id": "100",
    "money": "19.01",
    "list": [
      {
        "id": "1",
        "money": "0.00"
      },
      {
        "id": "2",
        "money": "18.00"
      }
    ],
    "region_id": ""
  }
}

会被转换成:

{
  "code": 0,
  "msg": "请求成功",
  "data": {
    "user_id": 100,
    "money": 19.01,
    "list": [
      {
        "id": 1,
        "money": 0
      },
      {
        "id": 2,
        "money": 18
      }
    ],
    "region_id": null
  }
}

数据模型

控制器中,禁止直接使用Db基类操作,任何数据库相关的操作,都应该统一创建对应的Model类进行逻辑采集处理。

Model的存储目录为:/app/http/版本号/model/目录下。

例如司机表的新增操作,应该创建一个DriverModel.php文件:

namespace app\http\v1_0_1\model;
use x\Model;
class DriverModel extends Model
{
    // 添加司机
  public function add($data) {
    return $this->insert($data);
    }
    // 编辑司机
  public function edit($data) {
        return $this->where('id', $data['id'])->update($data);
    }
}

下一章节,我们再来开始,一步步的搭建整个API项目架构。

相关文章
|
26天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
23天前
|
API
用 Koa 框架实现一个简单的 RESTful API
用 Koa 框架实现一个简单的 RESTful API
|
24天前
|
存储 分布式计算 关系型数据库
架构/技术框架调研
本文介绍了微服务间事务处理、调用、大数据处理、分库分表、大文本存储及数据缓存的最优解决方案。重点讨论了Seata、Dubbo、Hadoop生态系统、MyCat、ShardingSphere、对象存储服务和Redis等技术,提供了详细的原理、应用场景和优缺点分析。
|
9天前
|
设计模式 负载均衡 监控
探索微服务架构下的API网关设计
在微服务的大潮中,API网关如同一座桥梁,连接着服务的提供者与消费者。本文将深入探讨API网关的核心功能、设计原则及实现策略,旨在为读者揭示如何构建一个高效、可靠的API网关。通过分析API网关在微服务架构中的作用和挑战,我们将了解到,一个优秀的API网关不仅要处理服务路由、负载均衡、认证授权等基础问题,还需考虑如何提升系统的可扩展性、安全性和可维护性。文章最后将提供实用的代码示例,帮助读者更好地理解和应用API网关的设计概念。
37 8
|
1月前
|
监控
SMoA: 基于稀疏混合架构的大语言模型协同优化框架
通过引入稀疏化和角色多样性,SMoA为大语言模型多代理系统的发展开辟了新的方向。
37 6
SMoA: 基于稀疏混合架构的大语言模型协同优化框架
|
20天前
|
缓存 API 数据库
Python哪个框架合适开发速卖通商品详情api?
在跨境电商平台速卖通的商品详情数据获取与整合中,Python 语言及其多种框架(如 Flask、Django、Tornado 和 FastAPI)提供了高效解决方案。Flask 简洁灵活,适合快速开发;Django 功能全面,适用于大型项目;Tornado 性能卓越,擅长处理高并发;FastAPI 结合类型提示和异步编程,开发体验优秀。选择合适的框架需综合考虑项目规模、性能要求和团队技术栈。
25 2
|
28天前
|
SQL 缓存 测试技术
构建高性能RESTful API:最佳实践与避坑指南###
—— 本文深入探讨了构建高性能RESTful API的关键技术要点,从设计原则、状态码使用、版本控制到安全性考虑,旨在为开发者提供一套全面的最佳实践框架。通过避免常见的设计陷阱,本文将指导你如何优化API性能,提升用户体验,确保系统的稳定性和可扩展性。 ###
57 12
|
23天前
|
JSON JavaScript 中间件
Koa框架下的RESTful API设计与实现
在现代 Web 开发中,构建高效、可维护的 API 是至关重要的。Koa 是一个流行的 Node.js Web 应用框架,它具有简洁、灵活和强大的特性,非常适合用于设计和实现 RESTful API。
|
22天前
|
开发框架 Java 关系型数据库
Java哪个框架适合开发API接口?
在快速发展的软件开发领域,API接口连接了不同的系统和服务。Java作为成熟的编程语言,其生态系统中出现了许多API开发框架。Magic-API因其独特优势和强大功能,成为Java开发者优选的API开发框架。本文将从核心优势、实际应用价值及未来展望等方面,深入探讨Magic-API为何值得选择。
31 2
|
29天前
|
API PHP 数据库
PHP中哪个框架最适合做API?
在数字化时代,API作为软件应用间通信的桥梁至关重要。本文探讨了PHP中适合API开发的主流框架,包括Laravel、Symfony、Lumen、Slim、Yii和Phalcon,分析了它们的特点和优势,帮助开发者选择合适的框架,提高开发效率、保证接口稳定性和安全性。
53 3