CodeIgniter RestServer 项目教程:构建专业级REST API的终极指南

CodeIgniter RestServer 项目教程:构建专业级REST API的终极指南

【免费下载链接】codeigniter-restserver A fully RESTful server implementation for CodeIgniter using one library, one config file and one controller. 【免费下载链接】codeigniter-restserver 项目地址: https://gitcode.com/gh_mirrors/co/codeigniter-restserver

还在为CodeIgniter 3项目构建REST API而烦恼?传统方式需要编写大量重复代码,处理复杂的HTTP请求响应逻辑,还要考虑认证、限流、日志等基础设施。CodeIgniter RestServer项目正是为解决这些痛点而生,让你用最简洁的方式构建功能完整的RESTful服务。

读完本文你将获得

  • ✅ CodeIgniter RestServer核心架构深度解析
  • ✅ 从零开始搭建REST API服务的完整流程
  • ✅ 多种认证机制(API Key、Basic Auth、LDAP)实战配置
  • ✅ 请求限流、日志记录、CORS等高级功能配置指南
  • ✅ 多格式数据输出(JSON、XML、CSV、HTML)最佳实践
  • ✅ 生产环境部署和性能优化策略

项目概述与技术架构

CodeIgniter RestServer是一个专为CodeIgniter 3设计的RESTful服务器实现库,通过"一个库、一个配置文件、一个控制器"的极简理念,提供了完整的REST API开发解决方案。

核心架构图

mermaid

环境要求与安装

系统要求

  • PHP 7.2或更高版本
  • CodeIgniter 3.1.11+

安装步骤

通过Composer安装是最推荐的方式:

composer require chriskacerguis/codeigniter-restserver

或者在composer.json中添加依赖:

{
    "require": {
        "chriskacerguis/codeigniter-restserver": "^3.1"
    }
}

配置文件设置

安装完成后,需要将src/rest.php配置文件复制到CodeIgniter的config目录:

cp vendor/chriskacerguis/codeigniter-restserver/src/rest.php application/config/

快速入门:构建第一个REST API

创建基础控制器

创建一个新的API控制器application/controllers/Api.php

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

use chriskacerguis\RestServer\RestController;

class Api extends RestController {

    function __construct()
    {
        parent::__construct();
    }

    // 处理GET请求 - 获取用户列表或单个用户
    public function users_get()
    {
        // 模拟用户数据
        $users = [
            ['id' => 1, 'name' => '张三', 'email' => 'zhangsan@example.com'],
            ['id' => 2, 'name' => '李四', 'email' => 'lisi@example.com'],
            ['id' => 3, 'name' => '王五', 'email' => 'wangwu@example.com']
        ];

        $id = $this->get('id');

        if ($id === null) {
            // 返回所有用户
            $this->response([
                'status' => true,
                'message' => '用户列表获取成功',
                'data' => $users
            ], 200);
        } else {
            // 查找特定用户
            $user = array_filter($users, function($u) use ($id) {
                return $u['id'] == $id;
            });
            
            if (!empty($user)) {
                $this->response([
                    'status' => true,
                    'message' => '用户信息获取成功',
                    'data' => array_values($user)[0]
                ], 200);
            } else {
                $this->response([
                    'status' => false,
                    'message' => '用户不存在'
                ], 404);
            }
        }
    }

    // 处理POST请求 - 创建新用户
    public function users_post()
    {
        $name = $this->post('name');
        $email = $this->post('email');

        if (empty($name) || empty($email)) {
            $this->response([
                'status' => false,
                'message' => '姓名和邮箱不能为空'
            ], 400);
        }

        // 模拟创建用户(实际应保存到数据库)
        $newUser = [
            'id' => count($this->users) + 1,
            'name' => $name,
            'email' => $email,
            'created_at' => date('Y-m-d H:i:s')
        ];

        $this->response([
            'status' => true,
            'message' => '用户创建成功',
            'data' => $newUser
        ], 201);
    }

    // 处理PUT请求 - 更新用户
    public function users_put()
    {
        $id = $this->put('id');
        $name = $this->put('name');
        $email = $this->put('email');

        // 这里应该有实际的更新逻辑
        $this->response([
            'status' => true,
            'message' => '用户更新成功',
            'data' => ['id' => $id, 'name' => $name, 'email' => $email]
        ], 200);
    }

    // 处理DELETE请求 - 删除用户
    public function users_delete($id)
    {
        // 这里应该有实际的删除逻辑
        $this->response([
            'status' => true,
            'message' => "用户ID {$id} 删除成功"
        ], 200);
    }
}

API端点测试

使用不同的HTTP方法和参数测试API:

HTTP方法URL功能描述
GET/api/users获取所有用户列表
GET/api/users?id=1获取ID为1的用户信息
POST/api/users创建新用户
PUT/api/users更新用户信息
DELETE/api/users/1删除ID为1的用户

高级功能配置详解

认证机制配置

CodeIgniter RestServer支持多种认证方式,以下是最常用的配置:

1. API Key认证
// application/config/rest.php
$config['rest_enable_keys'] = true;
$config['rest_keys_table'] = 'api_keys';
$config['rest_key_name'] = 'X-API-KEY';

// 数据库表结构
CREATE TABLE `api_keys` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `user_id` INT(11) NOT NULL,
    `key` VARCHAR(40) NOT NULL,
    `level` INT(2) NOT NULL,
    `ignore_limits` TINYINT(1) NOT NULL DEFAULT '0',
    `ip_addresses` TEXT NULL,
    `date_created` INT(11) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. Basic认证配置
$config['rest_auth'] = 'basic';
$config['rest_valid_logins'] = ['admin' => 'password123'];
3. 混合认证模式
$config['allow_auth_and_keys'] = true;
$config['rest_auth'] = 'basic';
$config['rest_enable_keys'] = true;

请求限流配置

防止API被滥用,配置请求频率限制:

$config['rest_enable_limits'] = true;
$config['rest_limits_method'] = 'IP_ADDRESS'; // 或 'API_KEY'
$config['rest_limits_table'] = 'api_limits';

// 控制器中设置具体限制
public function __construct()
{
    parent::__construct();
    
    $this->methods['users_get']['limit'] = 100; // 每小时100次
    $this->methods['users_post']['limit'] = 10;  // 每小时10次
}

日志记录配置

启用API访问日志记录:

$config['rest_enable_logging'] = true;
$config['rest_logs_table'] = 'api_logs';
$config['rest_logs_json_params'] = true;

// 日志表结构
CREATE TABLE `api_logs` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `uri` VARCHAR(255) NOT NULL,
    `method` VARCHAR(6) NOT NULL,
    `params` TEXT DEFAULT NULL,
    `api_key` VARCHAR(40) DEFAULT NULL,
    `ip_address` VARCHAR(45) NOT NULL,
    `time` INT(11) NOT NULL,
    `rtime` FLOAT DEFAULT NULL,
    `authorized` TINYINT(1) NOT NULL,
    `response_code` SMALLINT(3) DEFAULT '0',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CORS跨域配置

支持前端跨域访问:

$config['check_cors'] = true;
$config['allowed_cors_origins'] = ['http://localhost:3000', 'https://yourdomain.com'];
$config['allowed_cors_methods'] = ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'];
$config['allowed_cors_headers'] = ['Origin', 'X-Requested-With', 'Content-Type', 'Accept'];

数据格式处理

支持的数据格式

CodeIgniter RestServer支持多种数据格式输出:

格式Content-Type使用场景
JSONapplication/json现代Web和移动应用
XMLapplication/xml传统系统集成
CSVapplication/csv数据导出
HTMLtext/html网页展示
JSONPapplication/javascript跨域请求

格式配置示例

// 配置支持的所有格式
$config['rest_supported_formats'] = [
    'json',
    'xml',
    'csv',
    'html'
];

// 设置默认输出格式
$config['rest_default_format'] = 'json';

控制器中的格式控制

class Products extends RestController {
    
    public function __construct()
    {
        parent::__construct();
        $this->rest_format = 'json'; // 控制器级别默认格式
    }
    
    public function list_get()
    {
        $products = [/* 产品数据 */];
        
        // 根据请求参数动态选择格式
        $format = $this->_detect_output_format();
        
        switch ($format) {
            case 'xml':
                $this->response($products, 200);
                break;
            case 'csv':
                $this->response($products, 200);
                break;
            default:
                $this->response([
                    'status' => true,
                    'data' => $products
                ], 200);
        }
    }
}

错误处理与状态码

标准HTTP状态码使用

class Api extends RestController {
    
    public function resource_get($id)
    {
        try {
            $resource = $this->resource_model->get($id);
            
            if (!$resource) {
                $this->response([
                    'status' => false,
                    'message' => '资源不存在'
                ], 404); // Not Found
            }
            
            $this->response([
                'status' => true,
                'data' => $resource
            ], 200); // OK
            
        } catch (Exception $e) {
            $this->response([
                'status' => false,
                'message' => '服务器内部错误',
                'error' => $e->getMessage()
            ], 500); // Internal Server Error
        }
    }
    
    public function create_post()
    {
        $data = $this->post();
        
        if (empty($data)) {
            $this->response([
                'status' => false,
                'message' => '请求数据不能为空'
            ], 400); // Bad Request
        }
        
        // 验证数据...
        if (!$this->form_validation->run()) {
            $this->response([
                'status' => false,
                'message' => '数据验证失败',
                'errors' => validation_errors_array()
            ], 422); // Unprocessable Entity
        }
        
        $id = $this->resource_model->create($data);
        
        $this->response([
            'status' => true,
            'message' => '创建成功',
            'data' => ['id' => $id]
        ], 201); // Created
    }
}

自定义错误处理

class Custom_api extends RestController {
    
    protected function early_checks()
    {
        // 在请求处理前进行自定义检查
        if (!$this->check_something()) {
            $this->response([
                'status' => false,
                'message' => '自定义检查失败'
            ], 403);
        }
    }
    
    public function _remap($object_called, $arguments = [])
    {
        try {
            parent::_remap($object_called, $arguments);
        } catch (Exception $e) {
            // 统一异常处理
            log_message('error', 'API异常: ' . $e->getMessage());
            
            $this->response([
                'status' => false,
                'message' => '服务暂时不可用',
                'code' => 'SERVICE_UNAVAILABLE'
            ], 503);
        }
    }
}

性能优化与最佳实践

数据库优化策略

class Optimized_api extends RestController {
    
    private $cache_time = 300; // 5分钟缓存
    
    public function products_get()
    {
        $category_id = $this->get('category_id');
        $page = $this->get('page', 1);
        $limit = $this->get('limit', 20);
        
        // 使用缓存键
        $cache_key = "products_{$category_id}_{$page}_{$limit}";
        
        // 尝试从缓存获取
        $products = $this->cache->get($cache_key);
        
        if (!$products) {
            // 数据库查询优化
            $this->db->select('id, name, price, category_id, created_at');
            $this->db->from('products');
            $this->db->where('status', 'active');
            
            if ($category_id) {
                $this->db->where('category_id', $category_id);
            }
            
            $this->db->order_by('created_at', 'DESC');
            $this->db->limit($limit, ($page - 1) * $limit);
            
            $products = $this->db->get()->result_array();
            
            // 设置缓存
            $this->cache->save($cache_key, $products, $this->cache_time);
        }
        
        $this->response([
            'status' => true,
            'data' => $products,
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => $this->get_total_count($category_id)
            ]
        ], 200);
    }
}

安全最佳实践

// application/config/rest.php
$config['force_https'] = ENVIRONMENT === 'production';
$config['rest_ip_blacklist_enabled'] = true;
$config['rest_ip_blacklist'] = '123.456.789.0, 987.654.321.0';
$config['rest_ajax_only'] = false; // 生产环境可设为true

// 控制器中的安全措施
class Secure_api extends RestController {
    
    public function __construct()
    {
        parent::__construct();
        
        // 启用XSS过滤
        $this->_enable_xss = true;
        
        // 方法级别的访问控制
        $this->methods['sensitive_data_get']['limit'] = 5;
        $this->methods['sensitive_data_get']['level'] = 2; // 需要更高级别的API Key
    }
    
    protected function early_checks()
    {
        // 请求频率检查
        if ($this->is_rate_limited()) {
            $this->response([
                'status' => false,
                'message' => '请求过于频繁,请稍后再试'
            ], 429);
        }
    }
}

实战案例:电商API系统

完整的商品API示例

class Products extends RestController {
    
    public function __construct()
    {
        parent::__construct();
        $this->load->model('product_model');
        $this->load->library('form_validation');
    }
    
    // 获取商品列表
    public function index_get()
    {
        $filters = [
            'category_id' => $this->get('category_id'),
            'min_price' => $this->get('min_price'),
            'max_price' => $this->get('max_price'),
            'keyword' => $this->get('keyword'),
            'page' => $this->get('page', 1),
            'limit' => $this->get('limit', 20),
            'sort_by' => $this->get('sort_by', 'created_at'),
            'sort_order' => $this->get('sort_order', 'DESC')
        ];
        
        $products = $this->product_model->get_products($filters);
        $total = $this->product_model->count_products($filters);
        
        $this->response([
            'status' => true,
            'data' => $products,
            'pagination' => [
                'current_page' => $filters['page'],
                'per_page' => $filters['limit'],
                'total' => $total,
                'total_pages' => ceil($total / $filters['limit'])
            ]
        ], 200);
    }
    
    // 获取单个商品详情
    public function detail_get($id)
    {
        $product = $this->product_model->get_product($id);
        
        if (!$product) {
            $this->response([
                'status' => false,
                'message' => '商品不存在'
            ], 404);
        }
        
        $this->response([
            'status' => true,
            'data' => $product
        ], 200);
    }
    
    // 创建新商品(需要管理员权限)
    public function create_post()
    {
        // 权限检查
        if (!$this->is_admin()) {
            $this->response([
                'status' => false,
                'message' => '权限不足'
            ], 403);
        }
        
        $data = $this->post();
        
        // 数据验证
        $this->form_validation->set_data($data);
        $this->form_validation->set_rules('name', '商品名称', 'required|min_length[2]|max_length[100]');
        $this->form_validation->set_rules('price', '价格', 'required|numeric|greater_than[0]');
        $this->form_validation->set_rules('stock', '库存', 'required|integer|greater_than_equal_to[0]');
        
        if (!$this->form_validation->run()) {
            $this->response([
                'status' => false,
                'message' => '数据验证失败',
                'errors' => $this->form_validation->error_array()
            ], 422);
        }
        
        $product_id = $this->product_model->create_product($data);
        
        $this->response([
            'status' => true,
            'message' => '商品创建成功',
            'data' => ['id' => $product_id]
        ], 201);
    }
    
    // 更新商品信息
    public function update_put($id)
    {
        if (!$this->is_admin()) {
            $this->response([
                'status' => false,
                'message' => '权限不足'
            ], 403);
        }
        
        $data = $this->put();
        
        $result = $this->product_model->update_product($id, $data);
        
        if (!$result) {
            $this->response([
                'status' => false,
                'message' => '商品更新失败'
            ], 400);
        }
        
        $this->response([
            'status' => true,
            'message' => '商品更新成功'
        ], 200);
    }
    
    // 删除商品
    public function delete_delete($id)
    {
        if (!$this->is_admin()) {
            $this->response([
                'status' => false,
                'message' => '权限不足'
            ], 403);
        }
        
        $result = $this->product_model->delete_product($id);
        
        if (!$result) {
            $this->response([
                'status' => false,
                'message' => '商品删除失败'
            ], 400);
        }
        
        $this->response([
            'status' => true,
            'message' => '商品删除成功'
        ], 200);
    }
    
    // 权限检查方法
    private function is_admin()
    {
        // 这里实现具体的权限检查逻辑
        return $this->rest->level >= 2; // 假设2是管理员级别
    }
}

部署与监控

生产环境配置

// application/config/rest.php 生产环境配置
$config['force_https'] = true;
$config['rest_ajax_only'] = true;
$config['rest_enable_logging'] = true;
$config['rest_enable_limits'] = true;
$config['rest_enable_keys'] = true;
$config['check_cors'] = true;
$config['allow_any_cors_domain'] = false;
$config['allowed_cors_origins'] = ['https://yourdomain.com'];

监控与日志分析

-- 常用的监控查询
SELECT 
    DATE_FORMAT(FROM_UNIXTIME(time), '%Y-%m-%d %H:00') as hour,
    method,
    uri,
    COUNT(*) as request_count,
    AVG(rtime) as avg_response_time,
    MAX(rtime) as max_response_time,
    SUM(CASE WHEN response_code >= 400 THEN 1 ELSE 0 END) as error_count
FROM api_logs 
WHERE time >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 24 HOUR))
GROUP BY hour, method, uri
ORDER BY hour DESC, request_count DESC;

-- API Key使用情况监控
SELECT 
    k.key,
    u.username,
    COUNT(l.id) as total_requests,
    SUM(CASE WHEN l.time >= UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 1 HOUR)) THEN 1 ELSE 0 END) as last_hour_requests
FROM api_keys k
LEFT JOIN users u ON k.user_id = u.id
LEFT JOIN api_logs l ON k.key = l.api_key
GROUP BY k.id
ORDER BY total_requests DESC;

常见问题与解决方案

Q1: 如何处理文件上传?

public function upload_post()
{
    $config['upload_path'] = './uploads/';
    $config['allowed_types'] = 'gif|jpg|png';
    $config['max_size'] = 2048;
    
    $this->load->library('upload', $config);
    
    if (!$this->upload->do_upload('file')) {
        $this->response([
            'status' => false,
            'message' => '文件上传失败',
            'errors' => $this->upload->display_errors()
        ], 400);
    }
    
    $data = $this->upload->data();
    
    $this->response([
        'status' => true,
        'message' => '文件上传成功',
        'data' => [
            'file_name' => $data['file_name'],
            'file_size' => $data['file_size'],
            'image_width' => $data['image_width'],
            'image_height' => $data['image_height']
        ]
    ], 201);
}

Q2: 如何实现API版本控制?

class Api_v1 extends RestController {
    // 版本1的API实现
}

class Api_v2 extends RestController {
    // 版本2的API实现
}

// 在routes.php中配置版本路由
$route['api/v1/(:any)'] = 'api_v1/$1';
$route['api/v2/(:any)'] = 'api_v2/$1';

Q3: 如何优化大量数据的响应性能?

public function large_data_get()
{
    // 使用分页
    $page = $this->get('page', 1);
    $limit = $this->get('limit', 1000);
    
    // 使用字段选择,避免SELECT *
    $this->db->select('id, name, created_at');
    
    // 使用流式响应
    $this->output->set_content_type('application/json');
    
    echo '[';
    $first = true;
    
    $query = $this->db->get('large_table');
    foreach ($query->result() as $row) {
        if (!$first) {
            echo ',';
        }
        echo json_encode($row);
        $first = false;
        
        // 刷新输出缓冲区
        if (ob_get_level() > 0) {
            ob_flush();
        }
        flush();
    }
    
    echo ']';
    exit;
}

总结与展望

CodeIgniter RestServer为CodeIgniter 3项目提供了强大而灵活的REST API开发能力。通过本文的详细讲解,你应该已经掌握了:

  1. 基础搭建 - 从安装配置到第一个API的创建
  2. 高级功能 - 认证、限流、日志、CORS等企业级功能
  3. 最佳实践 - 性能优化、安全措施、错误处理
  4. 实战案例 - 完整的电商API系统实现
  5. 生产部署 - 监控、调优和问题解决

虽然CodeIgniter 4已经内置了REST支持,但对于仍在维护CodeIgniter 3项目的团队来说,RestServer仍然是构建REST API的最佳选择。它的简洁性、灵活性和丰富的功能集,能够满足从简单到复杂的所有API开发需求。

未来,随着微服务架构和云原生应用的普及,良好的API设计变得更加重要。掌握CodeIgniter RestServer的使用,不仅能够提升现有项目的开发效率,也为后续的技术架构演进打下坚实基础。


如果本文对你有帮助,请点赞、收藏、关注三连支持!后续将带来更多CodeIgniter和API开发相关的深度内容。

【免费下载链接】codeigniter-restserver A fully RESTful server implementation for CodeIgniter using one library, one config file and one controller. 【免费下载链接】codeigniter-restserver 项目地址: https://gitcode.com/gh_mirrors/co/codeigniter-restserver

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值