之前一直都對 Graphql 有一些興趣,趁著剛好有時間來練習看看Graphql 的一些功能
首先先安裝以下三個套件
dotnet add package HotChocolate.AspNetCore
dotnet add package HotChocolate.AspNetCore.Playground
dotnet add package HotChocolate.Data.EntityFramework
在Program加入網址入口
app.MapGraphQL("/graphql"); // 實際接口入口
app.UsePlayground(new PlaygroundOptions
{
Path = "/playground", // gui入口
QueryPath = "/graphql", // 跟gui講實際接口入口
});
Graphql 有三個主要核心,分別是Query、Mutation、Subscription,這次實作主要以Query、Mutation
Query - 查詢
Mutation - 新增、修改、刪除
Subscription - 及時更新通知
Query
這是寫如何跟資料庫來做關聯Mapping,重點要是IQueryable的型別
public class Query {
private readonly ILogHelper _logHelper;
public Query(ILogHelper logHelper)
{
this._logHelper = logHelper;
}
[UsePaging(MaxPageSize = 50, DefaultPageSize = 10)] // 這個一定要先,分頁式
[UseProjection] // 查詢投影
[UseFiltering] // 條件
[UseSorting] // 排序方式
public IQueryable<Article> GetArticles([Service] RonWebDbContext db)
{
try
{
return db.Article;
}
catch(Exception ex)
{
this._logHelper.Error(ex);
throw;
}
}
}
設定服務對應
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddProjections()
.AddFiltering()
.AddSorting();
設定資料庫DI
要注意的是,因為Graphql 是可以一個查詢,同時對多個來做條件搜尋,所以資料庫的設定要注意一下
如果用預設的Scope,同時查詢兩個以上會有競爭關係,所以我這邊調整為每個都為獨立連線
// graphql 如果用scope 每個查詢都用同個db的話會有競爭問題,這邊開分別實例
builder.Services.AddDbContext<RonWebDbContext>(options =>
{
string connectionString = "資料庫連線字串";
options.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 33)),
options => options.EnableRetryOnFailure());
}, ServiceLifetime.Transient);
定義好就能嘗試看看連接狀況
Mutation
Mutation主要作用是處理新增修改以及刪除
寫的方式跟一般新增修改刪除一樣,差別在需要定義回傳,不能為void
public class ArticleCategoryMutation: IArticleCategoryHelper {
public async Task<ArticleCategory?> CreateAsync([Service] RonWebDbContext db, CreateArticleCategoryRequest data)
{
var category = await db.ArticleCategory.SingleOrDefaultAsync(a => a.CategoryName == data.CategoryName);
if (category != null)
{
return null;
}
else
{
category = new ArticleCategory()
{
CategoryName = data.CategoryName,
CreateDate = DateTime.Now,
CreateBy = data.UserId
};
await db.AddAsync(category);
await db.SaveChangesAsync();
return category;
}
}
}
補上Mutation
builder.Services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddProjections()
.AddFiltering()
.AddSorting()
.AddMutationType<ArticleCategoryMutation>(); // 補上這個Mutation
定義好就能嘗試看看連接狀況