GraphQL یک زبان پرس و جو برای APIها و یک Runtime به منظور اجرای پرس و جو برروی داده های موجود است. با استفاده از GraphQL این امکان برای کلاینت فراهم می شود که داده های مورد نیازش را از سرور درخواست کرده و دقیقا همان داده هایی را که نیاز دارد دریافت کند، نه چیزی بیشتر و نه چیزی کمتر.
پرس و جوهای GraphQL همیشه نتایج قابل پیشبینی ای را به همراه خواهند داشت. همچنین برنامه هایی که از GraphQL استفاده می کنند، سریع و پایدار خواهند بود به علت آنکه کنترل داده های دریافتی توسط خود آنها صورت می گیرد، نه سرور.
در GraphQL می توان درخواست ها را به گونه ای پردازش کرد که تمام داده های مورد نیاز برنامه فقط توسط یک درخواست قابل بازیابی باشد، اما بازیابی اطلاعات متعدد در Rest API معمولا با چند درخواست فراهم می شود. این ویژگی می تواند در شبکه های با سرعت محدود مفید باشد.
سرویس های GraphQL بوسیله تعریف Typeها و فیلدهای مربوط به Typeها ایجاد می شود و سپس توابعی را برای هر فیلد در هر Type فراهم می کند. افزودن فیلدها و Typeهای جدید به APIهای GraphQL، تاثیری بر Queryهای موجود ندارد. درحقیقت برنامه ها با یک نسخه از GraphQL API در تعامل هستند و همچنین به راحتی می توانند به ویژگی های جدید بطور پیوسته نیز دسترسی داشته باشند و این موضوع نگهداری کد سمت سرور را راحتتر می کند.
GraphQL در WebApi
برای استفاده از GraphQL در NET WebApi. ابتدا نیاز است GraphQL Package را نصب نماییم. توسط اجرا دستور زیر در CLR این امکان فراهم می شود.
> dotnet add package GraphQL
پیاده سازی GraphQL در WebApi
برای پیاده سازی GraphQL در NET WebApi. و اجرای آن نیاز به سه مرحله زیر است:
- تعریف Schema
- نحوه پاسخ به Queryها
- اجرای Queryهای مورد نیاز براساس APIهای فراخوانی شده
تعریف Schema
رشته ای که داخل Schema.For قرار میدهیم و از سه قسمت تشکیل شده است:
- Query: در حقیقت همان چیزی است که می توانیم از سرویس درخواست کنیم.
- Typeها: نشان دهنده یک نوع Object است که می توان از طریق سرویس ارائه شده فراخوانی شود.
- Mutation: از لحاظ معنایی یعنی می خواهیم اطلاعات را تغییر دهیم.
مثال زیر یک Schema تعریف شده با قسمت های عنوان شده را نشان می دهد.
GraphQL.Types.Schema.For(@"
type Author {
id: ID
firstName: String
lastName: String
books: [Book]
}
type Book {
id: ID
title: String
published: Date
author: Author
}
type Query {
books: [Book]
book (id: ID): Book
author(id: ID): Author
authors: [Author]
}
type Mutation {
addAuthor(id:ID, firstName: String, lastName:String): [Author]
addBook(id:ID, title: String, published:String): [Book]
}",
schemaBuilder =>
{
schemaBuilder.Types.Include<Query>();
schemaBuilder.Types.Include<Mutation>();
})
تعریف چگونگی پاسخ به Queryها
درحقیقت نیاز به موجودیت هایی به عنوان پاسخ دهنده داریم تا با استفاده از آنها درخواست های فراخوانی شده برای Queryهای موجود را از طریق سرویس دهنده مدیریت نماییم. برای نمونه با توجه به Schema تعریف شده در مثال قبل، دو کلاس Query و Mutation ایجاد کره ایم تا Queryهای موجود در Schema را مدیریت کنیم. به این ترتیب چند نمونه از متدهای کلاس Query می تواند بصورت زیر باشد:
public class Query
{
[GraphQLMetadata("books")]
public List<Book> GeBooks()
{
return dbContext.Books;
}
[GraphQLMetadata("book")]
public Book GeBook(int id)
{
return dbContext.Books.FirstOrDefault(x => x.Id == id);
}
[GraphQLMetadata("authors")]
public List<Author> GeAuthors()
{
return dbContext.Authors;
}
[GraphQLMetadata("author")]
public Author GeAuthor(int id)
{
return dbContext.Authors.FirstOrDefault(x => x.Id == id);
}
[GraphQLMetadata("addAuthor")]
public void AddAuthor(Author author)
{
dbContext.Authors.Add(author);
}
[GraphQLMetadata("addBook")]
public void AddBook(Book book)
{
dbContext.Books.Add(book);
}
}
و همچنین کلاس Mutation می تواند شامل متدهایی برای درج اطلاعات بصورت زیر باشد:
public class Mutation
{
[GraphQLMetadata("addAuthor")]
public List<Author> AddAuthor(int id, string firstName, string lastName)
{
context.Authors.Add(new Author
{
Id = id,
FirstName = firstName,
LastName = lastName
});
return context.Authors;
}
[GraphQLMetadata("addBook")]
public List<Book> AddBook(int id, string title, string published)
{
context.Books.Add(new Book
{
Id = id,
Title = title,
Published = Convert.ToDateTime(published)
});
return context.Books;
}
اجرای Queryها
در نهایت سرور، Query درخواست شده کلاینت را از طریق Schema موجود اجرا می نماید و خروجی آن را در قالب Json ارائه می کند.
با توجه به مثالی که تاکنون پیش برده ایم امکان اجرای Queryهای زیرفراهم می باشد.
query Authors{
authors{
id
lastName
firstName
books {
title
}
}
}
query Author{
author (id:1){
id
firstName
lastName
}
}
query Books{
books {
id
title
published
author{
id
lastName
}
}
}
query Book{
book(id:2){
title
published
author{
firstName
lastName
}
}
}
همچنین می توان برای مثال Queryهای Mutation جهت درج داده های جدید را به صورت زیر اجرا کرد.
mutation AddAuthor {
addAuthor(id:3, firstName:"x", lastName:"y") {
id ,
firstName,
lastName
}
}
mutation AddBook ($id:ID,$title:String, $published:String){
addBook(id:$id, title:$title, published:$published){
id
published
title
}
}
به منظور اطلاع بیشتر از نحوه نوشتن Queryهای مختلف می توانید به آدرس graphql-dotnet.github.io مراجعه نمایید.
فایل پیوست
منابع