توی این پست می‌خوایم در مورد  GraphQL باهاتون صحبت کنیم. GraphQL یکی از روش‌های جدید طراحی API هست که با استفاده ازون می‌تونین API‌ های قابل توسعه‌تری رو به وجود بیارین. 

اما قبلش ببینیم اصلا API چیه و چه کاربردی داره!

API چیست؟

API یا وب‌سرویس زبانی هست برای تبادل امکانات وب‌سایت‌ها با همدیگه.
مثلا فرض کنین وب‌سایت شما امکان نمایش نرخ لحظه‌ای دلار و سکه رو داره.
برای این‌که بقیه‌‌ی سایت‌ها بتونن از این امکان استفاده کنن، باید به وبسایت شما متصل بشن.

برای این‌که هر کسی بتونه به این وبسایت وصل بشه، باید سرویسی رو طراحی کنین که این سرویس ایزوله با یک پروتکل امن مثل REST تونل امنی رو ایجاد کنه تا بقیه به این تونل وصل بشن و سرویسی رو ازش دریافت کنن.

پس می‌تونیم بگیم زبان مشترک این سایت‌ها با همدیگه وب‌سرویسه.

حالا وقتی در مورد طراحی API صحبت می‌کنیم، اولین چیزی که به ذهن می‌رسه، پروتکلیه به نام REST.

و حالا ببینیم REST چیست؟

REST استانداردیه برای بازیابی داده‌ها از سمت سرور، به طوری که برای دسترسی به داده‌ها از درخواست‌های http استفاده می‌شه.
این درخواست‌ها با متدهای مختلف PUT ،POST ،GET و GET ارسال می‌شن:

  • با درخواست HTTP GET، می‌تونین resource ای رو بخونین.
  • با درخواست HTTP POST، می‌تونین resource جدیدی رو ایجاد کنین. 
  • و با درخواست‌های HTTP PUT و DELETE  می‌تونین resource رو به روز کرده یا حذف کنین. 

زمانی که REST در سال 2000 توسعه پیدا کرد، برنامه‌های سمت client نسبتا ساده بودن و سرعت توسعه‌ی برنامه‌ها هم به اندازه‌ی امروز نبود، در نتیجه REST برای خیلی از برنامه‌‌ها مناسب بود.

REST مفاهیم مهمی رو در طراحی API به همه معرفی کرد - سرورهای بدون حالت و دسترسی ساختاری به resource ها.
اما امروزه API ‌ها پیچیده‌تر شدن، به داده‌ها وابستگی بیش‌تری دارن و تحت تأثیر عوامل زیر قرار گرفتن: 

  • با افزایش استفاده از موبایل نیاز به بارگذاری کارآمدتر داده‌ها احساس می‌شه. 
  • انواع مختلف client:

چون REST ساختار داده‌ی ثابتی رو برمی‌گردونه، اگه بخوایم برای طراحی API از REST استفاده کنیم که همه‌ی نیازهای سمت client رو هم برآورده کنه، باید رفت‌وآمد زیادی بین client و server انجام بشه.  

  • انتظارات برای توسعه‌ی سریع‌تر امکانات:

برای ایجاد تغییر در سمت client، باید سمت سرور رو هم به درستی تنظیم کنیم که این‌ کار سرعت توسعه‌ی محصول رو کم می‌کنه. 


REST سال‌هاست به عنوان استاندارد وب‌سرویس‌ها استفاده می‌شه.
اما اخیرا فیس‌بوک راه‌حلی برای کار با API‌ ها ارائه داده به نام GraphQL.

GraphQL جایگزین جدیدی برای معماری مبتنی بر REST به حساب میاد تا بتونه کاستی‌های REST رو برطرف کنه.
بر خلاف GraphQL ،REST از رویکرد ساختار داده‌های ثابت تبعیت نمی‌کنه.
این امکان رو ایجاد می‌کنه تا client دقیقا داده‌‌ی مورد نیازش رو درخواست کنه.

برای این منظور برنامه‌ی سمت server یک GraphQL schema داره:
جایی که تمام داده‌های موجود به صورت سلسله مراتبی و همراه با type ‌ها تعریف می‌شن.
برنامه‌ی سمت client با نوشتن query، دقیقا اون چیزی رو که نیاز داره از server درخواست می‌کنه.
server هم response مناسب رو براش ارسال می‌کنه.

خب حالا تو بخش‌های بعدی این پست با تعریف، مزایا و معایب GraphQl بیش‌تر آشنا می‌شین.

 GraphQL چیست؟

به طور کلی GraphQL زبان کوئری‌نویسی open source است که توسط فیس‌بوک معرفی شده، شرکتی که در توسعه‌ی نرم‌افزار مبتنی بر وب پیشتازه.  

این ابزار توسط فیس‌بوک در سال 2012 به عنوان جایگزین معماری REST توسعه داده شد و در سال 2015 به صورت open source در اختیار توسعه‌دهنده‌ها قرار گرفت!

این ابزار این امکان رو فراهم می‌کنه تا  client داده‌‌ای که دقیقا نیاز داره رو از server درخواست کنه و کنترل بیش‌تری روی این داده‌ی ارسالی داشته باشه.  

انجام این‌کار با REST یکم سخته.
چون server باید تعیین کنه برای هر resource در هر URL، چه داده‌ای موجوده و سمت client همیشه باید تمام اطلاعات موجود توی یک resource رو درخواست کنه، حتی اگه فقط بخشی از اون اطلاعات رو نیاز داشته باشه. به این مشکل overfeching گفته می‌شه.

برای رفع این مشکل GraphQL معرفی شد.
برای واکشی و دریافت داده‌ها با استفاده از GraphQL، نیازی به ارسال چندین درخواست REST به سمت server نیست.
کاربر می‌تونه یک درخواست‌ رو به سمت server ارسال کنه و server هم اطلاعات مورد نیاز رو در قالب یک response بهش برمی‌گردونه. 

بنابراین GraphQL زبان کوئری‌نویسی است که نحوه‌ی درخواست داده‌های موردنیاز رو توضیح می‌ده و عموما برای بارگذاری داده‌ها از server به client استفاده می‌شه.

سه ویژگی مهم GraphQL

  1. با استفاده از client ،GraphQL دقیقا می‌دونه به چه داده‌هایی نیاز داره.  
  2. جمع‌آوری داده‌ها از چند resource به راحتی انجام می‌گیره. 
  3. GraphQL برای توصیف داده‌‌ها از type system استفاده می‌کنه. 

عملیات GraphQL عبارت است از : query (برای خواندن)، mutation (برای نوشتن) یا subscription (خواندن مداوم). 

هر کدوم از این عملیات، فقط string ای هستن که باید با توجه به مشخصات زبان کوئری GraphQL ساخته بشن.
خوشبختانه، GraphQL همیشه در حال پیشرفته، بنابراین ممکنه در آینده‌ی نزدیک عملیات دیگه‌ای هم به این عملیات اضافه بشه.

GraphQL query چیست و چه ویژگی‌هایی دارد؟

GraphQL query یک رشته‌ی string هست که از client به سمت server ارسال می‌شه و سپس اطلاعات یا response مورد نیاز در قالب استاندارد JSON به client برگشت داده می‌شه. 

ویژگی‌های GraphQL query رو با ذکر مثال براتون توضیح می‌دیم.

نمونه query بالا ویژگی‌های زیر رو داره:

  • شکل داده رو تعریف می کنه:

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

  • ماهیت سلسله مراتبی داره:

GraphQL روابط بین ‌object ها رو دنبال می‌کنه و داده‌های درخواستی با ساختار گرافی تعریف شده مطابقت پیدا می‌کنن.

  • Strongly type است:

یکی از مزیت‌های این ساختار strongly type بودن اونه. یعنی هر سطح از type ،query (یا object) خاصی داره، type ها هم شامل field هایی هستن و هر field نوع خاصی از داده رو برمی‌گردونه.  

  • نیازی به ورژن‌بندی API نیست:

شکل داده‌های بازگشتی کاملا توسط query سمت client تعیین می‌شه و کاربر تنها داده‌ای که نیاز داره رو درخواست می‌کنه، بنابراین API توسعه داده شده با GraphQL بدون تغییر در ورژن، تکامل پیدا می‌کنه. وقتی field‌های جدیدی رو اضافه می‌کنین،  field های جدید به سمت سرور هم اضافه می‌شن و اگه بخواین field ای رو حذف کنین، در سمت server هم به راحتی حذف می‌شه که تأثیری در ورژن API نمیذاره. از اون‌جایی که ساختار گرافی GraphQL با تغییرات به خوبی سازگاره و سطح بالایی از انعطاف‌پذیری رو ارائه می‌کنه، نیازی به ورژن‌بندی API نیست. 

مزایا و معایب استفاده از GraphQL

مزایای استفاده از GraphQL چیست؟

GraphQL مزایایی داره که با نیازهای شما برای توسعه‌ی یک API سازگاره: 

مناسب سیستم‌های پیچیده و microservice‌ ها

GraphQL می‌تونه چند سیستم رو با هم ادغام کنه و با این کار پیچیدگی اون‌ها کم‌تر به نظر می‌رسه.
سرور GraphQL وظیفه‌ی واکشی داده‌ها از سیستم‌های موجود رو برعهده داره و اون‌ها رو به شکل GraphQL response بسته‌بندی می‌کنه.

فرض کنین یک برنامه‌ی backend ای یکپارچه می‌خواد به معماری microservice مهاجرت کنه.
حالا GraphQL برای این‌که بتونه ارتباط بین microservice ها رو مدیریت کنه، اون‌ها رو در یک GraphQL schema ادغام می‌کنه.
از اون‌جایی که هر schema ،microservice‌ خودش رو تعریف می‌کنه و endpoint خودش رو هم داره، یک GraphQL API gateway همه‌ی schema ها رو در یک schema‌ عمومی، ادغام می‌کنه.

واکشی داده‌ها با یک API call

تفاوت اصلی بین GraphQL و REST اینه که دومی endpoint محوره.
یعنی توسعه‌دهنده برای جمع‌آوری تمام داده‌های موردنیاز، باید چندین endpoint رو با هم ترکیب کنه.
در حالی که در GraphQL فقط یک endpoint داریم و توسعه‌دهنده می‌تونه فقط با یک API call یا ارسال یک query، داده‌های مورد نیازش رو درخواست کنه.  

جلوگیری از واکشی بیش از حد داده

response‌های REST‌ داده‌های زیادی داره که ممکنه مورد نیاز کاربر نباشه، ولی GraphQL با واکشی دقیق داده‌ها در یک درخواست، این مشکل رو حل می‌کنه و هیچ داده‌ی اضافی در یک response وجود نداره.
در نتیجه توسعه‌دهنده با یک درخواست دقیقا به اطلاعات مورد نیازش دست پیدا می‌کنه.

تکامل API بدون versioning

در REST، به طور معمول چندین version از API ارائه می‌شه، اما GraphQL با قابلیت deprecate کردن فیلدها ما رو از ایجاد version های مختلف بی‌نیاز می‌کنه.
این field ها بدون تأثیرگذاری روی query های موجود، از schema حذف می‌شن.

پیام خطای تفصیلی

در REST، برای بررسی وضعیت یک response، هدرهای http رو بررسی می‌کنیم و بر اساس اون تشخیص می‌دیم که چه مشکلی رخ داده و چطوری اون مشکل رو حل کنیم.
در GraphQL اگر خطایی هنگام پردازش query ها وجود داشته باشه، backend‌ امکان خطای تفصیلی رو ارائه می‌ده که شامل resolver ها و محل دقیق خطا در query می‌شه.

مجوزها

در REST، هر view باید بتونه در شرایط مختلف تشخیص بده چه چیزهایی رو نشون بده و چه چیزهایی رو در معرض نمایش قرار نده که انجام این کار، ساده‌ نیست. اگر یک query شامل اطلاعات private باشه، معماری REST حتی بخش‌های public داده های درخواست شده رو هم نمایش نمی‌ده، اما با ایجاد GraphQL schema، می‌تونین انتخاب کنین کدوم توابع نشون داده بشن و چطوری کار کنن.

امکان Validation  و  type checking در GraphQL

توسعه‌دهنده می‌تونه داده‌های مورد نیاز رو در فرمت مناسب درخواست کنه و به راحتی field های جدیدی رو از طریق GraphQL IDE به query موجود اضافه کنه و نیازی به اعتبارسنجی فرمت داده‌ها نیست. 

تولید خودکار مستندات API

GraphQL API شامل کد، field ،type یا query می‌شه و همگام با تغییرات GraphQL ،API مستندات API رو هم نگه می‌داره.
این‌کار برای توسعه‌دهنده‌ها مفیده چون می‌تونن زمان کم‌تری رو صرف مستند‌سازی یک API کنن.

یک عملیات اضافی

همون‌طور که در ابتدای این پست اشاره کردیم، در REST عملیات CRUD با درخواست‌های http زیر انجام می‌گیره: 

  • CREATE:  ایجاد رکوردهای جدید با  دستور POST.
  • READ:  بازیابی داده‌ها بر اساس پارامترهای ورودی با دستور GET. 
  • UPDATE:  تغییر رکوردها با دستور PUT.
  • DELETE: و حذف داده‌های مشخص شده با دستور DELETE. 

با استفاده از این مفاهیم، GraphQL عملیات جدیدی رو معرفی می‌کنه به نام subscription:
که به client اجازه می‌ده پیام‌های بلادرنگی رو از server دریافت کنه.
هنگام دریافت یک پیام، اضافه شدن یک داده یا comment، می‌تونین برای ارسال خودکار notification به client از GraphQL subscription استفاده کنین.

‌ Prototyping سریع برنامه

برای تهیه‌ی prototype اولیه، استفاده از عملیات CRUD خیلی وقت‌گیره.
GraphQL با ارائه‌ی یک API endpoint که به عنوان یک data proxy بین UI و data storage عمل می‌کنه، این فرآیند رو سرعت می‌بخشه.

حالا ببینیم چه نقاط ضعفی داره.

نقاط ضعف استفاده از GraphQL چیست؟

GraphQL خیلی عالیه ولی مثل هر سرویس دیگه نقاط ضعف خودش رو داره. در ادامه به چند تا از مهم‌ترین معایبش اشاره می‌کنیم: 

بروز مشکلات عملکردی در صورت وجود query های پیچیده:

client می‌تونه دقیقا همون چیزی رو که لازم داره درخواست کنه.
اما اگه client یک‌مرتبه field‌های تو در تو رو درخواست کنه، ممکنه با مشکلات عملکردی مواجه بشه.
به همین دلیل می‌تونین برای query های پیچیده از REST API استفاده کنین: با استفاده از چند endpoint و query‌های خاص و دقیق تنظیم شده، داده‌ها رو بازیابی کنین. 

در صورت استفاده از GraphQL، می‌تونین برای متوقف کردن درخواست‌های ناکارآمد از مکانیزم‌های rate-limiting استفاده کنین، یعنی:‌
حداکثر عمق query، وزن‌دهی به پیچیدگی query،
persistent query ها  و جلوگیری از recursion.

پیچیدگی Web caching:

امکان caching با نگه‌داری مداوم اطلاعات برای client ها، باعث کاهش میزان ترافیک به‌ یک server می‌شه.

یک REST API با داشتن چند endpoint، می‌تونه تنظیمات caching رو انجام بده.
اما امکان caching در GraphQL به دلیل وجود query های مختلف و داشتن تنها یک endpoint بسیار دشواره.     

بر خلاف REST که از HTTP caching استفاده می‌کنه، GraphQL مبتنی بر روش‌های HTTP caching نیست.
(این روش‌ها امکان ذخیره‌سازی محتوای یک درخواست رو فراهم می‌کنن)
GraphQL cashing فقط با client های Apollo یا Relay که دارای مکانیزم‌ cashing هستن، قابل پیاده‌سازیه.

کاربرد بیش‌تر GraphQL در برنامه‌های بزرگ:

استفاده از GraphQL برای چندین microservice راه‌حل مناسبیه.
اما برای یک برنامه‌‌‌ی ساده، بهتره از معماری REST استفاده کنین.
برای برنامه‌های مبتنی بر resource، استفاده از  REST می‌تونه روش مناسبی باشه و دیگه نیازی به query های انعطاف‌پذیر GraphQL نیست.

آپلود کردن فایل:

از اون‌جایی که GraphQL چیزی به نام فایل نمی‌شناسه، مفهوم بارگذاری فایل هم براش مشخص نیست، ولی در REST این محدودیت وجود نداره، چون می‌تونین هر محتوایی که می‌خواین رو POST یا PUT کنین.  

برای بارگذاری فایل‌ها با استفاده از GraphQL، گزینه‌های مختلفی وجود داره: 

  • استفاده از رمزگذاری Base64. اما رمزگذاری/رمزگشایی، درخواست‌ها رو حجیم‌تر و هزینه‌برتر می‌کنه. 
  • ساخت API endpoint جداگانه.
  • استفاده از كتابخانه‌هایی مثل Apollo برای تعیین مشخصات چند درخواست. 

زمان زیاد لازم برای درک schema:

برای استفاده از GraphQL، باید زبان تعریف schema رو به خوبی یاد داشته باشین.
بنابراین نوشتن عملیات مناسب، درک و پیاده‌سازی یک Graph query ساده ممکنه زمان زیادی از شما بگیره.
از اون‌جایی که در یک پروژه ممکنه همیشه زمان کافی و منابع لازم برای آشنایی با GraphQL وجود نداشته باشه، کار کردن با REST می‌تونه راحت‌تر باشه.

نتیجه‌گیری 

در این پست سکو بررسی کردیم که GraphQL واقعاً دنیای API ها رو متحول کرده و خوبه که در موردش اطلاعات بیش‌تری کسب کنین.  

GraphQL ابزاری قدرتمنده و برای انتخابش دلایل زیادی وجود داره.
البته شاید هنوز GraphQL جایگزین کامل REST نباشه، چون اولی صرفا یک ابزاره در حالی که دومی یک الگوی معماری به حساب می‌آد، اما موقعیت‌های منحصر به فردی وجود داره که ممکنه در این موقعیت‌ها یکی از این دو تا برای استفاده مناسب‌تر باشن. 

در شرایطی که یک درخواست‌کننده به داده‌ای با یک قالب خاصی نیاز داره، فرمت‌ داده و روابط بین اون‌ها از اهمیت حیاتی برخوردار هستن.
در چنین مواردی، هیچ راه‌حل دیگه‌ای به جز GraphQL قابل استفاده نیست تا بتونه این سطح از ارتباط و پیوستگی بین داده‌ها رو فراهم کنه.  

بنابراین پیشنهاد می‌کنم که یادگیری کاملش رو آغاز کنین چون ممکنه در آینده‌ای نزدیک این فناوری جایگزین REST بشه. 

منابع:

Why GraphQL: Advantages and Disadvantages
?What is GraphQL
GraphQL: Core Features, Architecture, Pros and Cons