ساخت API و معایب و تفاوت های ( SOAP یا REST یا GraphQL یا gRPC )
کدام یک از شیوههای مختلف را برای ساخت API انتخاب کنیم؟ SOAP، REST، GraphQL و حتی شیوههای جدید مانند gRPC، همگی استانداردهای مشابهی برای طراحی و ساخت API و نوع تعامل مصرفکنندهها با آن هستند. از آنجا که این مبحث به سرعت در حال تغییر و تحول بوده، همواره مسائل و فرصتهای جدیدی برای سنجش وجود دارند.
در طی اجلاسی که در آوستین آمریکا برگزار شد، جیمز هیگینبوتام، متخصص و مشاور اِی پی آی و میکروسرویس شرکت LaunchAny، مروری بر شیوههای مختلف ساخت API داشت. از آنجا که مدتیست که REST عملاً به استاندارد طراحی ای پی ای تبدیل شده، جیمز چشم انداز فعلی طراحی ای پی ای را بطور کامل بررسی کرد، تا ببینیم آیا REST با لیاقت رتبه اول را تصاحب کرده است یا خیر.
فهرست مطالب
شیوههای مختلف ساخت API
البته این موضوع بیشتر از اینکه یک رقابت باشد، مطالعهایست بر اینکه چگونه اهداف تجاری تعیین کنندهی تصمیمات در مورد شیوه ساخت API هستند. در این مقاله «مسابقه محبوبیت» را کنار گذاشته و شیوههای مختلف ساخت API را این از نقطهنظر بررسی میکنیم که کدامیک برای مصرف کننده، بهترین انتخاب است.
ای پی آیها پاسخ بسیاری از کاربردها هستند
اولین چیزی که جیمز به آن اشاره میکند، این است که پهنهی استفاده از ای پی آیها بسیار گسترده بوده و ای پی آیها میتوانند برای پاسخگویی به بسیاری از کاربردها، استفاده شوند.
از آنجا که تجربه کاربری، تجربه کاری و تجربه همکاری و شراکت میتواند بسیار گسترده و متنوع باشد، طبیعتاً شیوه مناسب برای ایجاد و ساخت API نیز بستگی به نوع کارکردمان خواهد داشت.
به غیر از تفاوتهای مصرفکنندگان ای پی آی (API)، رفتارهای تعاملی بسیار متنوعی نیز وجود دارند که میتوانند در عمل پیادهسازی را تحت تأثیر قرار دهند. جیمز عملکردهای درخواست،پاسخ، درخواست، تایید، انتشار، اشتراک ، عملکردهای دستهای و ارسال پیام را در به عنوان شیوههای تعامل دسته بندی کرد.
او همچنین یادآور شد که معمولاً ای پی آیها در دسته درخواست یا پاسخ قرار میگیرند، و موارد دیگر در شرایط منحصر به فرد دیگری استفاده میشوند.
گذری در تاریخ: از CORBA تا GraphQL
راه دیگر برای درک گستردگی و تنوع شیوههای موجود، رجوع به تاریخ استانداردهای ارتباطات در وب است. جیمز به این نکته اشاره کرد که در دهه ۹۰ میلادی عمومیترین شیوه استاندارد ای پی آی (API) برای ارتباط بین کسب و کارها، زبان توصیفی سرویس به نام CORBA بود.
هدف CORBA با نقل قول از جیمز «ایجاد قابلیت همکاری بین سیستمها و حتی بین زبانهای برنامهنویسی توسط خارجسازی اشیاء از زبانها» بود.
پس از آن SOAP به وجود آمد، که برای یکپارچهسازی داخلی استفاده میشد، و همه چیز را بجای شئ به عنوان سرویس قلمداد میکرد.
SOAP فواید بسیار زیادی داشت، مثلاً وجود فایروال، خللی در کارکرد آن ایجاد نمیکرد، با پروتوکلهای مختلف لایه انتقال سازگار بود، و همچنین با فراخوانهای غیر همگام نیز کار میکرد.
قدرت پروتکل HTTP برای ساخت API
با این حال، با رشد تلفنهای هوشمند، اپلیکیشنهای وب و اینترنت اشیاء، همه به سمت HTTP بازگشتند. HTTP مانند نعمتی خدادادی برای ارتباطات بین اپلیکیشنها و SaaS (نرمافزار به عنوان سرویس) بوده، و این موضوع دلیل یا دلایلی داشته است.
برای توضیح بخشی از اصول اولیه، HTTP توسط URL ها خطوط منابع را برای ما بوجود میآورد. افعالی مانند «GET، POST، PUT و PATCH» وجود دارند که قابلیت کار با این منابع را فراهم میآورند. همچنین کدهای پاسخ، و هِدِرهایی وجود دارند که روابط بین کِلاینت و سرور را برای ما مشخص میکنند.
اگر بخواهیم کمی پیش برویم، HTTP مذاکرات محتوا را نیز فراهم میآورد، که به ای پی آیها اجازه میدهند طبق قالبهای داده (JSON، XML، شاید حتی CSV و غیره) یا زبانهای دیگر پشتیبانی شده توسط ای پی آی (API) ما، با سرور و کلاینت ارتباط ایجاد کنند.
HTTP همچنین مواردی مانند حافظههای نهان، Etagها، درخواستهای شرطی و کنترل همزمانی را ایجاد میکند.
چرا باید اینطور HTTP را زیر و رو کنیم؟
خب، درست است که ما پشتیبانی بسیار زیادی برای HTTP ایجاد کردهایم که کارایی بسیار زیادی برای ما فراهم کند، ولی برداشت جیمز این است که:
«همه خودشان را درگیر مفاهیم داخلی HTTP کردهاند، در حالیکه میتوانند فقط از HTTP استفاده کنند!»
در کل، درک پروتوکلهایی که برای انتقال دادهها استفاده میکنیم اهمیت زیادی دارد. همانگونه که جیمز اشاره میکند، ما معمولاً در هنگام بحث درباره شیوه طراحی و ساخت ای پی آی (API) در مورد این موارد فکر نمیکنیم. سازندگان ای پی آیها با داشتن درک بهتری از مشخصات HTTP میتوانند ای پی آیهای کاراکتر و قویتری بسازند.
مقایسه شیوههای ساخت ای پی آی (API)
جیمز هدف توسعه دهنده یا طراح خوب را اینطور بیان میکند:
«ما به اصل محتوای هر چیزی که مصرفکننده قرار است از آن استفاده کند نگاه میکنیم، و از خود میپرسیم آیا این مناسب کاربرد خاص ما خواهد بود؟»
بنابراین، نگاهی داشته باشیم به شیوههای مختلف ساخت ای پی آی (API) و اینکه هر کدام برای کدام کاربرد مناسب هستند.
انواع ای پی آی (API)
در هنگام استفاده از ابزار جدید در تیم خود، باید فواید و معایب آن را سبک و سنگین کنید. مسائل زیادی نیاز به اندازهگیری خواهند داشت. زمانی که برای یاد گرفتن آن باید صرف شود؛ زمانی که میتواند برای توسعه امکانات جدید صرف شود و البته زمان سربار که برای رسیدگی به دو سیستم همزمان نیاز دارید.
با وجود چنین هزینههای سنگینی، هر فناوری جدید باید با اختلاف بسیار بهتر، سریعتر و پربارتر باشد. بهبودهای آهسته، هیجان انگیزند، ولی ارزش سرمایهگذاری را نخواهند داشت.
انواع اِی پی آی (API) که من قصد صحبت در مورد آنها را دارم و بطور ویژه GraphQL، به عقیده من قدم بسیار بزرگ رو به جلو هستند، و فوایدی که فراهم میآوردند برای توجیه هزینهها، زیادی هم خواهند بود.
بهتر است بجای شروع با «پرداختن به امکانات» ابتدا آنها را بخوبی مورد تحلیل قرار داده، و چگونگی بوجود آمدن آنها را درک کنیم. در ادامه ما هر کدام را به طور کامل بررسی می کنیم.
RPC چیست و چه کاربردی دارد؟
بطور قطع RPC اولین الگوی اصلی برای اَپی (API) بوده، و وجود آن به سالها قبل یعنی اواسط دهه ۶۰ میلادی برمیگردد. در آن زمان، کامپیوترها هنوز آنقدر بزرگ و گرانقیمت بودند، که مفهوم توسعه برنامههای کاربردی بر اساس اِی پی آی، آنگونه که ما امروز آنها را میشناسیم، فقط در حد تئوری وجود داشت.
محدودیتهایی مثل سرعت و تأخیر، قدرت پردازش، زمان پردازش مشترک و لزوم مجاورت فیزیکی، بجای ایجاد سرویسهای که دادهها را در معرض نمایش بگذارند، مهندسین را مجبور به فکر در مورد سیستمهای توزیع شده میکرد.
از زمان ARPANET در دهه ۶۰، تا زمان CORBA و Java RMI در اواسط دهه ۹۰ میلادی، بیشتر کامپیوترها با استفاده از «فراخوانیهای رویهای راهدور» یا همان RPC با هم تعامل داشند.
RPC مدلی برای تعامل بین سرور و کلاینت است که در آن کلاینت از راه دور، رویه (یا متدی) برای اجرا روی یک سرور ایجاد میکند. بسیاری مسائل در مورد RPC کاملاً مطلوب هستند.
اصل اساسی آن این است که به توسعهدهنده اجازه میدهد از راه دور، رویه را طوری روی سرور اجرا کند که انگار روی سرور محلی است، فقط چه حیف که خیلی کندتر و غیرقابل اعتمادتر، که این موضوع تداوم و پایداری را بین سیستمهای مختلف و جداگانه ایجاد میکند.
مانند بسیاری چیزهای دیگر که از ARPANET نشأت گرفتهاند، RPC نیز از زمان خود جلوتر بود، چراکه این نوع تداوم مسئلهای است که ما حتی هنوز هم در حال کار کردن با عملیات غیرقابل اعتماد و غیرهمگام مانند پایگاهداده و فراخوانی سرویسهای خارجی، به شدت به دنبال آن هستیم.
در طول این چند دهه، تحقیقات بسیار زیادی در مورد این موضوع انجام شد، که چگونه توسعهدهندگان میتوانند رفتارهای غیرهمگام اینچنینی را داخل جریان برنامههای عادی قرار دهند؛ اگر مفاهیمی مانند Promise ها، Future ها و وظایف زمانبندیشده در آن زمان وجود داشتند، شاید امروز چشمانداز ما در مورد اِی پی آی طور دیگری میبود.
یک موضوع عالی دیگر در مورد RPC این است که از آنجا که محدودیتی در مورد نوع ساختمان داده ندارد، روشهای ویژهای میتواند برای مشتریانی که دقیقاً اطلاعات مورد نظر خود را درخواست و دریافت میکنند، نوشته شوند. این موضوع میتواند به حداقل شدن سربار و payload در هر لایه شبکه کمک کند.
با این حال، چیزهایی هم وجود دارند که کار با RPC را دشوار میکنند. اولاً اینکه تداوم نیاز به زمینه دارد. طراحی RPC به این صورت انجام شده است که سیستمهای محلی و راهدور را به شکلی قوی به هم متصل میکند. این موضوع باعث میشود مرزهای بین کدهای محلی و راهدور شما از بین بروند. برای بعضی حوزهها مثل مشتریان SDK، این موضوع بدون اشکال یا حتی مطلوب است، ولی برای اَپیهایی که کد مشتری خوب درک نشده باشد، بجای دادهمحور شدن، باعث کم شدن انعطافپذیری میشود.
ولی از آن مهمتر، پتانسیل تکثیر متدهای اِی پی آی (API) است. در تئوری، یک سرویس RPC در حقیقت اِی پی آی (API) کوچک و فکرشدهای را ارائه میدهد که قادر به انجام هر کاری باشد. اما در عمل، endpointهای بسیاری، بدون ساختار خاصی با هم ترکیب میشوند. بنابراین به مرور زمان و همانطور که اعضای تیم کم و زیاد میشوند و پروژه تغییر مسیر میدهد، ایجاد نظمی بسیار شدید و سختگیرانه برای جلوگیری از همپوشی اَپیها و ایجاد نسخههای تکراری، مورد نیاز خواهد بود.
درست است که در صورت داشتن ابزار و مستندسازی مناسب، مانند موردی که ذکر کردم، تغییرات قابل مدیریت و انجام هستند، ولی در طول مدت برنامهنویسی خودم، تعداد فوقالعاده کمی سرویس دیدم که دارای مستندسازی و نظم مناسب باشند. برای من این موضوع بیشتر شبیه به نخود سیاه است.
وب سرویس SOAP چیست؟
نوع اصلی دیگر اِی پی آی (API) که بوجود آمد، SOAP بود، که در اواسط دهه ۹۰ و توسط مرکز تحقیقات مایکروسافت متولد شد. SOAP یا «پروتوکل دسترسی ساده اشیاء» توصیف پروتوکل جاهطلبانهای برای ارتباطات مبتنی بر XML میان برنامههای کاربردی است. هدف اصلی SOAP، برطرف کردن برخی اشکالات عملی در RPC و بطور خاص RPC مبتنی بر XML بوده، توسط ساختن زیرساخت خوشساختی برای سرویسهای پیچیده وب بوده است. اما در حقیقت، بیش از موانعی که برطرف میکند، موانع ایجاد میکند. این موضوع که امروزه تعداد بسیار کمی endpoint توسط SOAP ساخته شدهاند، خود گواهی بر این موضوع است.
«بیشتر مردم SOAP را موفقیتی نصفه و نیمه میدانند.»
-دان باکس
مزایای وب سرویس SOAP
علیرغم قلنبه سلمبه بودن و اسمگذاریهای بد، SOAP چیزهای خوبی نیز دارد. قراردادهای قابل اجبار برای WSDL و WADL (که به ترتیب ویزدل و وادل تلفظ میشوند) بین کلاینت و سرور، از قابل پیشبینی بودن و امنیت نوع داده نتایج اطمینان حاصل میکند، و WSDL میتواند برای تولید مستندسازی و یا یکپارچهسازی بین IDE ها و دیگر ابزار استفاده شود.
انقلاب بزرگ SOAP در اِی پی آی (API) این بود که بطور تدریجی و شاید حتی ناخواسته، فراخوانهای منبعگرا را معرفی کرد. Endpointهای SOAP اجازه میدهند بجای اینکه برای تولید دادهها به چه متدهایی نیاز داریم درخواستهایی با ساختار از پیش تعیین شده داشته باشیم (البته اگر اینطور از آن استفاده کنیم). مهمترین ایراد SOAP قلمبه و سلنبه بودن آن است. استفاده از SOAP بدون استفاده از ابزارهای بسیار زیاد، تقریباً غیرممکن است. برای نوشتن تست، برای مشاهده پاسخهای دریافت شده از سرور و برای parse کردن دادهها به ابزارهای مختلف نیاز خوهیم داشت. خیلی از سیستمهای قدیمی هنوز از SOAP استفاده میکنند، ولی نیاز به استفاده از ابزارهای زیاد، باعث میشود استفاده از آن در پروژههای جدید بسیار خسته کننده باشد، و تعداد بایتهای مورد نیاز برای ساختار XML باعث شده که SOAP انتخاب بسیار بدی برای موبایلها و سیستمهای توزیع شده که تعداد مراجعات در آنها زیاد است باشد.
معماری rest چیست؟
وقتی از REST صحبت میکنیم، منظور ما قوانین تعریف شده روی فیلدینگ هستند، که عبارتند از روابط بین سرور و کلاینت، بدون حالت بودن (statelessness)، قابلیت ذخیره سازی در حافظه نهان، لایه بندی، کد بر اساس تقاضا و داشتن رابط یکسان.
همانطور که جیمز به آن اشاره میکند، از طرف دیگر، CRUD الگویی برای چرخه حیات است که بر REST اعمال میشود، و در واقع این دو، یک مفهوم واحد نیستند.
یکی از قابلیتهای مهم استفاده از REST، قابلیت لایهبندی و استفاده از قوانین حافظه نهان است. جیمز توضیح داده است که لایهبندی چه اهمیت بالایی داشته و چقدر بر معماری کلی پلتفرم اثرگذار است.
بیشتر پلتفرمها نیاز مبرم به اپلیکیشنهای سرور روی backend، متوازنساز بار (load balancer) و پروکسی معکوس بر روی front-end و قابلیت ارسال دادهها به شبکههای توزیع محتوا (CDN) دارند.
کار بر روی HTTP این نوع از ارتباطات را بین همهی این رابطها در طول مسیر ممکن میسازد. پایبند بودن به مشخصات اصلی HTTP فواید بسیار زیادی به دنبال داشته، و حتی امنیت API را نیز بهبود میدهد.
جیمز لایههای فراوان بین کلاینت و سرور را در این شکل نشان داده است. همانطور که او میگوید، خیلی چیزها باید ساخته شوند!
SOAP از HTTP استفاده کرده و بدون اینکه حتی لایه انتقال داده شبکه را در نظر بگیرد، ساختار خود را در بدنهی تقاضاها و پاسخها ایجاد میکند. از طرف دیگر، REST قراردادهای بین کلاینت و سرور، ابزارها، XML و هِدِرهای قراردادی را کنار گذاشته، و مفاهیم اساسی HTTP را جایگزین آنها میکند، چرا که بجای اینکه از verbهای HTTP برای تعامل با داده و از URIها برای رجوع به ساختار منابع سلسهمراتبی استفاده کند، ساختار داده در آن قابل انتخاب است.
تفاوت soap و rest
SOAP | REST | |
Verbهای HTTP | هرگز! | GET, PUT, POST, PATCHT DELETE |
قالب دادهها | XML | هرکدام که بخواهید |
قراردادهای بین کلاینت و سرور | همواره! | کی همچین چیزی لازم داره؟ |
سیستم نوع داده | بله | نوع داده چی هست؟! |
URLها | بسته به عملیات | منابع مشخص شده |
REST بطور کامل و صریح طراحی اِی پی آی (API) را دستخوش تغییر قرار داد و آن را از مدلسازی فعل و انفعالات، به مدلسازی برای دامنه دادهها تبدیل کرد. بخاطر کاملاً منبعگرا بودن اَپی تحت REST، نه لازم است بدانید، یا اهمیتی قائل شوید که برای دریافت اطلاعات مورد نظرتان چه پروسهای انجام میشود؛ نه لازم است اصلاً چیزی در مورد نوع پیادهسازی سرویس backend بدانید.
این موضوع تنها خبر خوش برای توسعهدهندگان نبود. بدلیل آنکه URL ها اطلاعات ثابتی میدهند، این اطلاعات براحتی قابل نگهداری در حافظه نهان هستند، و مهم نبودن نوع داده باعث، بخودی خود باعث ساده شدن کارهاست، و در نهایت از آنجا که REST بجای اینکه با نیازهای مصرفکننده کار داشته باشد، به دنبال مدلسازی دادههاست، باعث کوچکتر و سادهتر شدن اِی پی آی (API) میشود.
REST عالیست، و در همه جا باعث موفقیتهای بسیاری شده است، ولی مانند تمامی راهکارهای قبلی، REST نیز خالی از اشکال نیست. برای اینکه بتوانیم مستدلتر در مورد بعضی از نواقص آن صحبت کنیم، اجازه دهید سراغ مثالی ابتدایی برویم. فرض کنیم قصد داریم صفحه اول یک وبلاگ را بسازیم، که قرار است لیستی از پستهای وبلاگ ،به همراه نویسندهی آنها را نمایش دهد.
صفحه اصلی وبلاگ که عنوان و نویسنده هر پست را نمایش میدهد.
باید کدی بنویسیم که دادههای صفحه اصلی را از یک اَپی REST دریافت کنیم. با تعدادی تابع مربوط به منابعمان شروع میکنیم.
حالا، این توابع را مرتب میکنیم.
کارهایی که کد ما انجام میدهد به شرح زیر است:
-واکشی تمام پستها؛
-واکشی جزئیات هر پست؛
واکشی منابع مربوط به نویسنده برای هر پست؛
خوبی آنها این است که به سادگی قابل درک هستند، و مرزهای مفهومی و سازمانیافته خوبی برای هر یک از منابع ترسیم شده است. مشکل اینجاست که ما هشت درخواست به شبکه فرستادیم، که بسیاری از آنها بصورت سریالی رخ خواهند داد.
البته این ایراد به این مثال وارد است که اَپی ما میتوانست یک endpoint جداگانه بصورت /posts برای پستهای وبلاگ داشته باشد، ولی در واقع این بسیار ریز بینانه است. واقعیت این است که اغلب مواقع مجبور خواهید بود فراخوانیهای مختلفی به اِی پی آی (API) انجام دهید، که در نهایت برای تشکیل یک صفحه یا برنامه کاربردی به یکدیگر وابسته خواهند بود.
توسعه سرور و کلاینتهای تحت REST مسلماً بهتر از استفاده از چیزهایی است که قبل از آن وجود داشتند، یا حداقل اینکه امکان ارتکاب اشتباه در آن کمتر است، ولی از زمان مقاله فیلدینگ تا به امروز، اوضاع خیلی تفاوت کرده است. در آن زمان، کامپیوترها پلاستیکی و کرمرنگ بودند، ولی در حال حاضر آلومینیومی هستند! گذشته از شوخی، سال ۲۰۰۰ تقریبا اوج رشد کامپیوترهای شخصی بود.
هر سال قدرت پردازندهها دو برار میشد، و سرعت شبکهها با نرخ خیرهکننده ای در حال سریع شدن بودند. ضریب نفوذ اینترنت حدود ۴۵ درصد بود، و به نظر نمیرسید دیگر از آن بالاتر بروند.
پس از آن، در حدود سال ۲۰۰۸، کامپیوترهای موبایل به امری عادی تبدیل شدند، و با رشد موبایلها، عملاً یکشبه به اندازه یک دهه از نظر نسبت سرعت به کارایی عقب افتادیم. در سال ۲۰۱۷، نفوذ موبایل به حدود ۸۰% در آمریکا و در تمام جهان به بیش از ۵۰% رسیده، و وقت آن شده است که در بعضی از فرضیاتمان در مورد طراحی اَپی (API)، تجدید نظر کنیم.
تفاوت REST و GraphQL
در ادامه از دید یک توسعهدهنده برنامه کاربردی، بطور خاص برای موبایل به REST نگاهی خواهیم داشت. GraphQL و اِی پی آی (API) مبتنی بر آن، موضوع جدیدی نیستند، و مشکلات خارج از دسترسی توسعهدهندگان REST را برطرف نمیکنند. مهمترین کار GraphQL ، توانایی آن در حل سیستماتیک این مشکلات و با ایجاد سطحی از یکپارچهسازی است که جای دیگری در دسترس نیست. به عبارت دیگر، GraphQL راه حلی است مانند باطریهایی است که داخل جعبه دستگاههای مختلف میگذارند.
نویسندگان اصلی REST که شامل فیلدینگ هم میشود، در سال ۲۰۱۷ مقالهای منتشر کردند (Reflections on the REST Architectural Style and “Principled Design of the Modern Web Architecture”) که بازتاب دهنده دو دهه کار با REST و الگوهای دیگری است که از آن الهام گرفتهاند. این مقاله برای تمام افرادی که به طراحی اَپی (API) علاقهمندند، بسیار مختصر و مفید است.
بعد از این مقدمه تاریخی و مثال کاربرد، نگاهی داشته باشیم به سه ایراد بزرگ REST.
تفاوت رست (REST) و رست فول (RESTful)
این سوال بیشتر مثل یک پرسش آکادمیک است. اگر بخواهیم در یک جمله به این پرسش پاسخ دهیم باید بگوییم، REST مخفف Representational State Transfer میباشد و یک الگوی معماری برای ساخت وب سرویسها است. در عوض سرویس RESTful یکی از الگوهایی است که برای پیاده سازی این سبک معماری استفاده می شود.
این معماری مبتنی بر لایههای انتزاعی مختلف است. به بیان دیگر کامپوننتها هر لایه غیر قابل رویت هستند. به همین دلیل هم میتوان با استفاده از لایههای load-balance و یا لایههای پروکسی، امنیت و کارایی سیستم را بالاتر برد.
اما سرویس های RESTful بیش از وب سروریهایی که دستورات JSON و یا داکیومنتهای دیگری را مبادله میکنند، کارایی دارند.
زمانی که شما URI های خود را با استفاده از کدهای HTTP بعد از ریسورس قرار میدهید، در حقیقت API خود را قابل پیشبینی کرده اید. در این وضعیت توسعه دهندهها به تعاریف ریسورس شما دسترسی دارند و میتوانند پیشبینی کنند که API شما به چه شکل خواهد بود. البته منظور ما فهم و پیش بینی دادههای API است و ربطی به عملکرد آن ندارد.
اما حتی اگر شما نتوانید API خود را کاملا غیر قابل پیشبینی کنید، باز هم میتوانید هرگونه سرویس REST خود را با هایپرتکستها داکیومنت کنید. بر اساس مدل Fielding، قبل از اینکه یک سرویس RESTful باشد، به عنوان بخشی از API موظف است بخشی از دادههای خود را به صورت مدیا هایپرتکست ارائه کند.
بسیاری از سایتها اصول و شرایط REST را رعایت نمیکنند، اما باز هم به آنها REST میگویند. در حقیقت بسیاری از سایتهایی که ما فکر میکنیم REST هستند، در حقیقت از قواعد REST خارج شده اند و REST نیستند.
در مجموع وقتی کسی میپرسد آیا این APIای REST است، میخواهد بداند آیا شما یک API برای یک ماشین با کدهای HTTP دارید؟ اما اگر کسی از شما پرسید که آیا اپلیکیشن شما RESTful است، در حقیقت میخواهد بداند آیا معماری این API بر پایه REST است؟
به بیانی سادهتر منظور از REST در بیان عامیانه، نوع کد نویسی برنامه است. اما منظور از RESTful نوع گرایش معماری وب سرویس است.
آیا تفاوت REST و RESTful در عمل مهم است؟
مهم آن است که شما از معماری استفاده کنید که متناسب با نیازهایتان است و API شما را توسعه میدهد.
الگوی معماری REST مزایای بسیار زیادی دارد. ۱۸ سال پیش Fielding آن را برای وب طراحی نموده است. ولی بیشتر قواعدی که او در سر داشت، هنوز هم کارایی دارند. در سال ۲۰۰۰ خبری از اندروید و آیفون نبود. اما همان وقت هم Fielding احتیاجات اپلیکیشنهای آنلاین را درک کرده بود. ابزارهایی که امروزه استفاده میشوند نیز غالبا از REST توسعه یافته اند.
پس در عمل فرقی بین REST و Restful وجود ندارد.
ضعفهای REST
REST پرحرف است
بخاطر اینکه برای دریافت داده به اندازه کافی برای استفاده در یک اپلیکیشن، باید رفت و آمد زیادی بین کلاینت و سرور رخ دهد، سرویسهای REST حداقل اینکه «پرحرف» قلمداد میشوند. این فوران درخواست، اثرات مخربی بر کارایی، مخصوصا در موبایل دارد. اگر دوباره به مثالی که پیشتر زدیم رجوعع کنیم، حتی در بهترین حالت ممکن با یک گوشی موبایل جدید و اتصال سریع نسل۴، حداقل نیم ثانیه فقط تأخیر سربار خواهید داشت، پیش از اینکه حتی شروع به دریافت دادهها کنید.
۵۵میلیثانیه × ۸ درخواست = ۴۴۰میلیثانیه تأخیر
تأخیر | واکنش کاربر |
۰ – ۱۰۰ میلیثانیه | بلافاصله |
۱۰۰ – ۳۰۰ میلیثانیه | کمی کند |
۳۰۰ – ۱۰۰۰ میلیثانیه | صبر برای اتمام کار ماشین |
بیش از ۱ ثانیه | تغییر زمینه فکری |
بیش از ۱۰ ثانیه | بعداً مزاحمتون میشم… |
جدولی که واکنش کارابر به سطوح مختلف کارایی اپلیکیشن را نشان میدهد.
مشکل دیگر سرویسهای پرحرف، این است که در بسیاری موارد دریافت یک صفحه بزرگ، زمان کمتری از دریافت یک صفحه کوچک نیاز دارد. کم شدن کارایی درخواستهای کوچک دلایل زیادی دارد، از جمله شروع آهسته و کند پروتوکل TCP، فقدان فشردهسازی هِدِر و کارایی gzip. اگر در مورد این موضوع کنجکاو هستید، خواندن مقاله ایلیا گریگوریک با عنوان شبکه مرورگر پرسرعت را قویاً پیشنهاد میکنم. وبلاگ MaxCDN نیز مرور بسیار خوبی در این مورد انجام داده است.
این مشکل، در حقیقت ایراد فنی خود REST نیست، بلکه ایراد HTTP است، مخصوصا نسخه ۱ آن. HTTP/2 مشکل پرحرف بودن همه سبکهای اَپی (API) را برطرف نموده، و در کلاینتها مثل مرورگرها و SDKها بخوبی پشتیبانی میشود. متأسفانه، استفاده از آن در اَپیها محدود بوده است. در حال حاضر در سال ۲۰۱۷، بین ۱۰هزار وبسایت بزرگ دنیا، حدود ۲۰% آنها به HTTP/2 کوچ کردهاند.
در کمال تعجب، حتی Node.js پشتیبانی از HTTP/2 را تا نسخه ۸ خود ایجاد نکرده بود. اگر توانش را دارید، لطفا زیرساختهایتان را بروزرسانی کنید! در عین حال، نباید بیش از اندازه هم به این موضوع بپردازیم، چرا که این تنها بخشی از معادله است.
HTTP را که کنار بگذاریم، دلیل نهایی اهمیت پرحرف بودن، به خود موبایلها و بطور خاص به سیستم رادیویی آنها مربوط است. اصل موضوع این است که سیستم رادیویی برای موبایل، بیشترین مصرف باتری را دارد، بنابراین سیستم عامل موبایل هر زمان که بتواند این سیستم را از کار میاندازد. دوباره فعال کردن سیستم رادیویی نه تنها باعث مصرف زیاد باطری میشود، بلکه حتی زمان سربار بیشتری نیز به هر درخواست اضافه میکند.
TMI (واکشی بیش از اندازه REST )
اشکال بعدی که سرویسهای مبتنی بر REST دارند، این است که اطلاعات بسیار بیشتر از آنچه مورد نیاز است ارسال میکنند. در مثالی که بالاتر زدیم، ما فقط عنوان و نام نویسنده هر پست را نیاز داریم، که فقط حدود ۱۷% از دادههای برگشت داده شده را تشکیل میدهند، این یعنی ۶برابر زیان برای یک payload بسیار ساده. در یک اِی پی آی (API) واقعی، این حجم از سربار فوقالعاده زیاد است. به عنوان مثال، فروشگاههای اینترنتی، معمولاً یک محصول را با هزاران خط کد JSON نمایش میدهند. همانند مشکل «پرحرف بودن»، امروزه سرویسهای رست میتوانند با استفاده از fieldset های اسپارس و با ایجاد شروط برای شامل شدن یا نشدن قسمتهای دادهها، این مشکل را حل کنند. متاسفانه، پشتیبانی از این موضوع نادر، ناقص و برای سیستم حافظهنهان شبکه مشکلزا است.
شکل دهی و خودآزمایی REST
آخرین نکتهای که اَپیهای REST دچار فقدان آن هستند، مکانیزمی برای خودآزمایی است. بدون داشتن هیچگونه قراردادی در مورد نوع دادههای برگشتی، یا ساختار یک endpoint، هیچ راه قابل اعتمادی برای تولید مستندسازی، ایجاد شکلدهی و تعامل با دادهها وجود ندارد. کارکردن بر روی رست برای رفع این مشکل تا حدودی امکانپذیر است. پروژههایی که بطور کامل OpenAPI، OData و یا JSON API را پیادهسازی میکنند، اغلب تمیز، بخوبی مشخص شده و تا حد متناسبی دارای مستندسازی خوبی هستند، ولی backendهای اینچنینی نایابند.
حتی ابررسانه، به عنوان در دسترسترین گزینه، علیرغم اینکه برای دههها آن را در کنفرانسها بوق و کرنا کردهاند، هنوز هم به معمولا خوب پیادهسازی نمیشود.
REST یک شیوه خوب برای ساخت ای پی آی (API) هست یا خیر؟
بعبارتی، بله. در عین حال، برای طراحی و ساخت ای پی آی (API) چیزهای بسیار زیاد دیگری نیز باید عملیاتی شوند. مسئله بسیار فراتر از تنها یک سرور و کلاینت استفاده کننده از ای پی آی است. جیمز به ما توصیه میکند «فراتر از لپتاپمان فکر کنیم» و ۵ نکته اصلی را تاکید میکند:
- ما ابتدا باید مسئله تجاری را درک کنیم، و ترندهای فنی را بر اهداف کاری ارجحیت ندهیم.
- آموزش خودمان در مورد HTTP را بهبود داده، و وابستگی خود را به فریمورکها کاهش دهیم. HTTP را فراتر از مفهوم چرخه حیات CRUD بیاموزیم، و وقتی HTTP مسئلهای را حل کرده، برای حل دوباره آن به سراغ چیز دیگری نرویم.
- فریمورکی که در حال حاضر از آن استفاده میکنیم را تکامل دهیم.
- فراتر از لپتاپمان فکر کنیم: در طراحی ای پی آی (API) چیزهای بسیار زیادی برای عملیاتی شدن لازم هستند.
- وقتی شیوههای طراحی ای پی آی (API) را مقایسه میکنیم، آنها نه در برابر هم، بلکه در کنار هم قرار دهیم، تا ببینیم کدام شیوه برای کار ما مناسبتر است، یا کدام شیوهها در کنار هم پاسخگوی نیازهای ما خواهد بود.
GraphQL چیست؟
همانطور که قبلاً بررسی کردیم، GraphQL باعث ساخت ای پی آی (API) رساتری میشود. بدینصورت که به مصرفکننده اجازه میدهد منبع خاصی را در هنگام کوئری زدن انتخاب کند، که باعث افزایش توانمندی هر یک از فراخوانیهای ای پی آی میشود.
اگرچه این شیوه توسط GraphQL بصورت یک استاندارد درآمد، ولی جیمز خاطر نشان میکند که شیوههای پارامتری تعاملی اینچنینی در گذشته در لینکداین نیز مورد استفاده قرار گرفته بوده است.
GraphQL برای دادههای سلسلهمراتبی بسیار مناسب است. همچنین به خاطر داشتن قابلیتهایی مانند انتخاب سطح فیلد، مکانیزم خطایابی برای تایپها (strong typing) و مکانیزم خودآزمایی، GraphQL دارای خواص بسیار خوبی برای استفاده در ای پی آیهای front-end میباشد.
برخی از نکات منفی GraphQL شامل امنیت محدود endpoint ها و ابزار محدود عملیاتی میباشند. بعلاوه به دلیل اینکه GraphQL از POST استفاده میکند، همانند SOAP در آن نمیتوانید پاسخها را در حافظه نهان نگهداری کنید.
نداشتن قابلیت حافظه نهان و نبود انعطافپذیر، دلایلی هستند که میتوانند یک ای پی آی (API) را بسیار محدود کنند. این موضوع دلیلی است برای اینکه بسیاری از گروهها بطور کامل از GraphQL استفاده نمیکنند.
فواید | اشکالات |
پشتیبانی از دادههای سلسلهمراتبی | امنیت محدود endpointها |
انتخاب سطح فیلد | Tooling وجود دارد، ولی بصورت محدود |
مکانیزم خطایابی برای تایپها | تناقض در پیشنهادات |
مکانیزم خودآزمایی | نداشتن قابلیت حافظه نهان |
انعطافپذیر نبودن در تایپهای محتوایی |
gRPC چیست
gRPC که توسط گوگل کلاود توسعه داده شده است، یک فریموُرک متن باز RPC است. همانند CORBA، gRPC نیز با داشتن یک زبان توصیف رابط (IDL)، از یک protobuf (سریالکننده ساختمانهای داده) برای ایجاد یک backend توسط ژنراتورهای کد، استفاده میکند.
به گفتهی جیمز gRPC برای پیادهسازی درون یک سازمان بسیار مناسب است. و اینکه درصورت استفاده از gRPC، توسعه دادن کار در شبکه عمومی تر و دارای کلاینتهای بیشتر، کمی دشوارتر است.
ایرادات gRPC
برای جیمز، ایرادات gRPC در رابطه با تولیدکنندههای کد آن هستند، که مجبور خواهید بود آنها را بخوبی یاد بگیرید. اگر با زبانهای برنامهنویسی زیادی کار کرده باشید، تفاوتهای ظریفی بین تولیدکنندههای آنها وجود دارند که باید درکشان کنید.
همچنین مشابه GraphQL، gRPC نیز مشکلاتی در زمینه استفاده از حافظه نهان دارد.
فواید | اشکالات |
کارایی بالا، تاخیر کم | خطایابی محدود |
قالب پیام Protobuf | Tooling محدود در DevOps |
تولیدکننده کد (برای کلاینت و سرور) | تناقض در کدهای زبانهای مختلف |
ساخته شده بر اساس HTTP/2 | نداشتن قابلیت حافظه نهان |
انعطافپذیر نبودن در تایپهای محتوایی |
ابر رسانه: لینکها مهم هستند (Hypermedia)
اخیراً در وبلاگمان به بررسی فواید و مضرات استفاده از ابر رسانهها پرداختیم، و ابزاری که در این فرایند به ما کمک میکنند را معرفی کردیم. جیمز در ارائهی خود دلیل دیگری برای درنظر گرفتن ابررسانه مطرح کرد، که ارتباط زیادی با سیستمهای جدید ارتباطی دارد.
همانطور که در مورد ChatOps دیدیم، از ای پی آیها برای ایجاد ابزار جدید در مکالمات استفاده میشود. جیمز در این باره میگوید: «ای پی آیها هر کجا که لازم است کاری انجام شود، حاضر هستند.» صحبت او اساساً در مورد کانالهای پیامرسانی مانند Slack است، که جریان امور را به سمت و سوی جدیدی سوق میدهند.
امروزه افراد میتوانند تصمیمات مهم تجاری خود را در اپلیکیشنهای پیام رسان دلخواهشان اتخاذ کنند.
ابررسانه، در عین حفظ UX، میتواند به شخصیسازی محتوا برای این محیطهای جدید کمک کند. ای پی آیهای ابررسانه میتوانند با داشتن URL های منحصر به فرد برای هر بستهی پاسخی، به مشتریان بگویند چه امکاناتی و با چه شرایطی در اختیار آنها قرار دارند.
به عنوان مثال لینکهای ابر رسانه میتوانند بدون ایجاد تغییرات شگرف در سمت کلاینت، بلافاصله تغییرات لازم را در مورد دسترسیهای کاربران اعمال کنند. جیمز، ابررسانه را به عنوان راهی برای ای پی آیها برای پاسخگویی به پلتفرمهای نسل جدید و مشکلات جدیدی که ممکن است پدید آیند، میبیند.
Webhook ها و مسائل مرتبط با آن
اگر با webhookها آشنا باشید، احتمالاً Zapier و GitHub را میشناسید. Webhook موجود در GitHub وقتی توسعهدهندهای commit جدیدی ایجاد میکند، کاربران دیگر را نیز از این امر مطلع میکند. این موضوع نه تنها انقلابی در زمینه تولید نرمافزارها ایجاده کرده، بلکه بازار جدیدی در خطلوله مبتنی بر CD/CI نیز پدید میآورد.
بطور مشابه Zapier نیز REST hook مبتنی بر اشتراک خود را دارد که برای کاهش نمونهگیری (polling) طراحی شده است.
همچنین رویدادهایی (event) وجود دارند که توسط سرور ارسال شده، و به ما اجازه ارسال رویدادها به سمت کلاینت، ارسال پیامها، و غیره را میدهند. برای مثال، جیمز Kafka را مثال میزند، که یک راهکار ذخیرهسازی مبتنی بر واقعهنگاری است، و از همین شیوه برای برقراری ارتباط و ارسال پیامها به اشخاص موردنظر درون یک سازمان استفاده میکند.
Webhookها و شیوههای مشابه آن، برای معماریهای مبتنی بر وقایع مناسب به نظر میآیند. در این محیطها، برای رخ دادن یک رویداد خاص، عمل خاص دیگری باید صورت پذیرد.
شیوههای طراحی و ساخت API
نیاز به گفتن نیست که بین GraphQL، gRPC، REST و دیگر شیوههای طراحی و ساخت API راههای بسیار زیادی برای اینکه یک ای پی آی را سریعاً بسازیم راه بیاندازیم وجود دارد. ولی به این نکته نیز توجه کنیم که قابلیتهای مدیریتی، توسعه و تداوم یک سرویس میتوانند بر تصمیم ما تأثیرگذار باشند.
جیمز یادآور میشود که از نقطه نظر امنیتی، هر چه خودمان را درگیر مفاهیم بیشتری کنیم، مسائل و ایرادات بیشتری داریم که باید به آنها توجه کنیم!
آخرین و احتمالا مهمترین نکته اینکه شیوه طراحی ای پی آی شما باید متناسب با افراد توسعهدهنده که برای آنها سرویسی فراهم میکنید باشد. در واقع کاربرانتان برای شما مثل چراغ راهنما هستند!
نتیجهگیری
همهی انواع اِی پی آی (API) دارای ایراداتی هستند، ولی این گزاره درباره تمام الگوها صدق میکند. مقاله ساخت API ، قصد قضاوت در مورد یک پدیدهی اساسی که توسط غولهای نرمافزاری پایهگذاری شده را ندارد، بلکه تنها ارزیابی میانه رویی از هر یک از این الگوها، و اجرای «خالص» آنها از دید یک مشتری توسعهدهنده است.
امیدوارم بجای اینکه از مقاله ساخت API اینطور برداشت کنید که الگوهایی مثل REST یا RPC چقدر پراشکال هستند، این موضوع را از این مقاله استنتاج کنید که هر یک از آنها چه مصالحههایی انجام دادند، و همینطور امیدوارم بخشهایی از این مقاله را مورد توجه قرار دهید که چرا لازم است که یک سازمان مهندسی باید برای بهبود اَپیهای خود تلاش کند.
در حال حاضر استارتاپ اپی اِکو به عنوان اولین ای پی آی مارکت ایرانی، این فرصت رو برای شما به وجود آورده تا از طریق ساخت API و ارائه اون در سایت اپی اکو، علاوه بر درآمدزایی، به دیگر استارتاپ ها کمک کنید تا اپلیکیشن و نرم افزار خود را با هزینه کمتر و در زمان کوتاه تری، تولید نمایند.
ترجمه: توسط اَپی ِاکو اولین اِی پی آی مارکت ایرانی
دستت درد نکنه.
عالی بود. هرچند یه بخش هاییش واسم گنگ بود و دلیلش استفاده از کلمات تخصصی بود که نمیشناسم.
در کل عالی بابت حوصله ای که بخرج دادی.