使用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
  } 
}
graphene-test03.png

在推进GraphQL的使用和实施时,我们需要更加了解GraphQL的规范和术语。

请提供相关信息

石墨烯
石墨烯变异

广告
将在 10 秒后关闭
bannerAds