سلام وقت بخیر
من از طریق API Resources یک سری داده ها رو برای کلاینت ارسال میکنم. میخوام بدونم چطوری میتونم این داده ها رو customize کنم؟
این اطلاعات داخل resource من هستش:
class Blog extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'created_at' => $this->created_at->format('m/d/Y'),
'updated_at' => $this->updated_at->format('m/d/Y'),
];
}
}
این هم کنترلر من برای نمایش همه پست ها و نمایش تکی هر پست:
public function index()
{
$blogs = Blog::all();
return $this->sendResponse(BlogResource::collection($blogs), 'Posts fetched.');
}
public function show($id)
{
$blog = Blog::find($id);
if (is_null($blog)) {
return $this->sendError('Post does not exist.');
}
return $this->sendResponse(new BlogResource($blog), 'Post fetched.');
}
حالا من میخوام وقتی داخل هر پست میشم اطلاعات اضافی هم نمایش داده بشه (مثلا نام نویسنده، امتیاز پست و...) ولی تو متد index که همه پست ها فراخوانی میشه این موارد نباشه.
چطوری میتونم این کار رو انجام بدم؟
با تشکر
@Pharax
بله متوجه شدم کاری که شما انتظار دارید انجام شدنیه و من استراکچر رو شفاف براتون توضیح دادم حالا اگر می خواهید در index و show دو نتیجه متفاوت رو دریافت کنید باید در قسمت BlogCollection یک شرط قرار بدید و بر اساس یک پارامتر قابل دستیابی مثلا روت یا کنترلر درخواست کننده رو مشخص کرده و برای هر کدام نتیجه دلخواه رو برگردونید.
مثلا :
$request->getRequestUri()
سلام
از resource برای برگردوندن و سفارشی کردن یک نتیجه استفاده کنید و از resource collection برای لیستی از نتایج یعنی برای استفاده در index باید آرایه ای از نتایج رو صورت resourceCollection برگشت بدید ولی برای نمایش کاستومایز شده هر آیتم از resource استفاده کنید.
سلام وقت بخیر
@hekmati خیلی ممنون فقط میشه دقیقتر توضیح بدین یا اگر براتون مقدور هست کدش رو بنویسین که چطوری باید این کار رو انجام بدم؟ اولین بار هستش انجام میدم دقیق نمیدونم چطوریه
ممنون
از map استفاده کنید
متد index شما چیزی شبیه به این میشه
$blogs = Blog::get()->map(function ($post){
return[
'title'=>$post->title,
'slug'=>$post->slug,
'description'=>$post->description,
];
});
return $this->sendResponse(BlogResource::collection($blogs), 'Posts fetched.');
آیتم هایی که میخوایید رو داخل return قرار بدید
@Pharax
سلام وقت شما هم بخیر
با دستور زیر یک ریسورس بلاگ ایجاد میکنیم
php artisan make:resource BlogResource
و به شکل زیر نتیجه رو بر میگردونیم
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'created_at' => $this->created_at->format('m/d/Y'),
'updated_at' => $this->updated_at->format('m/d/Y'),
];
حالا با دستور زیر یک ریسورس کالکشن ایجاد میکنیم
php artisan make:resource BlogResourceCollection
که به شکل زیر نتیجه توی اون برگشت داده میشه
public function toArray($request)
{
return parent::toArray($request);
}
حالا زمانی که می خواهید در کنترلر به لیستی از نتایج روی تویایندکس دسترسی داشته باشید به این شکل اقدام کنید.
return new BlogResourceCollection(Blog::all());
برای دسترسی به یک آیتم خاص به همراه جزئیات کاستومایز شده هم می تونید به شکل زیر اقدام کنید
return new BlogResource(Blog::find($id));
@mehranmarandi90 متاسفانه روش شما ج نداد و این ارور رو میده
Call to undefined method App\Models\Blog::map()
.
.
@hekmati شما دقیقا کاری که من کردم رو بهم گفتین و اصلا اون موردی که من میخوام رو مثل اینکه متوجه نشدین
من میخوام وقتی متد index() فراخوانی میشه این برگرده:
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'created_at' => $this->created_at->format('m/d/Y'),
'updated_at' => $this->updated_at->format('m/d/Y'),
];
و وقتی هم متد show() فراخوانی میشه این برگرده:
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'author' => $this->author,
'rank' => $this->rank,
'created_at' => $this->created_at->format('m/d/Y'),
'updated_at' => $this->updated_at->format('m/d/Y'),
];
تو سوالم هم گفتم میخوام وقتی داخل هر پست میشم اطلاعات اضافی هم نمایش داده بشه (مثلا نام نویسنده، امتیاز پست و...) ولی تو متد index که همه پست ها فراخوانی میشه این موارد نباشه. آیا راهی هست که بشه برای هر متد این رو customize کرد؟
@Pharax
مطمئنید متد get رو قبلش صدا زدید؟ چون map از متد های کالکشن هست و نباید همچین اروری برگردونه.
ورژن لاراول شما چنده؟
@mehranmarandi90
بله حق با شماست و اشتباه از من بود
من از firstOrFail استفاده کرده بودم که ارور میداد ولی با get درست نمایش داد.
خیلی ممنون.
فقط اگر با map به راحتی میشه نمایش داد چرا از api resources استفاده میشه؟ تا جاییکه من مستندات خود لاراول رو خوندم برای این کار استفاده میشد که بشه برای کلاینت اطلاعات را خلاصه فرستاد!
هدف از تعریف api resources فرا تر از یک متد map هست، متد map یه ابزاره که شما هر جایی میتونید استفاده کنید. ولی api resource نوعی از معماری سیستم حساب میشه
شما همه جا میتونید با map تغییرات دلخواه رو اعمال کنید، ولی همیشه باید بدونید در Api های دیگه اسم Attribute ها رو چی نوشتید و در جا های جدید هم همون شکل بنویسید. ضمنا api resource علاوه بر map کردن فیلتر های دیگه ای هم روی خروجی انجام میده.
@Pharax
بله متوجه شدم کاری که شما انتظار دارید انجام شدنیه و من استراکچر رو شفاف براتون توضیح دادم حالا اگر می خواهید در index و show دو نتیجه متفاوت رو دریافت کنید باید در قسمت BlogCollection یک شرط قرار بدید و بر اساس یک پارامتر قابل دستیابی مثلا روت یا کنترلر درخواست کننده رو مشخص کرده و برای هر کدام نتیجه دلخواه رو برگردونید.
مثلا :
$request->getRequestUri()
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟