نسخه:

Eloquent: منابع API

معرفی

هنگام ساخت یک API، ممکن است به یک لایه تبدیل نیاز داشته باشید که بین مدل‌های Eloquent شما و پاسخ‌های JSON که در واقع به کاربران برنامه شما برگردانده می‌شوند، قرار گیرد. برای مثال، ممکن است بخواهید ویژگی‌های خاصی را برای زیرمجموعه‌ای از کاربران نمایش دهید و نه دیگران، یا ممکن است بخواهید همیشه روابط خاصی را در نمایش JSON مدل‌های خود بگنجانید. کلاس‌های منابع Eloquent به شما این امکان را می‌دهد که مدل‌ها و مجموعه‌های مدل‌های خود را به صورت واضح و آسان به JSON تبدیل کنید.

البته، همیشه می‌توانید مدل‌ها یا مجموعه‌های Eloquent را با استفاده از toJson روش‌های آنها به JSON تبدیل کنید. با این حال، منابع Eloquent کنترل دقیق و قوی تری بر سریال سازی JSON مدل های شما و روابط آنها ارائه می دهند.

تولید منابع

برای تولید یک کلاس منبع، می توانید از make:resource دستور Artisan استفاده کنید. به طور پیش فرض، منابع در app/Http/Resources فهرست برنامه شما قرار می گیرند . منابع Illuminate\Http\Resources\Json\JsonResource کلاس را گسترش می دهند:

php artisan make:resource UserResource

مجموعه منابع

علاوه بر تولید منابعی که مدل‌های فردی را تغییر می‌دهند، ممکن است منابعی تولید کنید که مسئول تغییر مجموعه‌ای از مدل‌ها هستند. این به پاسخ‌های JSON شما اجازه می‌دهد پیوندها و سایر اطلاعات متا را که به کل مجموعه‌ای از یک منبع معین مربوط می‌شود، شامل شود.

برای ایجاد مجموعه منابع، --collection هنگام ایجاد منبع باید از پرچم استفاده کنید. یا گنجاندن کلمه Collection در نام منبع به لاراول نشان می دهد که باید یک منبع مجموعه ایجاد کند. منابع مجموعه Illuminate\Http\Resources\Json\ResourceCollection کلاس را گسترش می دهند:

php artisan make:resource User --collection
 
php artisan make:resource UserCollection

نمای کلی مفهوم

این یک نمای کلی در سطح بالا از منابع و مجموعه های منابع است. شما بسیار تشویق می شوید که بخش های دیگر این مستندات را بخوانید تا درک عمیق تری از سفارشی سازی و قدرت ارائه شده توسط منابع به شما داشته باشید.

قبل از بررسی تمام گزینه های موجود در هنگام نوشتن منابع، اجازه دهید ابتدا نگاهی سطح بالا به نحوه استفاده از منابع در لاراول بیندازیم. یک کلاس منبع نشان دهنده یک مدل واحد است که باید به یک ساختار JSON تبدیل شود. به عنوان مثال، در اینجا یک UserResource کلاس منبع ساده وجود دارد:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
 
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}

هر کلاس منبع متدی را تعریف می کند toArray که وقتی منبع به عنوان پاسخی از یک روش مسیر یا کنترلر برگردانده می شود، آرایه ای از ویژگی هایی را که باید به JSON تبدیل شوند، برمی گرداند.

توجه داشته باشید که ما می توانیم مستقیماً از $this متغیر به ویژگی های مدل دسترسی داشته باشیم. این به این دلیل است که یک کلاس منبع برای دسترسی راحت، به طور خودکار ویژگی و روش دسترسی به مدل اصلی را پروکسی می کند. هنگامی که منبع تعریف شد، ممکن است از یک مسیر یا کنترل کننده بازگردانده شود. این منبع نمونه مدل زیربنایی را از طریق سازنده خود می پذیرد:

use App\Http\Resources\UserResource;
use App\Models\User;
 
Route::get('/user/{id}', function (string $id) {
return new UserResource(User::findOrFail($id));
});

مجموعه منابع

اگر مجموعه ای از منابع یا یک پاسخ صفحه بندی شده را برمی گردانید، باید از collection روش ارائه شده توسط کلاس منبع خود هنگام ایجاد نمونه منبع در مسیر یا کنترلر خود استفاده کنید:

use App\Http\Resources\UserResource;
use App\Models\User;
 
Route::get('/users', function () {
return UserResource::collection(User::all());
});

توجه داشته باشید که این اجازه نمی‌دهد که متا داده‌های سفارشی که ممکن است نیاز به بازگردانی با مجموعه شما داشته باشد، اضافه شود. اگر می‌خواهید پاسخ مجموعه منابع را سفارشی کنید، می‌توانید یک منبع اختصاصی برای نمایش مجموعه ایجاد کنید:

php artisan make:resource UserCollection

هنگامی که کلاس مجموعه منابع تولید شد، می توانید به راحتی هر متا داده ای را که باید در پاسخ گنجانده شود تعریف کنید:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
 
class UserCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @return array<int|string, mixed>
*/
public function toArray(Request $request): array
{
return [
'data' => $this->collection,
'links' => [
'self' => 'link-value',
],
];
}
}

پس از تعریف مجموعه منابع شما، ممکن است از یک مسیر یا کنترلر برگردانده شود:

use App\Http\Resources\UserCollection;
use App\Models\User;
 
Route::get('/users', function () {
return new UserCollection(User::all());
});

حفظ کلیدهای مجموعه

هنگام برگرداندن مجموعه منابع از مسیر، لاراول کلیدهای مجموعه را به گونه ای تنظیم مجدد می کند که به ترتیب عددی باشند. با این حال، می توانید یک preserveKeys ویژگی به کلاس منبع خود اضافه کنید که نشان می دهد آیا کلیدهای اصلی مجموعه باید حفظ شوند یا خیر:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Resources\Json\JsonResource;
 
class UserResource extends JsonResource
{
/**
* Indicates if the resource's collection keys should be preserved.
*
* @var bool
*/
public $preserveKeys = true;
}

هنگامی که preserveKeys ویژگی روی تنظیم شود true ، کلیدهای مجموعه زمانی که مجموعه از یک مسیر یا کنترلر بازگردانده می شود، حفظ می شود:

use App\Http\Resources\UserResource;
use App\Models\User;
 
Route::get('/users', function () {
return UserResource::collection(User::all()->keyBy->id);
});

سفارشی کردن کلاس منبع زیربنایی

به طور معمول، $this->collection ویژگی یک مجموعه منبع به طور خودکار با نتیجه نگاشت هر آیتم از مجموعه به کلاس منبع منفرد آن پر می شود. کلاس منبع منفرد به عنوان نام کلاس مجموعه بدون Collection قسمت انتهایی نام کلاس فرض می شود. علاوه بر این، بسته به ترجیح شخصی شما، کلاس منبع مفرد ممکن است با پسوند باشد یا نباشد Resource .

به عنوان مثال، UserCollection تلاش خواهد کرد تا نمونه های کاربر داده شده را در UserResource منبع نگاشت کند. برای سفارشی کردن این رفتار، ممکن است $collects ویژگی مجموعه منابع خود را لغو کنید:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Resources\Json\ResourceCollection;
 
class UserCollection extends ResourceCollection
{
/**
* The resource that this resource collects.
*
* @var string
*/
public $collects = Member::class;
}

منابع نوشتاری

اگر نمای کلی مفهوم را نخوانده اید ، بسیار تشویق می شوید که قبل از ادامه این مستندات این کار را انجام دهید.

منابع فقط باید یک مدل داده شده را به یک آرایه تبدیل کنند. بنابراین، هر منبع حاوی toArray روشی است که ویژگی‌های مدل شما را به یک آرایه مناسب API ترجمه می‌کند که می‌تواند از مسیرها یا کنترل‌کننده‌های برنامه شما بازگردانده شود:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
 
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}

هنگامی که یک منبع تعریف شد، ممکن است مستقیماً از یک مسیر یا کنترل کننده بازگردانده شود:

use App\Http\Resources\UserResource;
use App\Models\User;
 
Route::get('/user/{id}', function (string $id) {
return new UserResource(User::findOrFail($id));
});

روابط

اگر می‌خواهید منابع مرتبط را در پاسخ خود بگنجانید، می‌توانید آنها را به آرایه‌ای که با toArray روش منبع خود برگردانده شده است اضافه کنید. در این مثال، از روش PostResource منبع collection برای اضافه کردن پست‌های وبلاگ کاربر به پاسخ منبع استفاده می‌کنیم :

use App\Http\Resources\PostResource;
use Illuminate\Http\Request;
 
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'posts' => PostResource::collection($this->posts),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}

اگر می‌خواهید روابط را فقط زمانی وارد کنید که قبلاً بارگذاری شده‌اند، اسناد مربوط به روابط شرطی را بررسی کنید .

مجموعه منابع

در حالی که منابع یک مدل واحد را به یک آرایه تبدیل می کنند، مجموعه های منابع مجموعه ای از مدل ها را به یک آرایه تبدیل می کنند. با این حال، نیازی به تعریف یک کلاس مجموعه منابع برای هر یک از مدل های خود نیست، زیرا همه منابع روشی را collection برای تولید یک مجموعه منابع "ad-hoc" در جریان ارائه می دهند:

use App\Http\Resources\UserResource;
use App\Models\User;
 
Route::get('/users', function () {
return UserResource::collection(User::all());
});

با این حال، اگر نیاز به سفارشی سازی متا داده های بازگشتی با مجموعه دارید، لازم است مجموعه منابع خود را تعریف کنید:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
 
class UserCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'data' => $this->collection,
'links' => [
'self' => 'link-value',
],
];
}
}

مانند منابع منفرد، مجموعه‌های منابع ممکن است مستقیماً از مسیرها یا کنترل‌کننده‌ها برگردانده شوند:

use App\Http\Resources\UserCollection;
use App\Models\User;
 
Route::get('/users', function () {
return new UserCollection(User::all());
});

بسته بندی داده ها

data به طور پیش فرض، زمانی که پاسخ منبع به JSON تبدیل می شود، بیرونی ترین منبع شما در یک کلید پیچیده می شود . بنابراین، برای مثال، یک پاسخ مجموعه منابع معمولی مانند زیر است:

{
"data": [
{
"id": 1,
"name": "Eladio Schroeder Sr.",
"email": "therese28@example.com"
},
{
"id": 2,
"name": "Liliana Mayert",
"email": "evandervort@example.com"
}
]
}

اگر می‌خواهید بسته‌بندی بیرونی‌ترین منبع را غیرفعال کنید، باید withoutWrapping متد را در کلاس پایه فراخوانی کنید Illuminate\Http\Resources\Json\JsonResource . به طور معمول، شما باید این روش را از ارائه دهنده خدمات AppServiceProvider خود یا ارائه دهنده دیگری که در هر درخواست برای برنامه شما بارگذاری می شود، فراخوانی کنید:

<?php
 
namespace App\Providers;
 
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
// ...
}
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
JsonResource::withoutWrapping();
}
}

این روش تنها بر بیرونی ترین پاسخ تأثیر می گذارد و کلیدهایی را که به صورت دستی به مجموعه منابع خود اضافه می کنید withoutWrapping حذف نمی کند . data

بسته بندی منابع تو در تو

شما آزادی کامل دارید تا تعیین کنید که چگونه روابط منابع شما پیچیده می شود. اگر می‌خواهید همه مجموعه‌های منابع data ، بدون توجه به تودرتو، در یک کلید پیچیده شوند ، باید برای هر منبع یک کلاس مجموعه منابع تعریف کنید و مجموعه را در یک data کلید برگردانید.

ممکن است از خود بپرسید که آیا این باعث می شود که خارجی ترین منبع شما در دو کلید پیچیده شود data . نگران نباشید، لاراول هرگز اجازه نخواهد داد منابع شما به طور تصادفی دوبار بسته شوند، بنابراین لازم نیست نگران سطح تودرتو مجموعه منابعی باشید که در حال تغییر آن هستید:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Resources\Json\ResourceCollection;
 
class CommentsCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return ['data' => $this->collection];
}
}

بسته بندی و صفحه بندی داده ها

هنگام برگرداندن مجموعه های صفحه بندی شده از طریق یک پاسخ منبع، لاراول داده های منبع شما را در یک کلید قرار می دهد data حتی اگر withoutWrapping متد فراخوانی شده باشد. این به این دلیل است که پاسخ های صفحه بندی شده همیشه حاوی meta و links کلیدهایی با اطلاعات مربوط به وضعیت صفحه بندی کننده هستند:

{
"data": [
{
"id": 1,
"name": "Eladio Schroeder Sr.",
"email": "therese28@example.com"
},
{
"id": 2,
"name": "Liliana Mayert",
"email": "evandervort@example.com"
}
],
"links":{
"first": "http://example.com/users?page=1",
"last": "http://example.com/users?page=1",
"prev": null,
"next": null
},
"meta":{
"current_page": 1,
"from": 1,
"last_page": 1,
"path": "http://example.com/users",
"per_page": 15,
"to": 10,
"total": 10
}
}

صفحه بندی

شما می توانید یک نمونه صفحه بندی لاراول را به collection روش یک منبع یا به مجموعه منابع سفارشی ارسال کنید:

use App\Http\Resources\UserCollection;
use App\Models\User;
 
Route::get('/users', function () {
return new UserCollection(User::paginate());
});

پاسخ های صفحه بندی شده همیشه حاوی meta و links کلیدهایی با اطلاعاتی در مورد وضعیت صفحه بندی کننده هستند:

{
"data": [
{
"id": 1,
"name": "Eladio Schroeder Sr.",
"email": "therese28@example.com"
},
{
"id": 2,
"name": "Liliana Mayert",
"email": "evandervort@example.com"
}
],
"links":{
"first": "http://example.com/users?page=1",
"last": "http://example.com/users?page=1",
"prev": null,
"next": null
},
"meta":{
"current_page": 1,
"from": 1,
"last_page": 1,
"path": "http://example.com/users",
"per_page": 15,
"to": 10,
"total": 10
}
}

سفارشی کردن اطلاعات صفحه بندی

اگر می‌خواهید اطلاعات موجود در links یا meta کلیدهای پاسخ صفحه‌بندی را سفارشی کنید، می‌توانید paginationInformation روشی را روی منبع تعریف کنید. این متد $paginated داده ها و آرایه اطلاعات را دریافت می کند $default که آرایه ای حاوی کلیدهای links و است meta :

/**
* Customize the pagination information for the resource.
*
* @param \Illuminate\Http\Request $request
* @param array $paginated
* @param array $default
* @return array
*/
public function paginationInformation($request, $paginated, $default)
{
$default['links']['custom'] = 'https://example.com';
 
return $default;
}

صفات مشروط

گاهی اوقات ممکن است بخواهید فقط در صورتی که یک شرط مشخص شده باشد، یک ویژگی را در پاسخ منبع بگنجانید. به عنوان مثال، ممکن است بخواهید فقط در صورتی یک مقدار را وارد کنید که کاربر فعلی یک "مدیر" باشد. لاراول انواع مختلفی از روش های کمکی را برای کمک به شما در این شرایط ارائه می دهد. این when روش ممکن است برای اضافه کردن یک ویژگی به صورت مشروط به یک پاسخ منبع استفاده شود:

/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'secret' => $this->when($request->user()->isAdmin(), 'secret-value'),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}

در این مثال، secret کلید تنها در صورتی در پاسخ منبع نهایی بازگردانده می‌شود که روش کاربر احراز هویت شده isAdmin برگردد true . اگر روش برگردد false ، secret کلید قبل از ارسال به مشتری از پاسخ منبع حذف خواهد شد. این when روش به شما این امکان را می دهد که منابع خود را بدون توسل به عبارات شرطی در هنگام ساختن آرایه به وضوح تعریف کنید.

این when روش همچنین یک closure را به عنوان آرگومان دوم خود می پذیرد و به شما امکان می دهد مقدار حاصل را تنها در صورتی محاسبه کنید که شرط داده شده باشد true :

'secret' => $this->when($request->user()->isAdmin(), function () {
return 'secret-value';
}),

این whenHas روش ممکن است برای گنجاندن یک ویژگی استفاده شود اگر واقعاً در مدل اصلی وجود داشته باشد:

'name' => $this->whenHas('name'),

بعلاوه، whenNotNull اگر مشخصه تهی نباشد، ممکن است از این روش برای گنجاندن یک ویژگی در پاسخ منبع استفاده شود:

'name' => $this->whenNotNull($this->name),

ادغام ویژگی های شرطی

گاهی اوقات ممکن است چندین ویژگی داشته باشید که فقط باید بر اساس شرایط یکسان در پاسخ منبع گنجانده شوند. در این مورد، می‌توانید از mergeWhen روشی برای گنجاندن ویژگی‌ها در پاسخ استفاده کنید، تنها زمانی که شرط داده شده true :

/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
$this->mergeWhen($request->user()->isAdmin(), [
'first-secret' => 'value',
'second-secret' => 'value',
]),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}

دوباره، اگر شرط داده شده باشد false ، این ویژگی ها قبل از ارسال به مشتری از پاسخ منبع حذف خواهند شد.

این mergeWhen روش نباید در آرایه هایی که رشته ها و کلیدهای عددی را ترکیب می کنند استفاده شود. علاوه بر این، نباید در آرایه هایی با کلیدهای عددی که به ترتیب ترتیب داده نشده اند استفاده شود.

روابط مشروط

علاوه بر بارگذاری مشروط ویژگی‌ها، می‌توانید به‌صورت مشروط روابطی را در پاسخ‌های منابع خود بر اساس اینکه آیا رابطه قبلاً در مدل بارگذاری شده است، اضافه کنید. این به کنترلر شما اجازه می دهد تصمیم بگیرد که کدام روابط باید در مدل بارگذاری شوند و منبع شما به راحتی می تواند آنها را فقط زمانی که واقعاً بارگذاری شده اند شامل شود. در نهایت، این امر جلوگیری از مشکلات پرس و جو "N+1" در منابع شما را آسان تر می کند.

این whenLoaded روش ممکن است برای بارگذاری مشروط یک رابطه استفاده شود. برای جلوگیری از بارگذاری بی مورد روابط، این روش نام رابطه را به جای خود رابطه می پذیرد:

use App\Http\Resources\PostResource;
 
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'posts' => PostResource::collection($this->whenLoaded('posts')),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}

در این مثال، اگر رابطه بارگذاری نشده باشد، posts کلید قبل از ارسال به مشتری از پاسخ منبع حذف می شود.

رابطه مشروط به حساب می آید

علاوه بر مشروط کردن روابط، می‌توانید به صورت مشروط «شمارش» روابط را در پاسخ‌های منابع خود بر اساس اینکه تعداد رابطه در مدل بارگذاری شده است، اضافه کنید:

new UserResource($user->loadCount('posts'));

این whenCounted روش ممکن است برای گنجاندن مشروط تعداد رابطه در پاسخ منبع شما استفاده شود. اگر تعداد روابط وجود نداشته باشد، این روش از درج غیر ضروری ویژگی جلوگیری می کند:

/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'posts_count' => $this->whenCounted('posts'),
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}

در این مثال، اگر posts تعداد رابطه بارگیری نشده باشد، posts_count کلید قبل از ارسال به مشتری از پاسخ منبع حذف می شود.

انواع دیگر مصالح، مانند avg , sum , min و max همچنین ممکن است به صورت مشروط با استفاده از whenAggregated روش بارگیری شوند:

'words_avg' => $this->whenAggregated('posts', 'words', 'avg'),
'words_sum' => $this->whenAggregated('posts', 'words', 'sum'),
'words_min' => $this->whenAggregated('posts', 'words', 'min'),
'words_max' => $this->whenAggregated('posts', 'words', 'max'),

اطلاعات محوری شرطی

علاوه بر گنجاندن مشروط اطلاعات رابطه در پاسخ های منابع خود، می توانید به صورت مشروط داده هایی را از جداول میانی روابط چند به چند با استفاده از این whenPivotLoaded روش درج کنید. این whenPivotLoaded متد نام جدول محوری را به عنوان اولین آرگومان خود می پذیرد. آرگومان دوم باید یک بسته باشد که اگر اطلاعات محوری در مدل موجود باشد، مقداری را که باید برگردانده شود، برمی گرداند:

/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'expires_at' => $this->whenPivotLoaded('role_user', function () {
return $this->pivot->expires_at;
}),
];
}

اگر رابطه شما از یک مدل جدول میانی سفارشی استفاده می کند ، می توانید نمونه ای از مدل جدول میانی را به عنوان اولین آرگومان به whenPivotLoaded متد ارسال کنید:

'expires_at' => $this->whenPivotLoaded(new Membership, function () {
return $this->pivot->expires_at;
}),

اگر جدول میانی شما از ابزاری غیر از اکسسوری استفاده می کند pivot ، می توانید از whenPivotLoadedAs روش زیر استفاده کنید:

/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'expires_at' => $this->whenPivotLoadedAs('subscription', 'role_user', function () {
return $this->subscription->expires_at;
}),
];
}

افزودن متا دیتا

برخی از استانداردهای JSON API نیاز به افزودن متا داده به پاسخ های منابع و مجموعه منابع شما دارند. این اغلب شامل مواردی مانند links منبع یا منابع مرتبط یا متا داده در مورد خود منبع است. اگر نیاز به بازگرداندن متا داده های اضافی در مورد یک منبع دارید، آن را در toArray روش خود قرار دهید. به عنوان مثال، ممکن است link هنگام تبدیل یک مجموعه منابع، اطلاعاتی را اضافه کنید:

/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'data' => $this->collection,
'links' => [
'self' => 'link-value',
],
];
}

هنگام بازگرداندن متا داده های اضافی از منابع خود، هرگز نباید نگران نادیده گرفتن تصادفی کلیدها links یا meta کلیدهایی باشید که به طور خودکار توسط لاراول هنگام بازگرداندن پاسخ های صفحه بندی شده اضافه می شوند. هر اضافی links که تعریف می کنید با پیوندهای ارائه شده توسط صفحه نویس ادغام می شود.

داده های متا سطح بالا

گاهی اوقات ممکن است بخواهید فقط داده های متا خاصی را با یک پاسخ منبع وارد کنید در صورتی که منبع بیرونی ترین منبعی باشد که برگردانده می شود. به طور معمول، این شامل اطلاعات متا در مورد پاسخ به عنوان یک کل است. برای تعریف این متا داده، یک with متد به کلاس منبع خود اضافه کنید. این روش باید آرایه‌ای از متا داده‌ها را برگرداند تا تنها زمانی که منبع خارجی‌ترین منبع در حال تغییر است، با پاسخ منبع اضافه شود:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\Resources\Json\ResourceCollection;
 
class UserCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return parent::toArray($request);
}
 
/**
* Get additional data that should be returned with the resource array.
*
* @return array<string, mixed>
*/
public function with(Request $request): array
{
return [
'meta' => [
'key' => 'value',
],
];
}
}

افزودن متا داده هنگام ساخت منابع

همچنین می‌توانید هنگام ساختن نمونه‌های منبع در مسیر یا کنترلر خود، داده‌های سطح بالا را اضافه کنید. روشی additional که در همه منابع موجود است، آرایه ای از داده ها را می پذیرد که باید به پاسخ منبع اضافه شود:

return (new UserCollection(User::all()->load('roles')))
->additional(['meta' => [
'key' => 'value',
]]);

پاسخ های منابع

همانطور که قبلاً خواندید، ممکن است منابع مستقیماً از مسیرها و کنترلرها بازگردانده شوند:

use App\Http\Resources\UserResource;
use App\Models\User;
 
Route::get('/user/{id}', function (string $id) {
return new UserResource(User::findOrFail($id));
});

با این حال، گاهی اوقات ممکن است لازم باشد پاسخ HTTP خروجی را قبل از ارسال به مشتری سفارشی کنید. دو راه برای انجام این کار وجود دارد. ابتدا، می توانید response روش را به منبع زنجیره بزنید. این روش یک نمونه را برمی گرداند Illuminate\Http\JsonResponse و به شما کنترل کامل روی سرصفحه های پاسخ را می دهد:

use App\Http\Resources\UserResource;
use App\Models\User;
 
Route::get('/user', function () {
return (new UserResource(User::find(1)))
->response()
->header('X-Value', 'True');
});

از طرف دیگر، می توانید یک withResponse روش را در خود منبع تعریف کنید. این متد زمانی فراخوانی می شود که منبع به عنوان بیرونی ترین منبع در یک پاسخ بازگردانده شود:

<?php
 
namespace App\Http\Resources;
 
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
 
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
];
}
 
/**
* Customize the outgoing response for the resource.
*/
public function withResponse(Request $request, JsonResponse $response): void
{
$response->header('X-Value', 'True');
}
}