Laraveldagi API-larni loyihalashning eng yaxshi amaliyotlari

Bu yerdan o'g'irlangan.

Ushbu postda Migel Piedrafitaning Blogcast ilovasi tufayli audio versiyasi mavjud.

Men nafaqat DevOps muhandisi emasman, balki PHP bilan noldan boshladim, bolaligimdan, 5-sinfda o'qigan paytlarimda. O'shandan beri men o'z kodimni doimiy ravishda takomillashtirdim va odamlar toza kod, standart vizualizatsiya uchun qandaydir standartlarni qabul qilishganini va ular standart bo'lganligi sababli, har bir boshqa ishlab chiquvchilar bir xil kod bazasida nima yozganlarini yaxshiroq tushunishlari mumkin edi.

Men har doim oldingi oynada emas, balki orqada ko'proq kodlashni yaxshi ko'rardim. Men to'liq stack bo'lishga harakat qildim, ammo bu menga mos kelmadi. Shunday qilib, men, ayniqsa API interfeyslarini yozishga qaytdim. Bu safar, men umuman kodlash standartlari haqida gapirmayman, lekin qanday API ishlayotganligi va ularni qanday qilib osonroq ishlab chiqishni, xavfsizlikdan qanday qilib yaxshiroq qilish kerakligi haqida gaplashaman.

Asosan, API bu har qanday ilova, yoki Android ilovasi yoki veb-ilova tushunadigan maxsus formatdagi ma'lumotlarni qaytaradigan interfeys.

JSON keng qo'llaniladi, chunki deyarli hamma joyda. Boshqa variant - XML-ni ishlatish, lekin men XML-ni JSON-dan ko'proq foydalangan ba'zi uchinchi tomon API-larida (ayniqsa to'lovlarni etkazib beruvchilar mening mamlakatimda) muammoga duch keldim va ishlab chiqish butunlay bema'ni edi. Men doimo JSON API-larini ishlab chiqishni maslahat beraman, agar kimdir XML API-ni talab qilmasa.

API-ni ishlab chiqishda ba'zi bir narsalarga e'tibor berish kerak, xususan:

  • xavfsizlik - OAuth, API kaliti yoki CORS-dan foydalanib uni himoya qilish shart. Ixtiyoriy ravishda, ilova uchun so'rovlarni cheklash uchun siz gaz kelebekni ishlatishingiz kerak.
  • sarlavhalar - ilovalaringizga to'g'ri tarkib turini yuborganingizga ishonch hosil qiling. Kontent turining sarlavhasi - bu ma'lumotni qabul qiladigan mijozga ma'lumot beradigan ma'lumotlarning bir qismi: "men sizga yuborganim bu JSON" yoki "bu erda XML. "to'g'ri tahlil qiling", shuning uchun brauzer yoki sizning mijozingiz uni qanday hal qilishni biladi.
  • kodlash standartlari va nomlash - bu shunchaki orqaga qaytishdir. Javoblaringizda izchil ekaningizga ishonch hosil qiling. Faqat bitta nomlash va to'g'ri formatlash uchun yopishtiring.

Men Laravel-dagi API-larni kodlashni yaxshi ko'raman, chunki siz voqealarni translyatsiya qilish yoki boshqa yo'qolgan Lumen xususiyatlarini yanada tezroq qilishni istagan holda yanada kengaytirmoqchisiz, buni butun loyihani noldan yozmasdan qilishingiz mumkin. Agar siz yalang'och minimal darajada qolsangiz, Lumen-dan foydalanishingiz mumkin.

Xavfsizlik

Siz ehtiyot bo'lishingiz kerak bo'lgan eng katta muammo bu xavfsizlikdir. Uni himoya qilish juda oson, lekin agar uni to'g'ri bajarmasangiz, kiruvchi kirish huquqiga ega bo'lishingiz mumkin. Laravel-da siz Laravel Passport-dan foydalanishni xohlashingiz mumkin - bu Laravel ekotizimiga tegishli bo'lib, ushbu App ID - App Secret orqali identifikatsiyani qo'llab-quvvatlaydi, kirish tokenini olish uchun kimdir yoki serverni taqqoslash uchun, bu orqa yoki old qism. Asosan, siz server tomonidan yaratilishi mumkin bo'lgan tokenni (ya'ni har kuni cronjob-da ishlaydigan buyruqdan API-ga kirish) yoki OAuth-ning so'nggi nuqtasiga App ID va App Secret-dan so'rov yuborasiz. ilovangizga kirgan foydalanuvchi.

Shu bilan bir qatorda, deyarli bir xil ishlaydigan JWT Token autentifikatsiyasidan foydalanishni xohlashingiz mumkin, ammo tushunish osonroq bo'lishi mumkin. O'zingizning tanlovingizni tanlang va amalga oshirishda ham, ehtiyojlaringizda ham qaysi biri sizga mos kelishini ko'rib chiqing.

Sarlavhalar

Veb-so'rovlar shunchaki mijoz va server o'rtasidagi yoki ikki server o'rtasidagi oddiy suhbatlardir. Ular so'rov va javobga tayanadilar, agar bunday so'rov veb-sayt turiga kirmasa, lekin bu boshqa gap. Narsalarni so'rash yoki qaytarish paytida, sarlavhalar deb nomlangan ba'zi ma'lumotlar e'tiborga olinishi kerak - ulardan ba'zilari serverga olingan ma'lumotni qanday qayta ishlash kerakligi yoki mijoz javobni qanday olishni xohlashini aytadi.

Xuddi onang aytgandek: "do'kondan sut sotib ol, faqat X markali sutdan sotib ol". Siz nima qilishni bilasiz, lekin uni faqat bitta sut turini tanlashingiz kerak. Bu so'rovlar bilan bir xil: "men foydalanuvchilar ro'yxatini olishni xohlayman, lekin ularni JSON-da bering" yoki "men barcha foydalanuvchilarni olishni xohlayman, lekin meni 20 qismga yuboring" (agar siz GET parametrini ko'rsatsangiz) ). Buning uchun, qabul qilish deb nomlangan sarlavha mavjud, u javobni JSON sifatida olishni xohlasangiz application / json bo'lishi mumkin. Bu shart emas, lekin AJAX kabi ba'zi ilovalar uchun, agar u ushbu sarlavhani aniqlasa, mijoz uchun javobni avtomatik ravishda deklaratsiya qiladi, masalan:

var data = JSON.parse (javob.data);

Siz bilishingiz kerak bo'lgan yana bir sarlavha - Tarkib turi, bu biroz chalkash, ammo Qabul qilishdan farqli o'laroq: u serverga qanday tarkibga ega bo'lish kerakligini aytadi. Masalan, agar siz JSON qatoriga o'xshash RAW ma'lumotlarini yuborishni xohlasangiz, siz Content-Type-ni dastur / json-ga o'rnatishingiz mumkin, ammo agar siz tarkibni $ _POST o'zgaruvchisi orqali olishni istasangiz, uni x-www-ga sozlashingiz kerak. -form-urlencoded. Bu sizga nafaqat $ _POST orqali tarkibni tahlil qilishda yordam beradi, balki uni HTML shakllarida ishlatish kerak, chunki ularga oson kirish mumkin. Agar siz fayllarni kiritish orqali ikkilik kabi ma'lumotlarni yuborsangiz, masalan, tarkibni multipart / form-data yuborganingizga ishonch hosil qiling.

Laravelda bu muammo bo'lmaydi, chunki siz to'g'ridan-to'g'ri ma'lumotlarga kirishingiz mumkin.

Ilova / json uchun:

funktsiya indeksi ($ so'rovini so'rash)
{
   $ var = $ request-> o'zgaruvchi;
}

Ammo, application / json-da JSON tarkibini -> all () usulidan foydalanib ko'rolmaysiz:

funktsiya indeksi ($ so'rovini so'rash)
{
   $ data = $ request-> barchasi (); // bu bo'sh qator, hatto bizda ma'lumotlar ham mavjud.
}

Agar x-www-form-urlencoded yoki multipart / form-data-ga o'rnatilgan bo'lsa, -> all () yordamida barcha o'zgaruvchilarni ko'rishingiz mumkin.

Laravel-ga javob qaytarayotganda, siz o'rnatilgan JSON javobidan foydalanishingiz mumkin yoki siz uni yaxshiroq ishlab chiqishingiz va Laravel Fractal yoki Laravel Responder kabi paketlardan foydalanishingiz mumkin. O'z tajribamdan kelib chiqqan holda, Laravel Responder ishni semantik jihatdan yaxshiroq bajardi. Sizga ko'rsatay:

getUsers funktsiyasi ($ so'rovni so'rash)
{
   return respondonder () -> muvaffaqiyat (foydalanuvchi :: barchasi ()) -> javob berish ();
}

Bu OK 200 holatiga ega bo'lgan va JSON formatlangan barcha foydalanuvchilarni qaytaradi. Salqin, to'g'rimi? Xatolar uchun siz kod va xabarni yuborishga imkon beradigan shunga o'xshash narsani qilishingiz kerak:

getUsers funktsiyasi ($ so'rovni so'rash)
{
   $ users = Foydalanuvchi :: barchasi ();

   if ($ users-> count () === 0) {
      return responder () -> error ('no_users', 'foydalanuvchilar yo'q.)) -> javob ();
   }
   return respondonder () -> muvaffaqiyat ($ foydalanuvchilar) -> javob berish ();
}

Ushbu to'plam yanada ko'proq narsani qo'llab-quvvatlaydi, shuning uchun hujjatlarga o'ting, chunki uni osonlikcha transformator va yuborilgan ma'lumotlar bilan birlashtirish mumkin.

Kodlash standartlari

Men odamlar yaxshi ko'rgan yoki toza bo'lgan ba'zi standartlarga rioya qilishlarini ko'rish menga yoqadi. Toza kodni yaratishda va API yo'nalishlarini yaxshiroq tuzishda sizga yordam beradigan ba'zi maslahatlar.

API yo'nalishlarida marshrutlar / api.php faylidan foydalaning

Laravel oddiy marshrutlar / api.phpfile bilan birga keladi, bu veb-marshrutlash uchun ishlatiladigan odatdagi marshrutlar / web.php faylidan farq qiladi. api.php fayli sizning API yo'nalishlaringizni saqlash uchun yaratilgan. U bortda qo'llaniladigan o'rta dasturlarga ega (buni app / Http / Kernel.php, $ midwareGroups o'zgaruvchisida, api ostida ko'rish mumkin) va api prefiksi mavjud, shuning uchun belgilangan barcha yo'nalishlar / api uchun mavjud

Yo'nalish nomlaridan foydalaning

Men nima qilishni yaxshi ko'raman, butun API-ni sozlash, shuning uchun marshrutlarga ularning nomi bilan api orqali kirishim mumkin. prefiks

Route :: get ('/ users', 'API \ UserController @ getUsers') -> ism ('get.users');

Ushbu yo'nalishning URL manzilidan marshrutni olish mumkin ('get.users'), ammo u web.php bilan zid kelishi mumkin.

Yo'nalish :: guruh (['as' => 'api.'], Funktsiya () {
   Route :: get ('/ users', 'API \ UserController @ getUsers') -> ism ('get.users');
});

Shunday qilib, siz uni marshrutda olasiz ('api.get.users').

Agar siz marshrut nomlarini ishlatsangiz, agar sizning yozish testlaringiz bo'lsa, URL manzilini o'zgartirib, marshrut nomini saqlab qo'yishni rejalashtirmoqchi bo'lsangiz, hamma joyda URL manzilini almashtirishingiz shart emas.

Ta'riflovchi, ammo oddiy yo'nalish

Yaxshi amaliyot marshrutlarni foydalanuvchilar, xabarlar va hokazolar kabi bo'limlarga bo'lish va siz o'ylashingiz mumkin bo'lgan eng oddiy narsalardan foydalanishdir:

Yo'nalish :: guruh (['as' => 'api.'], Funktsiya () {
   Marshrut :: guruh (['as' => 'hisob.', 'Prefiks' => '/ account'], funktsiya () {
         Route :: get ('/ users', 'API \ UserController @ getUsers') -> ism ('get.users');
         Route :: get ('/ user / {id}', 'API \ UserController @ getUser') -> ism ('get.user');
         Route :: post ('/ user', 'API \ UserController @ createUser') -> ism ('create.user');
         // va boshqalar.
   });
});

Ma'lumot olish uchun :: get (), yaratish uchun :: post (), tahrirlash uchun :: patch () yoki :: put () va ma'lumotlarni o'chirish uchun :: delete () dan foydalaning. Shunga o'xshab, siz bir xil tugatish nuqtasidan foydalanishni tugatasiz, ammo har xil turdagi so'rovlar bilan siz boshqa harakatlarga o'tishingiz mumkin bo'ladi.

Nazoratchi ichida siz oddiy kodlashdan foydalanishingiz va so'rovlar darslaridan foydalanishingiz kerak, chunki men Laravelni itarishda batafsil aytib o'tdim - Laravel 5.7 uchun eng yaxshi maslahatlar

getUsers funktsiyasi ($ so'rovni so'rash)
{
   $ users = Foydalanuvchi :: barchasi ();
   return respondonder () -> muvaffaqiyat ($ foydalanuvchilar) -> javob berish ();
}
getUser funktsiyasi ($ id, $ so'rovni talab qilish)
{
   $ user = Foydalanuvchi :: findOrFail ($ id);
   return respondonder () -> muvaffaqiyat ($ foydalanuvchi) -> javob berish ();
}
createUser funktsiyasi (CreateUserRequest $ so'rovi)
{
    $ user = User :: create ($ request-> all ());
    return respondonder () -> muvaffaqiyat ($ foydalanuvchi) -> javob berish ();
}
// va boshqalar.

Bundan tashqari, barcha harakatlar uchun bir xil nomlarga yopishganingizga ishonch hosil qiling, shunda siz ularni tezroq topasiz va har kim kod bazasiga kirib, tarkibni saqlashni yoki yaratishni osonlashtiradi. Repo-ga API kalitlari yoki maxfiy ma'lumotlarni bermang, toza kodni yozmang va boshqalardan o'rganishni xohlang.

Tushunish juda qiyinmi? Menga yet!

Agar sizda Laravel haqida boshqa savollar bo'lsa, DevOps bilan bog'liq har qanday ma'lumotga muhtoj bo'lsangiz yoki rahmat aytishni xohlasangiz, meni Twitter @rennokki orqali topishingiz mumkin!

"Slack" jamoatchiligimizga qo'shiling va har hafta Faun mavzularini o'qing

Agar ushbu maqola foydali bo'lsa, iltimos, muallifni qo'llab-quvvatlashingizni ko'rsatish uchun iltimos, below tugmasini bosing. ⬇