Laravel Form Request
Laravel projelerimizde gelen isteklerde hem kod okunabilirliğini arttırmak ve daha karmaşık doğrulama işlemlerini yapabilmek için kullandığımız FormRequest sınıfından bahsedeceğiz.
Bir kitap projesi üzerinden anlatacağım. Öncelikli olarak rotaları oluşturalım.
- Şöyle Görünüyor olmalı;
# route / api.phpRoute::group(['prefix' => 'book'], static function () {
Route::post('create', 'BookController@create');
Route::get('list', 'BookController@list');
Route::delete('delete', 'BookController@delete');
Route::put('update', 'BookController@update');
});
Şimdi Artisan CLI üzerinden bir Controller oluşturuyoruz.
php artisan make:controller BookController
ardından metotlarımızı oluşturuyoruz. Şöyle görünüyor olmalı;
# app/Http/Controller/BookController
class BookController extends Controller
{
public function create()
{
}
public function list()
{
}
public function update()
{
}
public function delete()
{
}
}
öncelikle normal bir doğrula işlemi yapalım ve sonrasında kodlarımızı karşılaştıralım. Bir kitap oluşturduğumuzu varsayalım kitaba ait bilgiler şöyle olsun.
- Kitabın Adı
- Açıklaması
- Yazarı
- Yayınevi
- Fiyatı
- Sayfa Sayısı
- Basım Yılı
- ISBN Numarası
- Resim Link’i
- Dil
Şimdi bu bilgiler doğrultusunda bir doğrulama ve kayıt işlemi similasyonu gerçekleştirelim. Artık şöyle görüyor;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;class BookController extends Controller
{
public function create(Request $request)
{
$validator = Validator::make($request->all(),[
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255',
'description' => 'required|string|max:500',
'writer' => 'required|string|max:100',
'publisher' => 'required|string|max:100',
'price' => 'required|regex:/^\d+(\.\d{1,2})?$/',
'page_number' => 'required|numeric|min:1',
'edition_year' => 'required|numeric',
'isbn' => 'required|numeric|unique:blog,isbn',
'image' => 'required|string|max:255',
'lang' => 'required|string',
]);
if ($validator->fails()) {
return response()->json($validator->errors());
}else{
/**
* Diğer işlemler veritabanı kaydı vb.
*/
return response()->json('Book created.',200);
}
}
...
Görüldüğü gibi kontroller oldukça kalabalık ve daha fazla işlem gerektirdiğinde veya kendi doğrulama metotlarımızı eklediğimizde iyice karmaşık bir hale gelicek ve iyice okunabilirliğini kaybetmiş olacak öncelikli olarak kodu kısa parçalara ayır ve tek yerden yönet şeklinde ilerlememiz gerekiyor. O yüzden şimdi asıl kısıma gelelim. Artisan CLI ile bir sınıf oluşturalım.
php artisan make:request BookCreateRequest
bunu çalıştırdıktan sonra app/Http/Request klasörü ve bunun altında BookCreateRequest dosyasının oluştuğunu göreceksiniz. Bu dosya şöyle görünüyor olmalı;
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class BookCreateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
öncelikli olarak burda bulunan authorize metodundan bahsedelim. Bu kısım bizim bu isteği yapan tarafın doğrulama imkanı sağlıyor. Buradan değer olarak “false” dönerseniz istemciye doğrudan
403 | This action is unauthorized.
dönüşü iletilecektir. Eğer bunu yukarıdaki örnekte yapmak isteseydik doğrulama işlemini bir doğrulama içerisine yazacaktır örn.
use Illuminate\Support\Facades\Auth;class BookController extends Controller
{
public function create(Request $request)
{
if (Auth::check() && Auth::user()->isAdmin()) {
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255',
'description' => 'required|string|max:500',
....
vb. gibi işlemler uyguluyor olacaktır. Auth ve benzeri yapılardan başka yazılarda bahsedeceğim şuan ki kısım burası değil gördüğünüz gibi giderek karmaşıklaşıyor. En iyisi biz bunu oluşturduğumuz yeni dosya üzerinde çözelim. BookCreateRequest sınıfında şunları uygulayalım.
Öncelikli olarak doğrulama kısmını halledelim. Dosyamız artık şöyle görünüyor.
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class BookCreateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() :bool
{
// Doğrulama işlemi
return (Auth::check() && Auth::user()->isAdmin());
}
....
şimdi ise diğer doğrulama işlemini yapalım.
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255',
'description' => 'required|string|max:500',
'writer' => 'required|string|max:100',
'publisher' => 'required|string|max:100',
'price' => 'required|regex:/^\d+(\.\d{1,2})?$/',
'page_number' => 'required|numeric|min:1',
'edition_year' => 'required|numeric',
'isbn' => 'required|numeric|unique:blog,isbn',
'image' => 'required|string|max:255',
'lang' => 'required|string',
];
}
son eklemelerden sonra dosyamızın tamamı şöyle görünüyor olmalı
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class BookCreateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize() :bool
{
return (Auth::check() && Auth::user()->isAdmin());
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255',
'description' => 'required|string|max:500',
'writer' => 'required|string|max:100',
'publisher' => 'required|string|max:100',
'price' => 'required|regex:/^\d+(\.\d{1,2})?$/',
'page_number' => 'required|numeric|min:1',
'edition_year' => 'required|numeric',
'isbn' => 'required|numeric|unique:blog,isbn',
'image' => 'required|string|max:255',
'lang' => 'required|string',
];
}
}
böylelikle doğrulama için kullandığımz herşeyi ayırmış ve yönetmiş olduk şimdi ise bunu Controller içerisinde kullanalım ve aradaki farkı inceleyelim.
<?php
namespace App\Http\Controllers;
use App\Http\Requests\BookCreateRequest;
class BookController extends Controller
{
public function create(BookCreateRequest $request)
{
// Veritabanı kayıt vb.
}
burada create motuda bir Türkçesi bağımlılık enjeksiyonu yada bilinen adıyla “Dependency Injection” uyguluyoruz ve BookCreateRequest tipinde bir $request alacağını belirtiyoruz. Böylelikle doğrudan oluşturduğumuz Request çalışıyor ve orada ki doğrulama işlemi gerçekleştiriliyor eğer orada bir sorun olursa istemci tarafına doğrudan dönüş yapıyor ve hiç Controller tarafına devam etmiyor(* Bu kısımdaki dönüş tipleri ve mesaj yönetimini başka makalede anlatacağım ) ve sonuç olarak Controller temiz kalıyor ve okunabilirliğini arttıyor. Öncesi sonrası olarak bir inceleme yapalım.
Öncesi
<?php
namespace App\Http\Controllers;use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class BookController extends Controller
{
public function create(Request $request)
{
if (Auth::check() && Auth::user()->isAdmin()) {
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255',
'description' => 'required|string|max:500',
'writer' => 'required|string|max:100',
'publisher' => 'required|string|max:100',
'price' => 'required|regex:/^\d+(\.\d{1,2})?$/',
'page_number' => 'required|numeric|min:1',
'edition_year' => 'required|numeric',
'isbn' => 'required|numeric|unique:blog,isbn',
'image' => 'required|string|max:255',
'lang' => 'required|string',
]);
if ($validator->fails()) {
return response()->json($validator->errors());
} else {
/**
* Diğer işlemler veritabanı kaydı vb.
*/
return response()->json('Book created.', 200);
}
}
}
....
ve Sonrası
<? php
namespace App\Http\Controllers;
use App\Http\Requests\BookCreateRequest;
class BookController extends Controller
{
public function create (BookCreateRequest $ request)
{
//veritabanı kayıt vb.
}
....
aradaki fark çok net olarak görülebiliyor. Bir sonraki makalelerde
- Geri dönüş mesajları
- Özel mesaj oluşturma
- Özel kontrol yapıları
- Yetkilendirme vb. işlemleri anlatacağım. Teşekkür ederim.
Tolga Karabulut
tolga.karabulut@medianova.com
Medianova CDN — Senior PHP Developer
Örnek Proje kodları