مقدمه
با عرض سلام خسته نباشید خدمت دوستان عزیز قراره داخل این مقاله یک نگاهی به تکنولوژی Graphql ساخته تیم محبوب فیس بوک بپردازیم . خب در وحله اول ببینم اصلا GraphQl چه مشکلی رو از ما کمتر میکنه پس در ادامه با من همراه باشید . اگر به تاریخچه تکامل ارتباط Api یک نگاهی بکنیم میبینم نام های اشنا به چشم ما میخوره SOAP گرفته تا REST و GRPC و در نهایت GRAPHQL که هر کدوم یک سری مشکلات داشتن و دیگری سعی در پوشش اونو داشته از سال ۲۰۱۵ بود که غول فیس بوک تصمیم گرفت برای اینکه از اطلاعات دیتا در شبکه خودش بکاهه و حجم کمتر کنه از Rest به graphql کوچ کنه .
تکنولوژی GraphQl که بود چه کرد
اگر تا به حال rest کار کرده باشید میبینید برای هر درخواست باید یک endpoint مشخص تعریف کرد برای مثال برای گرفتن اطلاعات یک کاربر باید به endpoint با متد get درخواست بزنید و اطلاعات کاربر بگیرید خب این وسط اکثرا براتون اتفاق افتاده که برای یک صفحه شاید مقادیر نام کاربری تاریخ تولد عکس و ... رو نیاز نداشتید ولی چون از سمت بک اند کل اطلاعات کاربر با تمامی مقادیر به شما داده می شد مجبور بودید این دیتا هم داشته باشید . ( خب پس اینجا حتما میگید چ خوب می شد یک تکنولوژی بود بهش میگفتی برای این صفحه این دیتا این دیتا رو میخام و دیتا لازمه رو بهمون میداد ) خب اگر به جمله اول من دقت کرده باشید میبینید که وسط پروژه هستید پروژه متوسط رو به بالا میبینید نزدیک ۳۰۰ تا endpoint تعریف کردید و حالا بگرد دنبال پرتغال فروش :) پس اینجا هم مشکل داریم تعداد endpoint زیاد یک مشکل دیگه که داریم سر موضوع اینه تا حالا شده احتمالا شما بخواین مثلا دیتا ها کاربرتون از دیتابیس مونگو بگیرید داده های پست و مقاله تون از PostgreSQL خب این وسط باید سه ساعت بشینید دیزاین پترن repository pattern رو پیاده سازی کنید یک کلاس Storage تعریف کنید بعد نوع اتصال رو مشخص کنید و Model تون از کلاس ارث ببره و کلی ماجراهای دیگه خب پس اینجا هم یک دردسر داشتیم .
خب یک خبر خوشحال کننده تمامی این مشکلات رو graphql برطرف کرده و شما میتونید راحت از این ابزار استفاده کنید و این مشکلات از بین ببرید
اینم بگم graphql اینقدر هم علیه سلام نیست داخل پروژه های بزرگ برای کش کردن دیتا مشکل میخوریم یا خیلی ها سر تو در تو شدن graph هاش گیج میشن و میگن سخته درک کردنش که برای این دو مشکل من راه حل دارم :)
شرح موضوع :
فرض کنید میخواهیم اطلاعات کاربرها رو بگیریم و همچنین اطلاعات پست های یک کاربر پس با من همراه باشید برای کار کردن با GQL
مراحل نصب ( در نود جی اس گفته شده در فریم ورک Express که میتونید داخل تمامی زبان های کار میکنید از پکیج های که هست مربوط به GQL هست استفاده کنید )
شما نیاز به دو تا پکیج دارید اولی express-graphql هستش که با دستور زیر میتونید نصبش کنید .
npm i express-graphql --save
دومین پکیج با تعریف Schema ازش استفاده میکنیم graphql-tools هستش که به شکل زیر میتونید نصبش کنید .
npm i @graphql-tools/schema --save
وقتی این دو تا مورد نصب کردید باید typedef های خودمون رو بنویسیم پس به شکل زیر عمل میکنیم .
اولین مورد تعریف typeQuery هستش که الزامی هستش و به ما کمک میکنه Query های که از سمت GQL میخایم تعریف کنیم ( یک جوری همون چی میخایم از سرور میشه مثلا لیست کاربرها یا اینکه لیست پست ها و ...)
خب همون طور در کد مشاهده میکنید اینجا سه تا Query تعریف کردم اولیش users که لیست کاربرها رو میگیره برامون دومی posts لیست پست ها رو میگیره سومی user که ایدی بهش میدیم یک کاربر برمیگردونه
نکته : احتمالا به خودتون بگید چرا هر کدوم تایپ دارن این بحث ها GQL از تعریف تایپ استفاده میکنه یعنی میتونید برای هر مقادیرتون تایپ تعریف کنید به عنوان مثال برای برگشت لیست کاربران [User] اینجور میگیم که ارایه از تایپ User برامون برگشت داده میشه
خب بریم سراغ تعریف تایپ User , Post
خب همون طور داخل کد مشخص هستش ما اومدیم یک سری تایپ تعریف کردیم به عنوان مثال تایپ User شامل مقادیر id,username,email,name,posts خواهد بود .
نکته بعدی : احتمالا برای خودتون سوال شده باشه چرا داخل تایپ User اومدیم posts قرار دادیم ما میتونیم به کمک GQL ارتباطات بین entity های خودمون برقرار کنیم :)
کل چیزای نوشتیم رو باید داخل یک متغیر به اسم typeDefs قرار بدیم به این شکل .
خب بریم برای تعریف Revolvers :
به ما کمک میکنه وقتی Query users صدا زده شد مثلا دیتا چطوری برگشت داده بشن یا از چه Storage دیتا ها گرفته بشه یا اینکه ارتباطات که وجود داره رو مشخص کنیم و دیتاشونو بگیریم .
پس داریم:
دوباره مثل typeDefs ما به اسم اشنا میخوریم به اسم Query که میگیم وقتی Query users صدا زده شد کل دیتا users به من برگشت داده بشه .
نکته میتونیم در اینجا گرفتن دیتا رو از هر model یا storage داریم بگیریم
یک قسمت هم هست به اسم User میگیم داخل Query User یک Query به اسم posts هست که یک ایدی کاربر دریافت میکنه و فیلتر میکنیم دیتا پست رو براساس userId ثبت شده داخل ساختار داده posts و پس این چنین میتونیم ارتباط بین Query User و Post هم تعریف کنیم .
سپس باید به کمک graphql-tools schema مدنظرمونو بسازیم .
داخل پکیجش یک متد وجود داره به اسم makeExecutableSchema که مقدار typeDefs و resolvers بهش پاس میدیم تا schema ما ساخته بشه و بتونیم ازش استفاده کنیم سمت client
چون که الان نمیخام بحث گرفتن دیتا سمت کلاینت داخل ری اکت یا ویو و ... توضیح بدم از GUI خود graphql استفاده میکنیم ایشالله در ادامه از سری از مقالات GQL در مورد قسمت فرانت توضیح خواهم داد .
پس داخل express به کمک use یک endpoint تعریف میکنیم به اسم graphql/ که وقتی اونو صدا بزنیم یک GUI برامون باز میشه . به این شکل :
که میتونیم دیتاهای لازم داریم به صورت Query بنویسیم و به صورت graph بهمون تحویل میده .
الان من میخام کلیه اطلاعات کاربرهامو بگیرم + لیست پست های کاربر پس مینویسم به این شکل
خب همون طور که دیدین من لیست کاربرهامو گرفتم اما اینجا گفتم id name email و از posts هم id title احتیاج دارم و خروجی من به این شکل خواهد بود .
خب همون طور میبینید من دیتامو فیلتر کردم و چیزایی که میخاستمو گرفتم و دیتاهای اضافی رو نگرفتم و به این شکل میتونیم دیتاهای خودمون فیلتر سازی کنیم .
بریم سراغ تعریف یک Mutation که میتونیم روی Query داریم عملیات Delete update create رو داشته باشیم .
پس داخل متغیر typeDefs یک type دیگه به اسم Mutation مینویسم و سپس داخلش به این شکل به اصطلاح یک تابع بهش پاس میدیم و مقادیر ورودی رو مشخص میکنیم سپس چیزی که برمیگردونه رو مشخص میکنیم .
و بعد داخل revolvers مون میایم یک Mutation تعریف میکنیم به این شکل
یک تابع به هم اسم تابع که داخل typedefs تعریف کردیم مینویسیم و میگیم مقدار اول که rootValue که کارش نداریم پس ignore میکنیم سپس در مقدار دوم تابع مقادیر میگیریم ( چون من یک دیتا استاتیک داشتم و نمیخاستم زیاد درگیر دیتابیس نشم یک ارایه تعریف کردم و اومدم مقادیر push کردم به model که داشتم و دیتا ورودی رو برگشت دادم ) شما میتونیم داخل اینجا عملیات CRUD خودتون سمت model خودتون و دیتابیس تون داشته باشید .
سپس داخل کلاینت خودمون میایم به این شکل دیتاهامون رو وارد میکنیم و مقادیر بازگشتی هم مشخص میکنیم .
که اینجا به اسم تابع که داخل resolvers تعریف کردیم صدا میزنیم و مقادیر ورودی رو مشخص میکنیم و مقادیر بازگشتی هم مشخص میکنیم چی هارو میخایم
خروجی به شکل تصویر بالاست
نکته برای کش کردن دیتا من از پکیج apollo graphql استفاده میکنیم و همیشه نیازمو برطرف کرده و مشکل کشینگ دیتا رو راستش نداشتم تا به حال
نکته بعدی : اینکه برای اینکه اکثرا یکی از عیب های که graphql داره رو میگن تودرتو شدن graph ها هستش راستش من اینو مزیت میدونم چرا چون شما بدون هیچ کدی میتونیم ارتباطات یک به یک و یک به چند خودتون رو درست کنید و تحویل به خروجی بدید و همچنین سرعت بالاتری هم نسبت به rest در result داره که خودش یک مزیت حساب میشه
من خودم حدود یک سال نیم هستش دارم از GQL استفاده میکنیم خیلی ام راضیم هم سمت فرانت هم بک کلا خوشم میاد ازش و ازش بدی تا به حال ندیدم اگر دوستان سوالی نظری چیزی داشتن میتونن زیر همین پست بپرسن
پس لایک کامنت یادتون نره :) حمایت شما باعث دلگرمی من خواهد بود برای ادامه این سری از اموزش ها
آموزش بعدی :) رو شما میتونید تعیین کنید که چی باشه .