C# .Net Core 7.0 和 Graphql 實作

之前一直都對 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

 

定義好就能嘗試看看連接狀況

Copyright © 2025 - All right reserved