具有多 InputObjectType 的石墨烯突变

Posted

技术标签:

【中文标题】具有多 InputObjectType 的石墨烯突变【英文标题】:Graphene mutation with multi InputObjectType 【发布时间】:2022-01-17 15:28:37 【问题描述】:

我正在尝试将 graphql 服务器从 @nestjs/graphql 转换为 python graphene。是否可以像这样在graphene 中创建mutation 类,生成与@nestjs/graphql 中相同的架构?

type Mutation 
  register(input: RegisterInput!): AuthResponse!
  login(input: LoginInput!): AuthResponse!
  socialLogin(input: SocialLoginInput!): AuthResponse!
  otpLogin(input: OtpLoginInput!): AuthResponse!
  ...

AuthResponse 类突变可用于许多请求(注册、登录等)。到目前为止我能做的如下:

class RegisterInput(graphene.InputObjectType):
    email = graphene.String()
    password = graphene.String()

class LoginInput(graphene.InputObjectType):
    email = graphene.String()
    password = graphene.String()

class AuthResponse(graphene.Mutation):
    response = graphene.String()

    def mutate(root, info, **args):
        response = 'this is response'
        return AuthResponse(
            response=response,
        )

class RegisterObject(AuthResponse):
    class Arguments:
        input = RegisterInput(required=True)

class LoginObject(AuthResponse):
    class Arguments:
        input = LoginInput(required=True)

class Mutation(graphene.ObjectType):
    register = RegisterObject.Field(
        required=True
    )

    login = LoginObject.Field(
        required=True
    )

但上面生成的架构与上面的不同:

type Mutation 
  register(input: RegisterInput!): RegisterObject!
  login(input: LoginInput!): LoginObject!
  ...

【问题讨论】:

【参考方案1】:

终于可以回答我自己的问题了。为了用一个答案发出多重变异请求,我们可以执行以下操作:

user.py

import graphene

from ..common import (
    core, 
    attachment, 
    pagination
)

from ..addresses import address
from ..wallets import wallet
from ..shops import shop
from ..refunds import refund
from ..orders import order

from . import profile

class User(core.CoreEntity):
    name = graphene.String(required=True)
    email = graphene.String(required=True)
    password = graphene.String()
    shop_id = graphene.Int(name='shop_id')
    profile = graphene.Field(lambda:profile.Profile)
    shops = graphene.List(graphene.NonNull(lambda:shop.Shop))
    refunds = graphene.List(lambda:refund.Refund)
    managed_shop = graphene.Field(lambda:shop.Shop,name='managed_shop')
    is_active = graphene.Boolean(name='is_active')
    address = graphene.List(graphene.NonNull(lambda:address.Address))
    orders = graphene.List(lambda:order.Order)
    wallet = graphene.Field(lambda:wallet.Wallet)

class SuccessResponse(graphene.ObjectType):
    message = graphene.String(required=True)
    success = graphene.Boolean(required=True)

class OtpResponse(graphene.ObjectType):
    id = graphene.String(required=True)
    message = graphene.String(required=True)
    success = graphene.Boolean(required=True)
    phone_number = graphene.String(required=True)
    provider = graphene.String(required=True)
    is_contact_exist = graphene.Boolean(required=True)

class PasswordChangeResponse(graphene.ObjectType):
    success = graphene.Boolean(required=True)
    message = graphene.String(required=True)

class AuthResponse(graphene.ObjectType):
    token = graphene.String()
    permissions = graphene.List(graphene.String)

class RegisterInput(graphene.InputObjectType):
    name = graphene.String(required=True)
    email = graphene.String(required=True)
    password = graphene.String()
    permissions = graphene.Field(lambda:Permission)

class Permission(graphene.Enum):
    SUPER_ADMIN = 'Super admin'
    STORE_OWNER = 'Store owner'
    STAFF = 'Staff'
    CUSTOMER = 'Customer'

class LoginInput(graphene.InputObjectType):
    email = graphene.String()
    password = graphene.String()

mutation.py

import graphene

from .models.users import user, profile
from .models.products import product
from .models.orders import order

class Mutation(graphene.ObjectType):
    register = graphene.Field(
        lambda:user.AuthResponse,
        input=graphene.Argument(user.RegisterInput, required=True),
        required=True,
    )

    login = graphene.Field(
        lambda:user.AuthResponse,
        input=graphene.Argument(user.LoginInput, required=True),
        required=True,
    )

    @staticmethod
    def resolve_register(root, info, input):
        # return AuthResponse(email=input['email'], password=input['password'])
        # Here we can insert data into database (eg. Django or Odoo) and get fresh token for the registered user
        token = 'thisistoken'
        permissions = ['super_admin', 'customer']
        return user.AuthResponse(token=token, permissions=permissions)

    @staticmethod
    def resolve_login(root, info, input):
        # Here we can compare credential with database (eg. Django or Odoo) and get token
        token = 'thisistoken' 
        permissions = ['super_admin', 'customer']
        return user.AuthResponse(token=token, permissions=permissions)

这是在我们的 graphql Playground 应用程序中生成的架构:

type Mutation 
  register(input: RegisterInput!): AuthResponse!
  login(input: LoginInput!): AuthResponse!

  # below is other mutation request similar
  socialLogin(input: SocialLoginInput!): AuthResponse!
  otpLogin(input: OtpLoginInput!): AuthResponse!
  verifyOtpCode(input: VerifyOtpInput!): SuccessResponse!
  sendOtpCode(input: OtpInput!): OtpResponse!
  logout: Boolean!
  changePassword(input: ChangePasswordInput!): PasswordChangeResponse!
  forgetPassword(input: ForgetPasswordInput!): PasswordChangeResponse!
  verifyForgetPasswordToken(
    input: VerifyForgetPasswordTokenInput!
  ): PasswordChangeResponse!
  resetPassword(input: ResetPasswordInput!): PasswordChangeResponse!
  updateUser(input: UpdateUserInput!): User!
  activeUser(id: ID!): User!
  banUser(id: ID!): User!
  removeUser(id: ID!): User!
  createProfile(input: ProfileInput!): Profile!
  updateProfile(id: ID!, input: ProfileInput!): Profile!
  deleteProfile(id: ID!): Profile!

所以两个突变请求:registerlogin 由一个名为 AuthResponse 的对象突变对象回答。

希望这对其他人有所帮助。

【讨论】:

以上是关于具有多 InputObjectType 的石墨烯突变的主要内容,如果未能解决你的问题,请参考以下文章

使用 GraphQL + 石墨烯进行删除操作的最佳方法

GraphQL:具有标量和 InputObjectType 的 UnionType

如何解决具有多对多关系的石墨烯 django 节点字段

函数计算帮助石墨文档突破性能瓶颈,有效节省服务器成本

石墨在数据点之间具有空值

具有外键关系的对象的石墨烯中的 GraphQL 突变