You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel同时存在网页端与API时如何配置路由避免控制器重复?

解决方案

最优最高效方案:利用Laravel内置的请求类型判断

Laravel 自带expectsJson()方法,可以自动识别当前请求是否需要返回JSON格式响应,不需要拆分控制器,只需要修改原CustomersController的index方法,加一行判断逻辑即可,全程复用现有查询代码,没有冗余。

代码示例

原index方法逻辑:

public function index()
{
    $customers = Customer::all();
    return view('customers.index', compact('customers'));
}

修改后的兼容逻辑:

public function index()
{
    $customers = Customer::all();
    
    // 识别API请求自动返回JSON,网页请求照常返回视图
    if (request()->expectsJson()) {
        // 简单场景可直接返回集合,Laravel会自动序列化为JSON
        // return $customers;
        
        // 规范场景推荐用API资源统一格式化输出结构
        return \App\Http\Resources\CustomerResource::collection($customers);
    }

    return view('customers.index', compact('customers'));
}

路由配置

直接在api.php中添加对应路由即可,API路由默认带/api前缀,不会和web路由冲突:

use App\Http\Controllers\CustomersController;

Route::get('/customers', [CustomersController::class, 'index']);

进阶优化(适合复杂业务场景)

如果后续客户查询逻辑变复杂(需要加筛选、分页、权限判断等),可以把公共业务逻辑抽成服务层,后续就算要拆分Web和API控制器也不会产生重复代码:

  1. 新建服务类app/Services/CustomerService.php封装查询逻辑:
namespace App\Services;

use App\Models\Customer;

class CustomerService
{
    public function getCustomerList()
    {
        return Customer::query()
            ->where('is_active', 1)
            ->latest()
            ->paginate(20);
    }
}
  1. 控制器中注入服务类调用:
public function index(CustomerService $customerService)
{
    $customers = $customerService->getCustomerList();
    
    if (request()->expectsJson()) {
        return \App\Http\Resources\CustomerResource::collection($customers);
    }

    return view('customers.index', compact('customers'));
}

方案优势

  • 零额外扩展依赖,完全符合Laravel原生设计规范
  • 100%复用现有业务逻辑,没有冗余代码
  • 扩展性强,后续修改查询逻辑只需要改动一处即可同步生效到网页端和API端
  • 性能无额外损耗,expectsJson()仅做请求头判断,开销可以忽略

内容的提问来源于stack exchange,提问作者The Stompiest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:06:07