اشتراکها
ساخت مشابه Instagram با AngularJS
من هم همین خطا رو گرفتم، با حذف node.js 0.12 و نصب نسخه 0.10 مشکل حل شد
نظرات مطالب
PHP سریعتر از ASP.NET! افسانه یا واقعیت؟
بله. ضمنا node.js یک فناوری دیگر سمت سرور مبتنی بر جاوا اسکریپت است (و از این دست دارن زیاد میشن)
در این مقاله هدف این است که GraphQL را در ASP.NET Core راه اندازی کنیم. از یک کتابخانه ثالث برای آسانتر کردن یکپارچگی استفاده میکنیم و همچنین با جزئیات، توضیح خواهیم داد که چگونه میتوان از elementهای مربوط به GraphQL مثل (Type ،Query و Schema) برای کامل کردن فرآیند یکپارچگی در ASP.NET Core استفاده کنیم.
GraphQL و تفاوتهای آن با REST
GraphQl یک query language میباشد که queryها را با استفاده از type systemهایی که ما برای دادهها تعریف میکنیم، اجرا میکند. GraphQL به هیچ زبان یا پایگاه داده مشخصی گره نخورده است.
- GraphQL نیازمند رفت و برگشتهای کمتری به server، به منظور بازیابی دادهها برای template یا view است. همراه با REST ما مجبور هستیم که چندیدن endpoint مثلا (... api/students, api/courses, api/instructors ) را برای گرفتن همه دادههای که برای template یا view نیاز داریم ملاقات کنیم؛ ولی این شرایط در GraphQL برقرار نیست. با GraphQL ما تنها یک query را ایجاد میکنیم که چندین تابع (resolver) را در سمت سرور فراخوانی میکند و همه دادهها را از منابع مختلفی، در یک درخواست برگشت میدهد.
- همراه با REST، همانطور که Application ما رشد میکند، تعداد endpointها هم زیاد میشوند که این نیازمند زمان بیشتری برای نگهداری میباشد. اما با GraphQL ما تنها یک endpoint داریم؛ همین!
- با استفاده از GraphQL، ما هرگز به مشکل گرفتن دادههایی کم یا زیاد از منبع روبرو نخواهیم شد. به این خاطر است که ما queryها را با فیلدهایی که چیزهایی را که نیاز داریم، نشان میدهند، تعریف میکنیم. در این صورت ما همیشه چیزهایی را که درخواست دادهایم، دریافت میکنیم.
بنابراین اگر یک query شبیه زیر را ارسال کنیم :
query OwnersQuery { owners { name account { type } } }
{ "data": { "owners": [ { "name": "John Doe", "accounts": [ { "type": "Cash" }, { "type": "Savings" } ] } ] } }
شروع کار
یک پروژه جدید را با استفاده از دستور زیر ایجاد میکنیم:
dotnet new api -n ASPCoreGraphQL
پوشه Contracts شامل واسطهای مورد نیاز برای repository logic میباشد:
namespace ASPCoreGraphQL.Contracts { public interface IOwnerRepository { } }
namespace ASPCoreGraphQL.Contracts { public interface IAccountRepository { } }
در پوشه Models، کلاسهای مدل را نگه داری میکنیم؛ به همراه یک کلاس context و کلاسهای configuration:
public class Owner { [Key] public Guid Id { get; set; } [Required(ErrorMessage = "Name is required")] public string Name { get; set; } public string Address { get; set; } public ICollection<Account> Accounts { get; set; } } public class Account { [Key] public Guid Id { get; set; } [Required(ErrorMessage = "Type is required")] public TypeOfAccount Type { get; set; } public string Description { get; set; } [ForeignKey("OwnerId")] public Guid OwnerId { get; set; } public Owner Owner { get; set; } } public enum TypeOfAccount { Cash, Savings, Expense, Income }
public class ApplicationContext : DbContext { public ApplicationContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { } public DbSet<Owner> Owners { get; set; } public DbSet<Account> Accounts { get; set; } }
در پوشه Repository، کلاسهای مرتبط با منطق بازیابی دادهها را داریم:
public class OwnerRepository : IOwnerRepository { private readonly ApplicationContext _context; public OwnerRepository(ApplicationContext context) { _context = context; } }
public class AccountRepository : IAccountRepository { private readonly ApplicationContext _context; public AccountRepository(ApplicationContext context) { _context = context; } }
repository logic، یک راه اندازی ابتدایی بدون هیچ لایه اضافهتری است.
کلاس context و کلاسهای repository، در فایل Startup.cs ثبت میشوند:
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationContext>(opt => opt.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddScoped<IOwnerRepository, OwnerRepository>(); services.AddScoped<IAccountRepository, AccountRepository>(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore); }
Integration of GraphQL in ASP.NET Core
برای کار کردن با GraphQL در ابتدا نیاز است که کتابخانه GraphQL را نصب کنیم. به همین منظور در ترمینال مربوط به VS Code، دستور زیر را وارد میکنیم:
dotnet add package GraphQL
و همچنین کتابخانهی زیر که به ما کمک میکند تا GraphQL.NET را به عنوان یک وابستگی دریافت کنیم:
dotnet add package GraphQL.Server.Transports.AspNetCore
dotnet add package GraphQL.Server.Ui.Playground
(Creating GraphQL Specific Objects (Type, Query, Schema
کار را با ایجاد کردن یک پوشه جدید به نام GraphQL و سپس در آن ایجاد یک پوشه دیگر به نام GraphQLSchema، شروع میکنیم. در پوشه GraphQLSchema، یک کلاس را به نام AppSchema، ایجاد میکنیم.
کلاس AppSchema باید از کلاس Schema ارث بری کند تا در فضای نام GraphQL.Types قرار گیرد. در سازنده این کلاس، IDependencyResolver را تزریق میکنیم که قرار است به ما کمک کند تا اشیاء Query ،Mutation یا Subscription را resolve کنیم:
public class AppSchema : Schema { public AppSchema(IDependencyResolver resolver) :base(resolver) { } }
فعلا این کلاس را در همین حالت میگذاریم و سپس یک پوشه را به نام GraphQLTypes در پوشه GraphQL ایجاد میکنیم. در پوشه GraphQLTypes یک کلاس را به نام OwnerType ایجاد میکنیم:
public class OwnerType : ObjectGraphType<Owner> { public OwnerType() { Field(x => x.Id, type: typeof(IdGraphType)).Description("Id property from the owner object."); Field(x => x.Name).Description("Name property from the owner object."); Field(x => x.Address).Description("Address property from the owner object."); } }
از کلاس OwnerType به عنوان یک جایگزین برای مدل Owner درون یک GraphQL API استفاده میکنیم. این کلاس از نوع جنریک ObjectGraphType ارث بری میکند. با متد Field، فیلدهایی را که بیانگر خصوصیات مدل Owner میباشند، مشخص میکنیم.
در ابتدا واسط IOwnerRepository و کلاس OwnerRepository را به حالت زیر ویرایش میکنیم:
public interface IOwnerRepository { IEnumerable<Owner> GetAll(); } public class OwnerRepository : IOwnerRepository { private readonly ApplicationContext _context; public OwnerRepository(ApplicationContext context) { _context = context; } public IEnumerable<Owner> GetAll() => _context.Owners.ToList(); }
در ادامه یک پوشه دیگر را به نام GraphQLQueries در پوشهی GraphQL ایجاد و سپس در آن یک کلاس را به نام AppQuery ایجاد و آن را به حالت زیر ویرایش میکنیم:
public class AppQuery : ObjectGraphType { public AppQuery(IOwnerRepository repository) { Field<ListGraphType<OwnerType>>( "owners", resolve: context => repository.GetAll() ); } }
توضیحات AppQuery
همانطور که میبینیم این کلاس از ObjectGraphType ارث بری میکند. در سازنده کلاس، IOwnerRepository را تزریق میکنیم و یک فیلد را به منظور برگشت دادن نتیجه برای یک Query مشخص، ایجاد میکنیم. در این کلاس، از نوع جنریک متد Field، استفاده کردهایم که تعدادی type را به عنوان یک پارامتر جنریک پذیرش میکند که این بیانگر GraphQL.NET برای type های معمول در NET. میباشد. علاوه بر ListGraphType، نوعهایی مثل IntGraphType و StringGraphType و ... وجود دارند (لیست کامل).
پارامتر owners نام فیلد میباشد (query مربوط به کلاینت باید با این نام مطابقت داشته باشد) و پارامتر دوم نتیجه میباشد.
بعد از انجام این مقدمات، اکنون کلاس AppSchema را باز میکنیم و به حالت زیر آن را ویرایش میکنیم:
public class AppSchema : Schema { public AppSchema(IDependencyResolver resolver) :base(resolver) { Query = resolver.Resolve<AppQuery>(); } }
Libraries and Schema Registration
در کلاس Startup نیاز است کتابخانههای نصب شده و هم چنین کلاس schema ایجاد شده را ثبت کنیم. این کار را با ویرایش کردن متد ConfigureServices و Configure انجام میدهیم:
public void ConfigureServices(IServiceCollection services) { ... services.AddScoped<IDependencyResolver>(s => new FuncDependencyResolver(s.GetRequiredService)); services.AddScoped<AppSchema>(); services.AddGraphQL(o => { o.ExposeExceptions = false; }) .AddGraphTypes(ServiceLifetime.Scoped); ... }
در نهایت در متد schema Configure را به خط لوله درخواستها (request’s pipeline) اضافه میکنیم و هم چنین ابزار Playground UI:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { ... app.UseGraphQL<AppSchema>(); app.UseGraphQLPlayground(options: new GraphQLPlaygroundOptions()); app.UseMvc(); }
برای آزمایش GraphQL API امان، از ابزار GraphQL.UI.Playground استفاده میکنیم. در ابتدا پروژه را با دستور زیر اجرا میکنیم:
dotnet run
و سپس در مرورگر به این آدرس میرویم:
https://localhost:5001/ui/playground
کدهای مربوط به این قسمت را از اینجا دریافت کنید .ASPCoreGraphQL.zip