1. 程式人生 > >ASP.NET Core中使用GraphQL - 第七章 Mutation

ASP.NET Core中使用GraphQL - 第七章 Mutation

ASP.NET Core中使用GraphQL - 目錄


在前面幾篇中,我們已經介紹瞭如何使用GraphQL中的query

欄位獲取資料。那麼如何使用GraphQL進行資料的新增,刪除,修改操作呢?這裡我們需要引入GraphQL中的mutation

我們繼續編寫新程式碼之前,我們需要先整理一下當前的專案程式碼。這裡我們將HelloWorldQuery類改名為InventoryQuery類, 並將HelloWorldSchema類改名為InventorySchema。然後我們將hellohowdy兩個欄位移除掉。

在GraphQL中, 一個Mutation型別也是繼承自ObjectGraphType類。在以下程式碼中,createItem欄位在伺服器端建立了一個貨物並返回了它的內容。

InventoryMutation
public class InventoryMutation : ObjectGraphType  
{
    public InventoryMutation(IDataStore dataStore)
    {         
        Field<ItemType>(
            "createItem",
            arguments: new QueryArguments(
                new QueryArgument<NonNullGraphType<ItemInputType>> { Name = "item" }
            ),
            resolve: context =>
            {
                var item = context.GetArgument<Item>("item");
                return dataStore.AddItem(item);
            });
    }
}

以上程式碼中我們引入了一個新的ItemInputType類作為查詢引數。在第五章中,我們已經建立過一個標量型別的引數。但是針對複雜型別,我們使用不同的方式。因此,這裡我們建立了一個新的類ItemInputType。其程式碼如下:

ItemInputType
public class ItemInputType : InputObjectGraphType  
{
    public ItemInputType()
    {
        Name = "ItemInput";
        Field<NonNullGraphType<StringGraphType>>("barcode");
        Field<NonNullGraphType<StringGraphType>>("title");
        Field<NonNullGraphType<DecimalGraphType>>("sellingPrice");
    }
}

為了將新的貨物記錄新增到資料庫,我們還需要修改IDataStore介面,新增一個AddItem的方法,並在DataStore類中實現它。

IDataStore
public interface IDataStore
{
    IEnumerable<Item> GetItems();
    Item GetItemByBarcode(string barcode);
    Task<Item> AddItem(Item item);
}
DataStore
public async Task<Item> AddItem(Item item)  
{
    var addedItem = await _context.Items.AddAsync(item);
    await _context.SaveChangesAsync();
    return addedItem.Entity;
}

這裡請注意AddItem的方法簽名,在新增完成之後,我們將新增成功的貨物記錄返回了。因此我們可以查詢新新增物件的內嵌欄位

Just like in queries, if the mutation field returns an object type, you can ask for nested fields. This can be useful for fetching the new state of an object after an update. - GraphQl Org.

和查詢一樣,如果mutation欄位返回一個物件型別,你就可以查詢它的內嵌欄位。這對於獲取一個更新後物件的新狀態非常有用。

在我們執行程式之前,我們還如要在控制反轉容器中註冊ItemInputTypeInventoryMutation

Startup
services.AddScoped<ItemInputType>();  
services.AddScoped<InventoryMutation>();  

最後我們需要在InventorySchema的建構函式中,注入InventoryMutation

InventorySchame
public class InventorySchema : Schema  
{
    public InventorySchema(InventoryQuery query, InventoryMutation mutation)
    {
        Query = query;
        Mutation = mutation;
    }
}

現在你可以執行程式了,這裡我們執行如下的mutation

mutation {  
  createItem(item: {title: "GPU", barcode: "112", sellingPrice: 100}) {
    title
    barcode
  }
}

這段程式碼的意思是,我們將呼叫createItemmutation, 將item儲存到資料庫,並會返回新增item的titlebarcode屬性。

當然你也可以把新增的item物件放到Query Variables視窗中, 得到的結果是一樣的

本文原始碼: https://github.com/lamondlu/GraphQL_Blogs/tree/master/Part%20VII