یه دولوپر که سعی میکنه عمیق و کم هزینه باشه، از هرچیزی که بلدم مینویسم تا مطمئنشم درست یادش گرفتم.
رست VS گرافکیوال
اگه دولوپر هستید حتما درمورد استاندارد رست شنیدید و کار کردید، چندسالی هست ابزار جدیدی برای API معرفی شده به اسم گرافکیوال (GraphQL). اگه این مدت مشغول توسعه سرویسی بوده باشید ممکنه از خودتون پرسیده باشید آیا باید رست کنار بذارم و از گرافکیوال استفاده کنم؟ بذارید قبل این تصمیم اول ببینیم رست و گرافکیوال چی هستند.
رست (REST) چیست؟
رست (به انگلیسی REST) مخفف REpresentational State Transfer یکی از محبوبترین استانداردهای معماری API هست که روی فیلدینگ (Roy Fielding) در پایان نامه دکترای خودش معرفی کرد. این استاندارد تشویق میکنه لایه بکاند کاملا از فرانتاند جدا کنیم، این استاندارد یک سری قوانین وضع کرده، برای مثال:
- همه دیتاها باید با URL های یکتا دردسترس باشند.
- دیتاها نباید انکریپت بشن.
- از سشن استفاده نکنیم.
- فقط از پروتکل HTTP/HTTPS استفاده کنیم.
- برای عملیات CRUD از متدهای Get, Post, Put, Delete استفاده کنیم.
- بازگشت اندپوینتها باید Json, XML, atom, OData یا... باشد.
- و کلی قواعد دیگه که میتونید از اینجا به صورت کامل بخونید.
فرق REST و RESTful: درجریان باشید به این استاندارد میگن رست و در سرویسهایی که از این استاندارد استفاده کرده باشن میگن این سرویس رستفوله.
نکته دوم: در این پست منظور از کلاینت فرانتاند دولوپره نه کاربر نهایی.
گرافکیوال (GraphQL) چیست؟
گرافکیوال یک query language برای API هست. تو سال ۲۰۱۲ توسط فیسبوک ایجاد شد و درسال ۲۰۱۵ به صورت اپن سورس منتشر شد. این نه یک استاندارده نه یک وب سرویس. گرافکیوال واسط بین کوئری و دیتاسورسهای شماست. دیتاسورس شما میتونه دیتابیس یا وب سرویس باشه.
رست سالها به عنوان استاندارد وب سرویسها استفاده شد. از آنجایی که از پروتکل HTTP و متدهای استاندارد Get, Post, Put, Delete استفاده میکرد به شدت بین وب اپ ها محبوب شد. درنهایت بهتره اپلیکیشنها و پلتفرمها رو یه وب سرویس بنویسیم، چون به هر دیتایی نیاز پیدا کنیم با یک اندپوینت خاص بهش دسترسی داریم، ساخت اپ موبایل، وب، دسکتاپ و... به سادگی قابل اجراس، سرعت وب اپ بسیار زیاد میشه چون نیازی به رفرش صفحه نیست و با عوض شدن صفحه فقط اِلمانهای قبلی حذف و جدیدها را اضافه میکنیم، همینطور لود سرور خیلی پایین میاد چون تو هر صفحه نیاز نیست کل دیتاها از اول بگیریم و فقط اِلمانهای جدید صفحه رو از وب سرویس دریافت میکنیم، اینطوری هزینه سرور کاهش پیدا میکنه، پیچیدگی فنی توسعه کم میشه و...
نقطه ضعفهای REST
اگرچه سرویسهای رستفول بسیار موفق بودن ولی با فراگیر شدنشون ضعفهایی رو از خودشون نشون دادن.
۱- اندپوینتهای مختلف (ریکوئستهای مختلف)
در سرویسهای رستفول هر URL یک دیتای خاص رو نشون میده، پس برای صفحهای که اطلاعات کاربر، پستهای کاربر، کامنتها و... نمایش میده باید چند URL مختلف صدا کنیم تا تمام اطلاعات صفحه نمایش بدیم.
برای مثال یک وبلاگ درنظر بگیرید، شما یک سری مقاله دارید و تعدادی کامنت، پس در یک سرویس رستفول اندپوینتها باید به این صورت باشن:
GET /posts/<postId> - To fetch a particular post
GET /posts/<postId>/comments - To fetch all comments related to a post
GET /posts/<postId>/comments/<commentId> - To fetch a particular comment of a particular post
همینطور که میبینید هرچه تعداد اِلمانهای صفحه بیشتر میشه تعداد اندپوینتها افزایش پیدا میکنه، هرچه برنامه بزرگتر بشه توسعه و نگهداری این اندپوینتها سخت تر میشه. (البته هنوزم از روشهای سنتی مثل MVC بهتره)
۲- ارسال و دریافت دیتا
وقتی شما یک اندپویت صدا میکنید احتمالا مقداری اطلاعات توش هست که به دردتون نمیخوره و هیچوقت ازشون استفاده نمیکنید، همینطور گاهی بخاطر یک دیتای کوچیک مجبورید یه اندپوینت حجیم صدا کنید، این یه مشکل رایج تو رستفوله.
گاهی پیش میاد شما فقط به ۲-۳تا از دیتاها نیاز دارید ولی اندپوینت ۲۰-۳۰ تا دیتا برمیگردونه، اینطوری هم دیتای سنگینتری دریافت شده هم زمان پردازش بکاند بیشتر شده. گاهی هم به علت پراکندگی دیتا مجبورید چند ریکوئست ارسال کنید که اینم باعث افزایش زمان لود صفحه و ناراضی شدن کاربر میشه.
۳- ورژنهای مختلف API
وقتی شما دیتای یکی از اندپوینتها رو عوض میکنید مجبورید برای اینکه کاربرایی که (فرانتاند دولوپرها) از API شما استفاده کردند دچار مشکل نشن ورژن جدیدی برای API بدید و قبلی به حال خودش رها کنید تا دولوپرها بیان رو نسخه جدید.
این یعنی همیشه بعد آپدیت یک سری کاربر هنوز از نسخه قدیمی استفاده میکنند و اگر باگی پیدا بشه مجبورید همه ورژنها رو آپدیت کنید، برای همه ورژنها داکیومنت بنویسید، کدهای تکراری توی بکاند و...
۴- کلاینت در تاریکیه
تا زمانی که کلاینت (فرانتاند دولوپر) اندپوینت مربوطه صدا نکنه نمیدونه توی ریسپانس چه دیتایی هست، این یعنی همیشه جای اشتباه وجود داره و یک سری اندپوینت که هیچوقت استفاده نمیشن.
نقاط قوت GraphQL
گرافکیوال برای اولین بار توسط فیسبوک و برای رفع ضعفهای رست ایجاد شد.
۱- یک ریکوئست ارسال کن و تمام دیتاها دریافت کن
یک سرویس گرافکیوال تنها یک اندپوینت داره و کاربر میتونه کوئری موردنظرش رو بهش ارسال کنه و دیتای مورد نیازشو بگیره، بذارید با همون مثال وبلاگ توضیح بدیم:
{
findPost(id: <postId>) {
id
title
content
author
comments {
id
comment
commentedBy
}
}
}
همنیطور که میبینید تمام اطلاعات موردنیازمون تنها با یک ریکوئست دریافت کردیم، پس اگر به دیتای بیشتری نیاز داشته باشم فقط باید کوئری بزرگتری بنویسم.
۲-ـ Strongly Typed
گرافکیوال کاملا Strongly Typed است، این باعث میشه نیازی به داکیومنت نداشته باشید و کلاینت (فرانتاند دولوپر) بدونه بعد از ارسال کوئری چه نوع دیتایی دریافت میکنه.
۳- کلاینت همه چیز مشخص میکنه
گرافکیوال اجازه میده کلاینت مشخص کنه ریسپانس چه شکلی باشه و چه دیتایی توش وجود داشته باشه، این قابلیت احتمال دریافت اطلاعات بیاستفاده از بین میبره.
۴- تکامل API (ورژنینگ)
از اونجایی که تمام ریسپانسها طبق شِمایی (schema) که کلاینت ارسال کرده هست، اضافه کردن فیلد جدید به API مشکلی ایجاد نمیکنه، همچنین گرافکیوال برای حذف فیلدها قابلیتی داره به اسم `@deprecated` . بنابراین از ایجاد ورژنهای مختلف بینیاز میشیم.
۵- پروتکل انتقال دیتا
گرافکیوال میتونه روی هر پروتکلی مثل HTTP, HTTPS, WebSockets, TCP, UDP و... اجرا بشه.
نقاط ضعف گرافکیوال
خب، گرافکیوال عالیه، ولی اینم مثل بقیه چیزا نقاط ضعف خودش داره.
۱- سیستمی برای کش کردن وجود نداره
گرافکیوال برخلاف رستفول که از سیستم کش HTTP استفاده میکنه سیستم کش برای موبایل و بروزر نداره، اگرچه ابزارهایی مثل Relay سیستم کش در اختیار ما قرار میده ولی مثل رستفول بالغ و جا افتاده نیست.
۲- مانیتورینگ و گزارش خطاها
استاندارد رست برای گزارش خطاها از کدهای HTTP استفاده میکنه.این باعث میشه API برای برنامه نویسان بسیار ساده باشه، ولی گرافکیوال همه ریسپانسها با استاتوس کد ۲۰۰ ارسال میکنه، یک ریسپانس خطا با سرویس گرافکیوال با استاتوس کد ۲۰۰ به طور معمول به این شکله:
{
errors: [
{
message: 'Some error occurred'
}
]
}
این باعث میشه مدیریت و مانیتورینگ خطاها خیلی سخت بشه.
۳- نمایش ساختار و حمله به منابع
برخلاف سرویسهای رستفول در سرویسهای گرافکیوال برای نوشتن کوئری کاربر باید با دیتا استراکچر شما آشنا باشه، اگر شما API خودتون به شخص ثالثی بدید در واقع دیتا استراکچر خودتون بهش دادید، پس باید سرویس خیلی خوبی نوشته باشید که کلاینت نتونه join های سنگین بزنه تا سرویس شما زیر حمله Dos نره.
۴- امنیت - احراز هویت و مجوزها
در جامعه گرافکیوال هنوز درمود نحوه ایجاد امنیت برای سرورهای گرافکیوال به نقطه نظر واحدی نرسیدن. هنوز استانداردی برای ادغام احراز هویت و مجوزها در گرافکیوال وجود نداره. معمولا فقط برای لایه بیزینسی احراز هویت انجام میدیم، اما با توجه به ضعف شماره ۳ باید به کسانی که لاگین نکردن اجازه کوئری زدن بدیم؟ این سوال هنوز درمورد GraphQL جواب داده نشده.
۵- هزار و یک مشکل کوئری
در سرویسهای رستفول خیلی سادس یه اندپوینت مورد بررسی قرار بدیم، از SQL لاگ بگیریم و سرعتش بالا ببریم، اما درمورد گرافکیوال که طبیعتش دینامیکه خیلی سخته کوئریش به دست آورد و بهینه سازی کرد. گاهی ممکنه مجبور به حل هزار و یک مشکل معمول + مشکل Join های سنگین بخورید.
۶- اکوسیستم جوان
از لحاظ قدمت گرافکیوال بین بقیه استانداردها مثل بچهس، این یعنی تو کار ممکنه به هزار و یکجور مشکل جدید بخورید و کسی قبلا راه حل مشخصی پیدا نکرده و باید ساعتها وقت صرف پیدا کردن راه حل بکنید. پس برای استفاده از لایبرریها خیلی دقت کنید.
نتیجه
بذارید اینجوری شروع کنم که گرافکیوال یه ابزاره و رست یک الگوی معماری. میشه گفت که گرافکیوال میتونه جایگزین رست بشه، اما در این عصر از میکروسرویسها و ساخت API ها بسیار کوچک ما میتونیم هردوتاش داشته باشیم.
سرورهای گرافکیوال پرفورمنس رو به عنوان اولیت اصلی حفظ میکنند درحالی که سرویس رستفول سرویسمون رو قابل اطمینان نگه میداره.
گرافکیوال میتونه توسط سرویس رستفول در دسترس قرار بگیره، برای مثال روی اندپوینت `/graphql` قرار بگیره و کوئریها اجرا کنه درحالی که رست فول برای موراد خاص مورد استفاده قرار بگیره.
در مواردی بعضی پلتفرمها ممکنه سرویس گرافکیوال عملکرد بهتری داشته باشه و در بعضی مواقع رستفول. پس قبل اینکه بگید کدوم عملکرد بهتری داره، خوبه نیازهاتون بررسی کنید و طبق اون نتیجه بگیرید از کدوم استفاده کنید.
مطلبی دیگر از این انتشارات
اصول طراحی سرویس های RESTful
مطلبی دیگر از این انتشارات
بیوگرافی مارک بنیوف؛ برنامهنویسی که تاجر شد
مطلبی دیگر از این انتشارات
آشنایی با برخی از Component های کاربردی یونیتی - قسمت سوم