hello Controller -> Service -> Repository -> Model yapısı için ben şu şekilde bir yol izlemiştim umarım bu konuda yardımcı olabilir. "city" tablosu oluşturmuştum kodları kısaca şu şekilde paylaşayım;
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class City extends Model
{
protected $table = "cities";
protected $primaryKey = "id";
public $timestamps = false;
protected $fillable = [
'country_id',
'name',
];
protected $guarded = [
'id',
'created_at',
'updated_at'
];
public function country() {
return $this->belongsTo(Country::class,'country_id','id');
}
}
Temel olarak bir model sınıfım sadece kolon ve foreign key yapılarını içeriyor. CRUD işlemlerini bu yapıda modele dahil etmiyorum.
namespace App\Repositories;
use App\Models\City;
use App\Abstracts\BaseRepositoryAbstract;
class CityRepository extends BaseRepositoryAbstract
{
public function __construct()
{
$this->model_class = new City();
}
public function selectAllGroupedCountry()
{
return $this->model_class->orderBy('country_id')->orderBy('name')->get()->groupBy('country.name');
}
}
Kullandığım repository sınıflarım genel olarak tüm CRUD işlemleri aynı olduğu için bir abstract yazmayı tercih ettim. Ek olarak o tabloda farklı dönüşler almak istiyorsam sınıfa dahil ettim.
`
namespace App\Abstracts;
use App\Interfaces\BaseRepositoryInterface;
abstract class BaseRepositoryAbstract implements BaseRepositoryInterface
{
protected $model_class;
public function selectAll()
{
return $this->model_class->all();
}
public function selectByID(int $id)
{
return $this->model_class->find($id);
}
public function insert(array $fillable_array)
{
$row = $this->model_class->create($fillable_array);
return $row->fresh();
}
public function update(int $id, array $fillable_array)
{
$row = $this->selectByID($id);
$row->update($fillable_array);
return $row->fresh();
}
public function delete(int $id)
{
$row = $this->SelectByID($id);
return $row->delete();
}
}
`
Ah tabi reposity üretirken bir de construct fonksiyonu kullanmak zorunda olduğum için interface dahil ettim. Olur da başka bir kişi repository oluşturmak ister ise bu yapı onu uyarsın diye.
namespace App\Interfaces;
interface BaseRepositoryInterface
{
public function __construct();
public function selectAll();
public function selectByID(int $id);
public function insert(array $fillable_array);
public function update(int $id, array $fillable_array);
public function delete(int $id);
}
Service noktasına gelince de yapı şu hali almaya başladı;
namespace App\Services;
use App\Repositories\CityRepository;
use Illuminate\Support\Collection;
class CityService
{
private $cityRepository;
public function __construct()
{
$this->cityRepository = new CityRepository();
}
public function GetAllCities() : Collection
{
return $this->cityRepository->selectAll();
}
public function GetAllCitiesGroupedCountry() : Collection
{
return $this->cityRepository->selectAllGroupedCountry();
}
}
Güzel yanı şu oldu artık ORM yapısındaki fonksiyonlar için "hacı bak bu yok!" diyip altını çizen PHPStorm'dan kurtulmuş oldum. repository üzerinde bu işlemler dönüyordu çünkü. Service yapısını ben repositoryleri bir araya toplayan facede gibi kurguladım. Mesela varsayalım ki bir tabloya veri ekleyince birden fazla tablo ile iletişime geçsin servicede repoları çağırıp işlemi yapıp geriye boolean değerler döndürüyorum. Controller da bu cevabı kontrol edip işlemi biritiryorum.
Şöyle bir durum da söz konusu olabiliyor controller da birden fazla service yapısını direkt içine alıyordu. Yani ufak da olsa inşa etmek istediğim yapı bu şekilde. Fazla veri yükü altında neler yapar bilmiyorum daha tecrübe edemesem de belki yardımcı olabilir 😃