ساخت API مدرن با GraphQL، بخش دوم

در بخش قبل گرف‌کیوال رو معرفی کردیم و گفتیم که چه مشکلاتی رو حل می‌کنه، در این بخش با استفاده از Django و Graphene یک ای‌پی‌آی گرف‌کیوال خواهیم ساخت. البته بیشتر توجه روی بخش گرف‌کیوال خواهد بود و فرض می‌کنیم شما با Django آشنایی دارید.

این پروژه در این آدرس در دسترس عموم قرار دارد.


راه‌اندازی ای‌پی‌آی گرف‌کیوال

نصب graphene

ابتدا با استفاده از دستور زیر کتاب‌خانه‌ی graphene-django را نصب می‌کنیم:

pip install graphene-django

و در فایل settings.py تغییرات زیر را اعمال می‌کنیم:

  • در قسمت INSTALLED_APPS اپ graphene_django را اضافه کردیم.
  • در انتهای فایل، خط‌های زیر را اضافه می‌کنیم. این چند خط به گرافین می‌گه از کجا ساختار اسکیما رو بخونه.

تعریف اسکیما

گرافین در پکیج graphql_api.schema دنبال متغیر schema خواهد گشت، مشابه ایمپورت‌ها در پایتون. بنابر این پوشه‌ی graphql_api/schema رو ایجاد می‌کنیم و توش چند تا فایل زیر رو می‌سازیم:

تا به اینجا یه کوئری خیلی ساده تعریف کردیم. توی این کوئری تعریف کردیم که یه فیلد وجود داره به نام hello که تایپش String هستش، بعدش هم گفتیم که هر وقت کسی مقدار این فیلد رو خواست، در جواب رشته‌ی world رو برگردونه.

روش کار graphene به این صورت است که برای هر فیلدی که تعریف می‌کنیم به دنبال تابعی می‌گردد که با resolve شروع شود و در ادامه نام فیلد بیاید. به طور مثال برای فیلد hello به دنبال تابع resolve_hello می‌گردد و هنگامی که بخواهد کوئری گرف‌کیوال را اجرا کند و مقدار hello را بداند این تابع را صدا می‌کند.

افزودن graphql به routing

حالا لازمه که یه url تعریف کنیم تا بتونیم به ای‌پی‌ای گرف‌کیوال دسترسی داشته باشیم. فایل urls رو به شکل زیر تغییر می‌دیم تا ای‌پی‌آی graphql در آدرس /gaphql/ دیده بشه:

سرور رو اجرا می‌کنیم و به آدرس localhost:8000/graphql می‌ریم تا ببینیم ای‌پی‌آی چطور کار می‌کنه. توی قسمت سمت چپ کوئری graphql رو که می‌خوایم اجرا بشه رو می‌نویسیم و جواب سرور رو دریافت می‌کنیم.

سمت راست: جواب سرور، سمت چپ: درخواست
سمت راست: جواب سرور، سمت چپ: درخواست


برای اینکه اسکیمای گرف‌کیوال رو به صورت فایل داشته باشیم دستور زیر رو اجرا می‌کنیم:

python manage.py graphql_schema --out schema.graphql

و فایل schema.graphql ایجاد می‌شه، و فایل اسکیمای ساخته شده رو در اختیار تیم‌های دیگه قرار می‌دیم که قراره از این ای‌پی‌ای استفاده کنند.

اسکیمای hello world
اسکیمای hello world


تعریف ای‌پی‌آی مربوط به مدل

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

تعریف مدل‌های Post و Comment

دو تا مدل Post و Comment را به این شکل تعریف می‌کنیم:

مدل پست و کامنت
مدل پست و کامنت

تعریف تایپ Post

حالا می‌خوایم Post رو به گرف‌کیوال اضافه کنیم، برای این کار لازمه دو تا کار انجام بشه:

  • تعریف تایپ متناظر با مدل Post.
  • تعریف کوئری که بتونیم یک پست رو با آی‌دی بگیریم.
تعریف تایپ متناظر با مدل post
تعریف تایپ متناظر با مدل post

این چند خط داره می‌گه که متناظر مدل Post یک تایپ گرف‌کیوال وجود داره و فیلد‌های id و title و body یک پست قابل کوئری کردن هستند. گرفین به صورت اتوماتیک خودش تایپ‌های مدل رو بررسی می‌کنه و تایپ‌های متناظر رو در گرف‌کیوال برای این فیلد‌ها تعیین می‌کنه.

حالا باید به کوئری اصلی یه فیلد post اضافه کنیم که id رو ورودی می‌گیره و در صورتی که پست متناظر با این آی‌دی وجود داشت، مقدار پست رو بر می‌گردونه. برای این کار یه کلاس جدید تعریف می‌کنیم:

تعریف کوئری مربوط به پست
تعریف کوئری مربوط به پست

در این چند خط یک کلاس PostQuery تعریف کرده‌ایم. در این کلاس گفتیم که یک فیلد پست وجود دارد که یک آرگیومنت از نوع ID ورودی می‌گیرد و در خروجی PostType بر می‌گرداند (تایپ گرف‌کیوال متناظر با مدل Post) و سپس تابع resolve_post را تعریف کرده‌ایم این تابع از ورودی id رو می‌خونه و با استفاده از امکانات مدل جنگو، پست رو پیدا می‌کنه و بر می‌گردونه.

حالا باید به کوئری اصل اضافه بشه:

اضافه کردن کوئری مربوط به پست به کوئری اصلی
اضافه کردن کوئری مربوط به پست به کوئری اصلی

با اضافه کردن PostQuery به کلاس‌های پدر Query اصلی، فیلد post به Query اصلی اضافه می‌شود.

حال ای‌پی‌آی رو تست می‌کنیم:

در این حالت اسکیمای جدید ما به این شکل می‌باشد:

یه تایپ جدید به نام PostType اضافه شده است، هم‌چنین فیلد post به کوئری اصلی اضافه شده است.

تعریف رابطه‌ها

تا به اینجای کار یک تایپ جدید با فیلد‌های ساده ایجاد کردیم، اما در بسیاری از موارد فیلدهای پیچیده نیاز داریم. به طور مثال یک پست، فیلد نویسنده دارد. هم‌چنین لازم است بتوانیم لیست کامنت‌های مربوط به پست را نیز بگیریم. در ادامه این نوع فیلد‌ها را بررسی می‌کنیم.

ابتدا دو تایپ گرف‌کیوال برای یوزر و کامنت تعریف می‌کنیم:

حال نویسنده و لیست کامنت‌ها رو به پست اضافه می‌کنیم:

مقدار self در تابع resolve_comments یک پست است که از مدل Post ایجاد شده است (در این مثال دقیقا همان پستی است که از تابع resolve_post در PostQuery برگردانده شده است). بنابر این می‌توانیم از تمام امکاناتی که مدل جنگو در اختیار ما قرار می‌دهد استفاده کنیم، مثلا لیست کامنت‌ها رو بگیریم و حتی در صورت نیاز، فیلتر کنیم.

حالا می‌توانیم دیتای مربوط به کامنت‌ها و نویسنده را از پست بگیریم:

تا به اینجا اسکیمای ما شامل تایپ کامنت، یوزر و پست می‌باشد:

پیشنهاد می‌کنم در ادامه مستندات graphql و مستندات graphene رو مطالعه کنید تا برای بخش‌های بعدی آماده باشید.

جمع بندی

تا به اینجای کار یک ای‌پی‌آی ساده‌ی گرف‌کیوال رو راه‌اندازی کردیم و چند تا تایپ هم توش تعریف کردیم و با مفاهیم اولیه گرف‌کیو ال آشنا شدیم. در بخش‌های بعدی مفاهیم پیشرفته‌تری رو توضیح خواهم داد.