我们已经可以使用各种方式来获取数据了。但是如何修改服务器端的数据呢?包括数据插入,修补,删除或者更新等等。GraphQL 的 mutation 就是负责这部分的。
在我们继续之前,我想对项目做一点调整, HelloWorldQuery 调整为 InventoryQuery,同时,HelloWorldSchema 也调整为 InventorySchema。当然,我也从根肿删除了 hello 和 world 这两个字段。
Mutaion 类型也是从 ObjectGraphType 派生的,下面的 createItem 字段,其实可以理解为一个方法,将可以在服务器端创建一个条目并返回它。
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。它需要从 InputObjectGraphType 派生。
public class ItemInputType : InputObjectGraphType { public ItemInputType() { Name = "ItemInput"; Field<NonNullGraphType<StringGraphType>>("barcode"); Field<NonNullGraphType<StringGraphType>>("title"); Field<NonNullGraphType<DecimalGraphType>>("sellingPrice"); } }
我们需要实际更新服务器端的数据,所以,在 DataSource 中,它使用 ApplicationDbContent 将新的条目添加到 DBSet<Item> Items 集合中。
public async Task<Item> AddItem(Item item) { var addedItem = await _applicationDbContext.Items.AddAsync(item); await _applicationDbContext.SaveChangesAsync(); return addedItem.Entity; }
注意,我们将新添加的条目返回个 createItem 端点,以便我们可以查询新创建条目的字段。这也是建议的方式。
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.
在运行应用之前,还需要将新的类型注册到依赖注入容器中。
services.AddScoped<ItemInputType>();
services.AddScoped<InventoryMutation>();
别忘了,还需要在 Schema 中注册我们新创建的 Mutation 对象。
public class InventorySchema : Schema { public InventorySchema(InventoryQuery query, InventoryMutation mutation) { Query = query; Mutation = mutation; } }
现在,让我们在 GraphiQL 中运行如下的请求。
mutation { createItem(item: {title: "GPU", barcode: "112", sellingPrice: 100}) { title barcode } }
这将添加一个新的条目,并返回新创建条目的 title 和 barcode 字段。
你还可以使用 Varible 执行。