使用Azure Functions和Graphene来操作CosmosDB数据(2)
首先
在「使用Azure Functions和Graphene操作CosmosDB数据」文章中,我们已经在Azure Functions中实现了GraphQL API的查询操作,但是还没有实现变更操作,所以这次我们打算继续实现变更操作。
请参考这篇文章和这篇文章,了解前期准备和实施内容。
2. GraphQL查询的变更操作定义
继续之前在「使用Azure Functions和Graphene处理CosmosDB数据操作」中所做的工作,我们将使用Graphene来实现GraphQL的Mutation功能。在实现过程中,我们将参考Graphene官方文档。
突变是一个执行GraphQL操作的过程,它涉及向数据源写入数据并获取执行结果。(查询只涉及从数据源读取结果)
定义模式,然后定义解析器,并最后在解析器内部实现对数据源的处理,这个流程与上次相同,但是解析器的指定与之前稍有不同,是以Query类型进行定义的。
2.1. 对于 Mutation 操作的每个解析器定义的对应关系。
为了将GraphQL的Mutation类型的每个操作(字段)与解析器函数对应起来,我们需要为每个操作准备继承Mutation类的类。
#Mutation型の各操作と対応づけるリゾルバーの定義
class CreateItem(graphene.Mutation):
class Arguments:
item = ItemInput(required=True) #ミューテーションのAugument
Output = Item #ミューテーションの実行結果の型
def mutate(self, info, item): #Mutation実行時に呼び出される関数
i = Itemオブジェクトを作成するDB操作
return i
在上述的例子中,使用了Input类型的对象。这里我们会准备一个继承自InputObjectType的类,并将其作为Arguments传递给Query和Mutation的各个操作。
#idとmessageというフィールドを持つinput型の定義
class ItemInput(graphene.InputObjectType): #inputの定義
id = graphene.String(required=True)
message = graphene.String()
2.2. Mutation型的定义。
GraphQL的Mutation类型和Query类型一样,都是作为继承自ObjectType的类来定义。
在Mutation类型中,将字段名与继承自Mutation的类进行对应,当调用与GraphQL查询中所描述的Mutation字段名相对应的解析器时,就会发生这样的流程。 (在Mutation类型和继承自Mutation的类中可能会令人困惑…)
#createItemというフィールドを持つMutation型の定義
class Mutation(graphene.ObjectType):
create_Item = CreateItem.Field()
另外,据说snake_case将替换为camelCase。
2.3. 执行根查询声明和变异
在执行GraphQL查询时,可以通过在Schema类中将mutation和Mutation类型相匹配(声明为根查询类型),以便在实际执行变异时(调用execute方法)调用对应的Mutation解析器函数(或者类),并且执行相应的操作。这与Query类型的工作方式类似。
schema = graphene.Schema(
query=Query,
mutation=Mutation #ここを追加
)
schema.execute("GraphQLのミューテーション")
2.4. 与GraphQL相关的代码
以下是我們這次新添加的與GraphQL相關的程式碼。
#整體的程式碼已經PUSH到GitHub上,但目前仍然在整理當中。
# input DBItemInput
class DBItemInput(graphene.InputObjectType):
id = graphene.String(required=True)
owner = graphene.String(required=True)
partitionKey = graphene.ID(required=True)
message = graphene.String()
addition = graphene.String()
class CreateItem(graphene.Mutation):
class Arguments:
item = DBItemInput(required=True)
Output = DbItem
def mutate(self, info, item):
results = DatabaseConnection().create_item(item).pop()
i = DbItem.__new__(DbItem)
i.__dict__.update(results)
return i
class DeleteItem(graphene.Mutation):
class Arguments:
item = DBItemInput(required=True)
Output = DbItem
def mutate(self, info, item):
results = DatabaseConnection().delete_item(item)
if results.__len__() > 0:
i = DbItem.__new__(DbItem)
i.__dict__.update(results[0])
return i
return None
class UpsertItem(graphene.Mutation):
class Arguments:
item = DBItemInput(required=True)
Output = DbItem
def mutate(self, info, item):
results = DatabaseConnection().upsert_item(item)
i = DbItem.__new__(DbItem)
i.__dict__.update(results)
return i
# type Mutation
class Mutation(graphene.ObjectType):
create_Item = CreateItem.Field()
delete_Item = DeleteItem.Field()
upsert_Item = UpsertItem.Field()
class GraphQL:
def __init__(self):
self.schema = graphene.Schema(
query=Query,
mutation=Mutation
)
pass
def query(self, query):
results = self.schema.execute(query)
return json.dumps(results.data)
如果用GraphQL模式定义语言来描述上述模式,可能会是以下这种感觉。
input DBItemInput {
id: String!
owner: String!
partitionKey: String!
message: String
addition: String
}
type Mutation {
createItem(DBItemInput!): DbItem
deleteItem(DBItemInput!): DbItem
upsertItem(DBItemInput!): DbItem
}
schema {
query: Query
mutation: Mutation
}
4. 确认执行GraphQL变更操作。
我想在已实现的函数中发出GraphQL的mutation,并查看响应。关于执行方法,可以使用curl命令发出查询,也可以使用GraphiQL或Insomnia。对于curl命令,你可以使用以下方式发出查询。
curl -X POST -H "Content-Type: application/json" -d '{"query": "mutation { createItem (item: {id: "id1", owner: "testuser", partitionKey: 1, message: "test message1", addition: "addtion message 1"}) { id message } }"}' http://localhost:7071/api/MyFunction
以下是本次发布的GraphQL变异。对于Insomnia,如果指定URL并发布以下变异,将获得响应。
mutation {
createItem(item: {id: "id1", owner: "testuser", partitionKey: 1, message: "test message1", addition: "addtion message 1"}) {
id
message
}
}

在推进GraphQL的使用和实施时,我们需要更加了解GraphQL的规范和术语。
请提供相关信息
石墨烯
石墨烯变异