DTO چیست و چگونه در لاراول از آن استفاده کنیم؟
DTO مخفف "Data Transfer Object" یه دیزاین پترن هست که برای جابهجایی اطلاعات بین لایههای مختلف برنامه استفاده میشه، نحوه کار DTOها در واقع به اینصورت که اطلاعات توی یه "Object" نگهداری میشن و اون Object هست که بین قسمتهای مختلف برنامه پاس داده میشه!
در برنامههای لاراولی معمولا DTOها برای پاس دادن اطلاعات بین Repository و Service یا Service و Controller و امثالهم استفاده میشه. این مهم به ما کمک میکنه که بتونیم لاجیک برنامه رو حفظ کنیم و برنامه رو قابل توسعه نگه داریم.
استفاده از DTO در لاراول
برای استفاده از DTO توی برنامه لاراولی، نیازه که یه کلاس برای هر DTO که مورد استفاده قرار میدیم ایجاد کنیم، برای مثال فرض کنید که یه مدل Product
داریم که property های name
، count
، price
رو شامل میشه.
در مسیر project_folder\app\DTO
یه فایل به نام ProductDTO
مشابه مثال زیر ایجاد میکنیم:
namespace App\DTO;
class ProductDTO
{
public string $name;
public int $count;
public int $price;
public function __construct(string $name, int $count, int $price)
{
$this->name = $name;
$this->count = $count;
$this->price = $price;
}
}
DTO ما آمادست و میتونیم ازش استفاده کنیم، برای مثال برای ساخت یک محصول جدید کنترلرمون رو به این صورت ویرایش میکنیم:
namespace App\Http\Controllers;
use App\DTO\ProductDTO;
use App\Services\ProductService;
use Illuminate\Http\Request;
class ProductController extends Controller
{
private ProductService $productService;
public function __construct(ProductService $productService)
{
$this->productService = $productService;
}
public function createProduct(Request $request)
{
$productDTO = new ProductDTO(
$request->name,
$request->count,
$request->price
);
$product = $this->productService->createProduct($productDTO);
return response()->json($product);
}
}
توی مثال بالا متد CreateProduct
یک object به نام $request
از سمت کلاینت دریافت میکنه و بر اساس اطلاعات اون یک Object به نام productDTO
میسازه و به متد CreateProduct
در ProductService
پاسش میده. ProdcutService
الان میتونه بر اساس DTO که دریافت کرده یه محصول جدید رو توی دیتابیس ایجاد کنه.
فایده استفاده از این روش این هست که شما در صورتی که مثلا اگر به مدل Product
یه property جدید اضافه کردید تنها کاری که لازمه انجام بدید اینه که به productDTO
این property رو اضافه کنید و تمام...، نیاز نیست همه جارو ویرایش کنید و خودکار به همه قسمت ها اضافه میشه. در نتیجه برنامه ماژولار و توسعه پذیری دارید.
اگر بخوایم توی این آموزش پترن ریپوزیتوری (repository pattern) رو نادیده بگیریم و از داخل سرویس مستقیم مدل رو فراخوانی کنیم و یک محصول جدید بسازیم، به این صورت میتونیم عمل کنیم:
namespace App\Services;
use App\DTO\ProductDTO;
use App\Models\Product;
class ProductService
{
public function createProduct(ProductDTO $productDTO): Product
{
$product = new Product();
$product->name = $productDTO->name;
$product->count = $productDTO->count;
$product->price = $productDTO->price;
$product->save();
// OR
$product = Product::create($productDTO);
return $product;
}
}
در کد بالا $productDTO
رو که به متد createProduct
پاس داده بودیم رو دریافت کردیم و داخل متد، DTO رو به مدل Product
اساین کردیم. به همین سادگی
دلیل اینکه توی این پست از Repository Design Pattern استفاده نکردیم ساده تر کردن مفهوم آموزش بود وگرنه شما میتونید همونطور که DTO رو به سرویس پاس دادید به ریپوزیتوری هم پاسش بدید و اونجا فرایند ذخیره سازی رو انجام بدید.
البته میتونید برای اعمال مختلف DTO های جداگانهای ایجاد کنید برای مثال به صورت زیر DTO ها رو خرد کنید:
- Create product =
DTO/Product/CreateProductDTO
- Update product =
DTO/Product/EditProductDTO
- Get product =
DTO/Product/ViewProductDTO
- و...
پایان/