Это правильный шаблон GraphQL для мутации
У меня есть несколько вопросов о моих шаблонах для API, который я пишу. Написано на бэкэнде в Starlette с использованием MongoDB и GraphQL/Graphene для моих нужд базы данных /api.
Из-за ограниченного объема документации мне иногда трудно определить правильные шаблоны. Одна вещь, которая заставляет меня задуматься, иду ли я в правильном направлении, - это то, как работают мутации. Я знаю, что после запроса результат анализируется резолверами exdef resolve__id(parent, info): return parent['_id']
где родитель - результат, возвращенный из базы данных ex return loads(dumps(val))
. Мне кажется, что GraphQL делает то же самое с результатом мутации:return CreateUser(user=user)
.
Мои вопросы возникают, потому что объект, возвращаемый result = await resources.database.users.insert_one(newUser)
содержит только идентификатор createdUser, что означает, что он не может быть возвращен как метод resolve_password():
например, для объекта потребуется поле пароля. Из-за этого после каждого запроса вставки я запускаю другой запросuser = await resources.database.users.find_one({"_id": result.inserted_id})
чтобы получить только что созданный предмет. Это, в свою очередь, позволяет мне вернуть созданного пользователя в объекте CreateUser, как ожидает GraphQL, согласно документации Graphene: https://docs.graphene-python.org/en/latest/types/mutations/.
По сути, мой вопрос сводится к следующему: шаблон выполнения двух запросов по мутации, ожидаемой для моего инструментария, или я неправильно использую либо функции разрешения, либо какую-либо другую часть GraphQL?
Пожалуйста, дайте мне знать, требуется ли какая-либо другая часть моего кода или дополнительные пояснения. Я включил свой класс User ниже, который содержит весь код, на который я ссылаюсь, для предоставления контекста.
class User(graphene.ObjectType):
name = graphene.String()
_id = graphene.String()
password = graphene.String()
icon = graphene.String()
def resolve_name(parent, info):
return parent['user_name']
def resolve__id(parent, info):
return parent['_id']
def resolve_password(parent, info):
return parent['password']
def resolve_icon(parent, info):
return parent['icon']
class UserInput(graphene.InputObjectType):
userName = graphene.String(required=True)
password = graphene.String(required=True)
icon = graphene.String(required=True)
class CreateUser(graphene.Mutation):
user = graphene.Field(User)
class Arguments:
user_data = UserInput(required=True)
async def mutate(root, info, user_data=None):
newUser = {
'user_name': user_data.userName,
'password': user_data.password,
'icon': user_data.icon
}
result = await resources.database.users.insert_one(newUser)
user = await resources.database.users.find_one({"_id": result.inserted_id})
return CreateUser(user=user)
class UserQuery(graphene.ObjectType):
user = graphene.Field(User, userName=graphene.String())
users = graphene.List(User, length=graphene.Int())
async def resolve_user_by_id(parent, info, userId):
val = await resources.database.users.find_one({"_id": userId})
return loads(dumps(val))
async def resolve_user_by_name(parent, info, userName):
val = await resources.database.users.find_one({'user_name': userName})
return loads(dumps(val))
async def resolve_users(parent, info, length):
val = await resources.database.users.find().to_list(length=length)
return loads(dumps(val))
class UserMutation(graphene.ObjectType):
create_user = CreateUser.Field()