The Best Fluffy Pancakes recipe you will fall in love with. Full of tips and tricks to help you make the best pancakes.

laravel 中介層小筆記

在開發後台api的時候使用了swagger建立api文件給前端人員查看測試,但自己同時也還在開發,自己的修正如果一直跟前端開發人員起衝突會造成困擾。

所以在另外開了一個新的資料庫並建立了一個中介class,讓請求如果遇到有test前綴的url就自動轉換到另一個資料庫,這樣就可以保持程式邏輯一致,資料卻不會衝突。

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\DB;

class UseApiTestDatabase
{
  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure  $next
   * @return mixed
   */
  public function handle($request, Closure $next)
  {
    // 檢查請求是否為 api/test 開頭
    if ($request->is('api/test/*')) {
      // 設定測試資料庫的連接資訊
      config([
        'database.connections.mysql.host' => env('API_TEST_DB_HOST'),
        'database.connections.mysql.database' => env('API_TEST_DB_DATABASE'),
        'database.connections.mysql.username' => env('API_TEST_DB_USERNAME'),
        'database.connections.mysql.password' => env('API_TEST_DB_PASSWORD'),
      ]);

      // 重新連接到測試資料庫
      DB::purge('mysql');
      DB::reconnect('mysql');
    }

    return $next($request);
  }
}

但今天前端人員發現他新增、或用不帶參數的get方法(index)可以正確取得資料,但是針對取得的資料要去修或刪時卻會出現 resource not found的問題。

排查後發現當url帶有路徑參數的時候就會沒有正確進入上述的中介來轉導資料庫,在到達這個中介之前,laravel已經查詢好路由參數對應的資料庫紀錄了,感覺到可能是生命週期相關的問題

後來發現是kernel設定的順序造成的,因為他原本設定在SubstituteBindings之後,所以先檢查了資源,才去切換資料庫而導致此狀況,而store跟index 方法正常是因為他們沒有帶路徑參數進來,相關動作是到了控制器裡面才執行,在那之前切換資料庫的中介層就有被正確執行。


    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            'throttle:api',
            \App\Http\Middleware\UseApiTestDatabase::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *