در جلسه ی قبل با نحوه نوشتن کوئری های پیچیده تر و پویا با استفاده از variable
ها، fragment
ها و directive
ها در GraphQL آشنا شدیم. در این جلسه با mutation
ها و روش تغییر داده در سرور آشنا خواهیم شد. در نهایت با توضیح inline fragment
ها و meta field
ها، مبحث query ها در GraphQL را به اتمام خواهیم رساند.
Mutation ها:
تا به اینجا تمامی بحث هایی که انجام شد مربوط به دریافت داده از سرور بود. اما هر سیستم مدیریت داده ای نیاز به تغییر داده در سرور دارد. این تغییرات می تواند شامل ایجاد یک داده جدید، ویرایش یک داده یا حذف آن از سرور باشد.
در سیستم REST برای دریافت داده ها از متد GET
استفاده می شود و متدهایی مانند post
، put
، delete
و... برای تغییر داده ها در سرور استفاده می شود. در GraphQL نیز این اصول پیاده سازی شده است. برای دریافت داده ها از query و برای تغییر داده ها در سرور از mutation
استفاده می شود.
در واقع mutation
ها از نظر ساختار شبیه به query ها هستند اما آن ها باعث تغییر داده ها در سرور می شوند. از نظر فنی می توان با query ها نیز به این هدف (تغییر داده ها) دست یافت اما توصیه می شود با توجه به اصول در نظر گرفته شده، برای این کار از mutation
ها استفاده شود.
Mutation
ها می توانند در نتیجه عملیات خود فیلدهایی را درخواست کنند. بنابراین در mutation
نوشته شده می توان فیلدها را درخواست کرد. برای درک بهتر به مثال زیر توجه کنید (نکته: قبل از ادامه بحث از آنجایی که mutation ها در سرور تغییر ایجاد می کنند، استفاده از آن ها در سرورهای تست مثل سرور استفاده شده در این دوره امکان پذیر نیست. بنابراین کوئری زیر قابل اجرا نخواهد بود):
mutation CreateCharacter($name: String!, $status: String!) {
createCharacter(name: $name, status: $status) {
id
name
}
}
در کوئری بالا mutation
و CreateCharacter
در واقع operation type
و operation name
استفاده شده هستند. در این بین یک mutation
به نام createCharacter
استفاده شده است. این mutation
باعث ساخته شدن یک داده جدید در سرور می شود (در جلسه های بعد شیوه پیاده سازی و ساخت داده جدید در سرور توضیح داده می شود). برای ارسال داده از variable
ها استفاده شده است. همچنین این mutation
در نتیجه، فیلدهای مختلفی را ارائه می دهد که می توان از آن ها استفاده کرد. استفاده از این داده ها برای زمانی که یک داده ویرایش شده است بسیار کاربردی خواهد بود.
همان طور که گفته شد mutation ها مانند query ها عمل می کنند. اما یک تفاوت بزرگ بین آن ها وجود دارد:
در حالی که query ها به صورت هم روند اجرا می شوند، mutation ها به صورت غیر هم روند اجرا خواهد شد.
این یعنی اگر در یک mutation
دو تغییر در داده ای ایجاد شود، می توان تضمین کرد که تغییر اول ابتدا انجام شده و سپس تغییر دوم ایجاد خواهد شد. این موضوع باعث خواهد شد از روبرو شدن با مواردی مثل race condition
در mutation
ها جلوگیری شود.
Inline Fragment ها:
مانند بسیاری از زبان های برنامه نویسی، GraphQL نیز از interface
ها استفاده می کند. درباره ی interface
ها در جلسه های بعد صحبت خواهیم کرد. اما در اینجا فرض کنید فیلد موجود در کوئری نوشته شده، یک interface
را پیاده سازی کرده است. برای دریافت این فیلد باید از inline fragment
ها استفاده کنید. به طور مثال کوئری زیر را در نظر بگیرید:
query ExampleQuery($id: ID!) {
person(id: $id) {
name
... on User {
wallet
}
... on Admin {
permissions
}
}
}
در کوئری بالا، نوع کاربر ممکن است User یا Admin باشد. هر یک از این دو نوع دارای فیلد name
هستند. اما ممکن است نوع User فیلد permissions
را نداشته باشد. بنابراین با استفاده از inline fragment ها می توان با توجه به نوع، فیلد مورد نیاز را دریافت کرد.
Meta field ها:
فرض کنید در کوئری نوشته شده، type داده مورد نظر مشخص نباشد. برای این منظور در GraphQL می توان از Meta field ها استفاده کرد. یکی از Meta field
هایی که در GraphQL وجود دارد، __typename
است. این فیلد، نوع داده برگردانده شده توسط کوئری را مشخص می کند. به طور مثال کوئری زیر را در نظر بگیرید:
query characterNameAndStatus($characterId: ID!) {
character(id: $characterId) {
__typename
id
name
}
}
در این کوئری، با استفاده از __typename
، نوع character
برگردانده شده است.
در این جلسه با شیوه تغییر داده ها در سرور با استفاده از mutation
ها آشنا شدیم و در نهایت با آشنا شدن با inline fragment
ها و meta field
ها، آشنایی با کوئری ها در GraphQL به اتمام رساندیم. در جلسه ی بعد به تشریح Schema
و type
ها در GraphQL خواهیم پرداخت.
موفق و موید باشید.