ایجاد یک api در لاراول 5.5 با استفاده از api resources

تقریبا 1 سال میشه که از فرکتال واسه توسعه API استفاده میکنم. قبلا هربار که یک پروژه جدید داشتم، اولین کاری که انجام می دادم نصب کردن فرکتال بود. واسه همین تنها چیزی که از لاراول انتظار داشتم تا در نسخه های جدیدش ارائه بده، رفع کردن همچین نیازی بود. قابلیت ترنسفورم داده ها برای ایجاد یک API بهتر.

حال نزدیک به یک سال میشه که من کارهای فرانت-اند رو با فریمورک Vue.js انجام میدم و از طرفی سرویس دهی به کلاینت موبایل هم یکی از کارایه که خیلی ازش خوشم میاد. واسه همین،‌تنها کاری که من با لاراول انجام میدم ایجاد API هستش. هربار که من میخواستم یک API بنویسم فرکتال اولین کتابخونه ای بود که نصب میکردم. ولی دیگه نیازی به اینکار نیست!

لاراول سرویس ها و قابلیت های جدیدی رو با هر نسخه جدید ارائه میده. Api resources قابلیتیه که با 5.5 اومده و ما رو از استفاده از کتابخانه ی شخص سوم بی نیاز کرده. فرکتال کتابخانه عالی هست، ولی من تا جایی که امکانش باشه ترجیح میدم که بیشترین استفاده رو از قابلیت های خود فریمورک بکنم.

API reources دقیقا مشابه فرکتال پیاده سازی شده، پس فهمیدن اینکه چطوری کار میکنه واسم زمان زیادی طول نکشید.

ایجاد یک پروژه لاراول

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

1
laravel new laravelapi

خوب حال همه میدونیم که باید سرورمون رو برای پروژه کانفیگ کنیم. ^_^

ایجاد یک post resource

ریسورس ها در لاراول ویژگی جدیدی هستن که مدل ها و کالکشن مدل ها رو به راحتی برامون ترنسفورم میکنن. بزارید یک ریسورس برای مدل User درست کنیم:

1
php artisan make:resource User

بعد از اجرای دستور بالا، ریسورس User در app/Http/Resources قرار میگیره.

مایگریشین users رو باز کنید و ستون هایی که مایلید رو بهش اضافه کنید:

1
2
3
4
5
6
7
8
9
10
11
12
13
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
‍$table->integer('telepone');
‍$table->string('photo');
$table->rememberToken();
$table->timestamps();
});
}

من اینجا ستون های telepone و photo رو اضافه کردم.
سپس پروژه رو به دیتابیس وصل کنید و مایگریت رو انجام بدید.

خوب حالا چی؟

خوب، تا الان، ما یک مدل، کنترلر و مایگریشن داریم. و همینطور یک ریسورس که مدل و مدل کالشن ما رو به JSON تبدیل میکنه. خوب که چی؟

اول از همه، یک کلاس ریسورس چیه؟ کلاس User که توی دایرکتوری Resources ایچاد کردیم به چه دردی میخوره؟ خوب این کلاس متعلق به مدل User است و کارش فقط اینه که داده اون مدل رو به ساختار JSON تبدیل کنه.

بزارید کلاس User رو باز کنیم.

خوب اینجا ما فقط یک متد به اسم toArray داریم که در حال حاضر آرایه ای از همه صفت هایی که مدل User داره رو برای تبدیل شدن به ساختار JSON برمیگردونه.

استفاده از ریسورس User

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

کنترلر User شما بعد از ایجاد تغییرات لازم باید به این صورت باشه:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Resources\User as UserResource;
class UserController extends Controller
{
public function show($id)
{
return new UserResource(User::findOrFail($id));
}
}

برای ترنسفورم کردن اطلاعات کاربر، ما به سادگی User رو به UserResource پاس میدیم.

خوب حال بزارید یک روت جدید واسه متد show بسازیم واسه اینکه نتیجه رو ببینیم.

روت api.php رو باز کنید و خارج از میدلور این روت رو اضافه کنید:

1
Route::get('/users/{id}', 'UserController@show');

حالا میتونید یک سیدر هم برای User اضافه کنید که یکسری داده فیک براش بسازید :) . بعد اینکار لینک زیر رو باز کنید.

http://laravelapi.dev/api/users/1

نتیجه ای که میبینید باید شبیه این باشه:

user_show_by_id

خوبس، حال اگه در داده بالا یکسری از صفت های مدل User مانند مثل id یا updated_at رو نخوایم نمایش بدیم چی؟ یا اینکه بخوایم برای خواناتر شدن اسم صفت photo رو به avatar تغییر بدیم. همچنین که مقدار مربوط به صفت photo را میبینید، آدرس تصویر کامل نیست و فاقد آدرس سرور هست.

پس ریسورس User رو دوباره باز کنید و داده برگشتی متد toArray رو به این صورت تغییر بدید:

1
2
3
4
5
6
7
8
9
10
11
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'phone' => $this->telephone,
'avatar' => url($this->photo),
'registeredAt' => $this->created_at->toDateTimeString()
];
}

همونطور که میدونید اسم صفت telephone رو موقع برگشت به phone تغییر دادم. صفت های photo و created_at هم همینطوری. بله، صفت updated_at رو پاک کردم چون نیازی نبود که اون رو هم برگشت بدم.

اگه مرورگر رو رفرش کنیم نتیجه اینبار به این صورت میشه:

user_show_by_id_custom_toarray

نکته مهمی که باید در نظر بگیرید اینه که همیشه مقادیر هر صفت رو بر اساس نوع آن برگشت داد. برای مثال اگه دارید صفت price رو برای یک محصول برمیگردونید پس باید موقع برگشت دادنش تبدیلش کنید به نوع عدد. این باعث میشه که مقدار price بعنوان رشته داخل کوتیشین قرار نگیره.

بزارید برای مثال در زیر صفت telephone رو به عدد تبدیل کنیم:

1
2
3
4
5
6
7
8
9
10
11
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->email,
'phone' => (int) $this->telephone,
'avatar' => url($this->photo),
'registeredAt' => $this->created_at->toDateTimeString()
];
}

اگه مرورگر رو دوباره رفرش کنید میبینید که مقدار صفت telephone به عدد تبدیل شده.

این همه چیزی بود که API Resource میتونه انجام بده؟

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

البته همونطور که میدونید، مباحث دیگه ای هم هست که اگه بخوام در مورد اونا هم بنویسم باعث میشه طول مثاله خیلی زیاد بشه. مباحثی مانند Pagination, resource collection, اضافه کردن رابطه ها, data wrapping و meta data از جمله مواردی هستن که میتونید براتون کاربردی باشن.

Proudly hosted on GitLab pages
© مهران رسولیان