昨天提到了一些部分,今天就來說到關於資料庫與預設設定的注意事項。
Validation
Validation
是開發 Web 應用中很重要的一個環節,除了可以確定資料的行別的正確性之外,還有驗證內容的格式是否有效,以及可以過濾一些已知的安全性問題。Laravel 本身自帶的 Validation
已經夠強大,在各種情境中都可以應付,甚至是可以使用自訂的規則去加強檢查的涵蓋範圍。
除了官方文件有列出來的部分,下面是我平時使用會用到的作法:
就以官方的範例 User model 的驗證來說,rules
規則我建議都要使用 array<string>
public function rules(): array
{
return [
'email' => ['required', 'email', 'unique:users'],
'name' => ['required', 'string', 'max:50'],
'password' => 'required'
];
}
除了在使用上可以利用 editor
的 syntax highlight
幫助閱讀之外,更好去使用有特殊字元的規則。
以及不
要直接取用 request 物件中的 payload,要使用經過 validation 處理過的。
// Good
// $data = ['email' => 'xx', 'name' => 'xx', 'password' => 'xx']
$data = $request->validated();
// Not good
$data = $request->all();
// Not good
$email = $request->get('email');
$name = $request->get('name');
Mass Assignment
// User.php
protected static $unguarded = true;
// Or
// AppServiceProvider.php
Model::unguard();
依照前一個方法從 validation 中取出驗證過的資料,不僅可以讓可讀性更好,還可以更好掌握流程控制。
$data = $request->validated();
// ...
User::query()->create($data);
migration
的 down
因為主要問題有兩點:
就跟資料庫的備份
一樣,如果沒測試的話,要使用時你有信心
直接執行嗎?甚至是有確認這仍然是可以正常運作的嗎?
rollback
嗎?在資料庫中的紀錄是有狀態的,無法像是 codebase
一樣輕易的 rollback
並且不損失資料。很多的情況下對於資料庫的處理應該是不斷的推進,使用新的 migration 去處理變更,而不是直接 rollback
。
所以可以看到預設的 migration 並無針對 down
function 內有其他的定義:
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users');
}
};
middleware
要移除因為在多數的情況下,laravel 的專案都會以純 API Service 的形式去開發,所以記得要檢查把不需要的全端專案設定,去逐一檢查並且移除。
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
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,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
以官方的預設版本為例,你應該就可以把 web
下所有的 middleware 都移除。