اندازهی قلم متن
تخمین مدت زمان مطالعهی مطلب:
پنج دقیقه
Mutationها در GraphQL، اکشنهای میباشند که با استفاده از آنها Add ، Delete و Update را انجام میدهیم. تا کنون ما query های بازیابی اطلاعات را اجرا کردهایم. در این قسمت میخواهیم در رابطه با Mutation دادهها صحبت کنیم.
Input Types and Schema Enhancing for the GraphQL Mutations
کار را با ایجاد کردن یک کلاس جدید به نام OwnerInputType در پوشه Types، شروع میکنیم:
public class OwnerInputType : InputObjectGraphType { public OwnerInputType() { Name = "ownerInput"; Field<NonNullGraphType<StringGraphType>>("name"); Field<NonNullGraphType<StringGraphType>>("address"); } }
در سازنده کلاس، خصوصیت Name را مقدار دهی و دو فیلد را ایجاد میکنیم. همانطور که میبینیم دو خصوصیت Id و Accounts را نداریم؛ به دلیل اینکه نیازی به آنها نیست.
اگر قسمت قبل را دنبال کرده باشید متوجه هستیم برای ایجاد کردن query ها مجبور بودیم که یک کلاس را به نام AppQuery ایجاد کنیم. برای Mutation هم همین گونهاست. یک کلاس به نام AppMutation را در پوشه GraphQLQueries ایجاد میکنیم:
public class AppMutation : ObjectGraphType { public AppMutation() { } }
در نهایت نیاز است کلاس AppSchema را باز کرده و خصوصیت Mutation را به آن اضافه میکنیم:
public class AppSchema : Schema { public AppSchema(IDependencyResolver resolver) :base(resolver) { Query = resolver.Resolve<AppQuery>(); Mutation = resolver.Resolve<AppMutation>(); } }
اکنون همه چیز آماده است تا تعدادی Mutation، در پروژه ایجاد کنیم.
Create Mutation
در ابتدا واسط IOwnerRepository و کلاس OwnerRepository را همانند زیر ویرایش میکنیم (اضافه کردن متد CreateOwner):
public interface IOwnerRepository { ... Owner CreateOwner(Owner owner); } public class OwnerRepository : IOwnerRepository { ... public Owner CreateOwner(Owner owner) { owner.Id = Guid.NewGuid(); _context.Add(owner); _context.SaveChanges(); return owner; } }
متد CreateOwner یک شیء Owner جدید ایجاد شده را بازگشت میدهد. سپس در کلاس AppMutation:
public class AppMutation : ObjectGraphType { // Add public AppMutation(IOwnerRepository repository) { Field<OwnerType>( "createOwner", arguments: new QueryArguments(new QueryArgument<NonNullGraphType<OwnerInputType>> { Name = "owner" }), resolve: context => { var owner = context.GetArgument<Owner>("owner"); return repository.CreateOwner(owner); } ); } }
اکنون پروژه را اجرا کرده و سپس درخواست را در UI.Playground به صورت زیر ارسال کنید:
mutation($owner:ownerInput!){ createOwner(owner:$owner){ id, name, address } }
سپس در قسمت Query Variables :
{ "owner":{ "name":"Abolfazl-Roshanzamir", "address":"Address - User 4" } }
بجای کلمه کلیدی query، از کلمه کلیدی mutation برای mutationsها استفاده میکنیم. این تنها یک تفاوت جدید است.
Update Mutation
در ابتدا واسط IOwnerRepository و کلاس OwnerRepository را مطابق زیر ویرایش میکنیم:
public interface IOwnerRepository { ... Owner UpdateOwner(Owner dbOwner, Owner owner); } public class OwnerRepository : IOwnerRepository { ... public Owner UpdateOwner(Owner dbOwner, Owner owner) { dbOwner.Name = owner.Name; dbOwner.Address = owner.Address; _context.SaveChanges(); return dbOwner; } }
در نهایت همانند بخش (Create Mutation) یک فیلد را در سازنده کلاس AppMutation برای Update، اضافه میکنیم:
public class AppMutation : ObjectGraphType { public AppMutation(IOwnerRepository repository) { ... // Update Field<OwnerType>( "updateOwner", arguments: new QueryArguments( new QueryArgument<NonNullGraphType<OwnerInputType>> { Name = "owner" }, new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "ownerId" }), resolve: context => { var owner = context.GetArgument<Owner>("owner"); var ownerId = context.GetArgument<Guid>("ownerId"); var dbOwner = repository.GetById(ownerId); if (dbOwner == null) { context.Errors.Add(new ExecutionError("Couldn't find owner in db.")); return null; } return repository.UpdateOwner(dbOwner, owner); } ); } }
اکنون پروژه را اجرا کرده و سپس درخواست را در UI.Playground به صورت زیر ارسال کنید:
mutation($owner:ownerInput!,$ownerId:ID!){ updateOwner(owner:$owner,ownerId:$ownerId){ id, name, address } }
سپس در قسمت Query Variables:
{ "owner":{ "name":"Andy Madaidan", "address":"Address - User 1" }, "ownerId": "53270061-3ba1-4aa6-b937-1f6bc57d04d2" }
Delete Mutation
همان الگوی Create / Update را دوباره دنبال میکنیم. در ابتدا واسط IOwnerRepository و کلاس OwnerRepository را همانند زیر ویرایش میکنیم:
public interface IOwnerRepository { ... void DeleteOwner(Owner owner); } public class OwnerRepository : IOwnerRepository { ... public void DeleteOwner(Owner owner) { _context.Remove(owner); _context.SaveChanges(); } }
و آخرین کاری که نیاز است انجام شود، ویرایش کلاس AppMutation میباشد:
public class AppMutation : ObjectGraphType { public AppMutation(IOwnerRepository repository) { ... //Delete Field<StringGraphType>( "deleteOwner", arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "ownerId" }), resolve: context => { var ownerId = context.GetArgument<Guid>("ownerId"); var owner = repository.GetById(ownerId); if (owner == null) { context.Errors.Add(new ExecutionError("Couldn't find owner in db.")); return null; } repository.DeleteOwner(owner); return $"The owner with the id: {ownerId} has been successfully deleted from db."; } ); } }
اکنون پروژه را اجرا کنید و سپس درخواست را در UI.Playground به صورت زیر ارسال کنید:
mutation($ownerId:ID!){ deleteOwner(ownerId:$ownerId) }
سپس در قسمت Query Variables :
{ "ownerId": "6f513773-be46-4001-8adc-2e7f17d52d83" }
نتیجه گیری
اکنون ما میدانیم که چگونه از Input Type ها برای Mutation ها استفاده کنیم. چگونه mutation action های متفاوتی را ایجاد کنیم و هم چنین چگونه در خواستهای mutation را در سمت کلاینت ایجاد کنیم.
در قسمت بعد در رابطه با فراخوانی GraphQL API در یک کلاینت ASP.NET Core صحبت خواهیم کرد.
کدهای کامل مربوط به این قسمت را از اینجا دریافت کنید: ASPCoreGraphQL_3.rar