فراز بنی آدم
2 سال پیش توسط فراز بنی آدم مطرح شد
11 پاسخ

سفارشی سازی API Resources

سلام وقت بخیر
من از طریق 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 که همه پست ها فراخوانی میشه این موارد نباشه.
چطوری میتونم این کار رو انجام بدم؟
با تشکر


ثبت پرسش جدید
حسن حکمتی
تخصص : برنامه نویس وب و بلاکچین
@hekmati 2 سال پیش مطرح شد
0

@Pharax
بله متوجه شدم کاری که شما انتظار دارید انجام شدنیه و من استراکچر رو شفاف براتون توضیح دادم حالا اگر می خواهید در index و show دو نتیجه متفاوت رو دریافت کنید باید در قسمت BlogCollection یک شرط قرار بدید و بر اساس یک پارامتر قابل دستیابی مثلا روت یا کنترلر درخواست کننده رو مشخص کرده و برای هر کدام نتیجه دلخواه رو برگردونید.
مثلا :

$request->getRequestUri()

حسن حکمتی
تخصص : برنامه نویس وب و بلاکچین
@hekmati 2 سال پیش مطرح شد
0

سلام
از resource برای برگردوندن و سفارشی کردن یک نتیجه استفاده کنید و از resource collection برای لیستی از نتایج یعنی برای استفاده در index باید آرایه ای از نتایج رو صورت resourceCollection برگشت بدید ولی برای نمایش کاستومایز شده هر آیتم از resource استفاده کنید.


فراز بنی آدم
@Pharax 2 سال پیش مطرح شد
0

سلام وقت بخیر
@hekmati خیلی ممنون فقط میشه دقیقتر توضیح بدین یا اگر براتون مقدور هست کدش رو بنویسین که چطوری باید این کار رو انجام بدم؟ اولین بار هستش انجام میدم دقیق نمی‌دونم چطوریه
ممنون


مهران مرندی
تخصص : برنامه نویس
@mehranmarandi 2 سال پیش آپدیت شد
0

از 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 قرار بدید


حسن حکمتی
تخصص : برنامه نویس وب و بلاکچین
@hekmati 2 سال پیش مطرح شد
0

@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));

فراز بنی آدم
@Pharax 2 سال پیش مطرح شد
0

@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 کرد؟


مهران مرندی
تخصص : برنامه نویس
@mehranmarandi 2 سال پیش مطرح شد
0

@Pharax
مطمئنید متد get رو قبلش صدا زدید؟ چون map از متد های کالکشن هست و نباید همچین اروری برگردونه.
ورژن لاراول شما چنده؟


فراز بنی آدم
@Pharax 2 سال پیش مطرح شد
-1

@mehranmarandi90
بله حق با شماست و اشتباه از من بود
من از firstOrFail استفاده کرده بودم که ارور میداد ولی با get درست نمایش داد.
خیلی ممنون.
فقط اگر با map به راحتی میشه نمایش داد چرا از api resources استفاده میشه؟ تا جاییکه من مستندات خود لاراول رو خوندم برای این کار استفاده میشد که بشه برای کلاینت اطلاعات را خلاصه فرستاد!


مهران مرندی
تخصص : برنامه نویس
@mehranmarandi 2 سال پیش مطرح شد
1

هدف از تعریف api resources فرا تر از یک متد map هست، متد map یه ابزاره که شما هر جایی میتونید استفاده کنید. ولی api resource نوعی از معماری سیستم حساب میشه
شما همه جا میتونید با map تغییرات دلخواه رو اعمال کنید، ولی همیشه باید بدونید در Api های دیگه اسم Attribute ها رو چی نوشتید و در جا های جدید هم همون شکل بنویسید. ضمنا api resource علاوه بر map کردن فیلتر های دیگه ای هم روی خروجی انجام میده.


فراز بنی آدم
@Pharax 2 سال پیش مطرح شد
حسن حکمتی
تخصص : برنامه نویس وب و بلاکچین
@hekmati 2 سال پیش مطرح شد
0

@Pharax
بله متوجه شدم کاری که شما انتظار دارید انجام شدنیه و من استراکچر رو شفاف براتون توضیح دادم حالا اگر می خواهید در index و show دو نتیجه متفاوت رو دریافت کنید باید در قسمت BlogCollection یک شرط قرار بدید و بر اساس یک پارامتر قابل دستیابی مثلا روت یا کنترلر درخواست کننده رو مشخص کرده و برای هر کدام نتیجه دلخواه رو برگردونید.
مثلا :

$request->getRequestUri()

فراز بنی آدم
@Pharax 2 سال پیش مطرح شد
0

@hekmati
بله کاملا درست کار کرد.
خیلی ممنون


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام