如何在 GraphQL 中执行突变?
Posted
技术标签:
【中文标题】如何在 GraphQL 中执行突变?【英文标题】:How to execute a mutation in GraphQL? 【发布时间】:2019-02-21 18:31:34 【问题描述】:在 GraphQL 中,我们基本上有两种类型的操作:查询和突变。虽然文档中对查询进行了很好的描述并且有很多示例,但我很难理解如何执行突变。突变显然是更新方法。
我创建了非常简单的 Node.js 服务器:
var express = require("express");
var graphqlHTTP = require("express-graphql");
var graphql = require("graphql");
var inMemoryDatabase = require("./inMemoryDatabase").inMemoryDatabase;
var _ = require("lodash-node");
var userType = new graphql.GraphQLObjectType(
name: "User",
fields:
id: type: graphql.GraphQLString ,
name: type: graphql.GraphQLString
);
var queryType = new graphql.GraphQLObjectType(
name: "Query",
fields:
user:
type: userType,
args:
id: type: graphql.GraphQLString
,
resolve: function(parent, id )
return _.find(inMemoryDatabase, id: id );
);
var mutationType = new graphql.GraphQLObjectType(
name: "Mutation",
fields:
user:
type: userType,
args:
id: type: graphql.GraphQLString ,
name: type: graphql.GraphQLString
,
resolve: function(parent, id, name )
var index = _.findIndex(inMemoryDatabase, id: id );
inMemoryDatabase.splice(index, 1, id: id, name: name );
return _.find(inMemoryDatabase, id: id );
);
var schema = new graphql.GraphQLSchema(
query: queryType,
mutation: mutationType
);
var app = express();
app.use(
"/graphql",
graphqlHTTP(
schema: schema,
graphiql: true
)
);
var port = 9000;
if (process.env.PORT)
port = process.env.PORT;
app.listen(port);
console.log("Running a GraphQL API server at localhost:" + port + "/graphql");
内存数据库只是在用户对象数组id, name
中:
var inMemoryDatabase = [
id: "31ce0260-2c23-4be5-ab78-4a5d1603cbc8",
name: "Mark"
,
id: "2fb6fd09-2697-43e2-9404-68c2f1ffbf1b",
name: "Bill"
];
module.exports =
inMemoryDatabase
;
执行查询以通过 id 获取用户如下所示:
user(id: "31ce0260-2c23-4be5-ab78-4a5d1603cbc8")
name
更改用户名会是什么样子?
【问题讨论】:
【参考方案1】:嘿,可能完全没听懂你在说什么,但我看待突变的方式是这样的
我得到了一些参数和一个字段,这与 params 和一个静态路径相同,我做了一些事情(在你的情况下,查找用户并根据传入的参数更新属性 之后,我从 resolve 函数返回一些内容,该函数将满足您在突变的type
中指定的类型
var mutationType = new graphql.GraphQLObjectType(
name: "Mutation",
fields:
user:
// You must return something from your resolve function
// that will fulfill userType requirements
type: userType,
// with these arguments, find the user and update them
args:
id: type: graphql.GraphQLString ,
name: type: graphql.GraphQLString
,
// this does the lookup and change of the data
// the last step of your result is to return something
// that will fulfill the userType interface
resolve: function(parent, id, name )
// Find the user, Update it
// return something that will respond to id and name, probably a user object
);
然后将其作为上下文,传递一些参数并请求回用户
mutation updateUser
user(id: "1", name: "NewName")
id
name
在正常的生产模式中,您通常还会有类似 errors
的内容,可以返回以传达失败/未找到更新的不同状态
【讨论】:
GraphQL 有内置的错误报告,如果突变失败,你通常会返回一个字段错误;它根本不会在架构中专门编码。 嗨大卫,我想这真的取决于你想要的错误级别。 Graphql 将为模式错误或无效查询等提供基本信息,但如果您想要更丰富的错误,这些错误等同于您从休息中得到的信息(如 422 或某些特定的失败事件),您必须为此返回一个新类型.另一个具体的例子是绑定到一个验证框架,比如在 rails ActiveModel::Validations 中,这样错误就会“更好”并且更容易被客户端使用。 在 Ruby 中,我倾向于使用graphql-ruby.org/errors/execution_errors.html(也描述了与语言无关的 JSON 错误响应格式)来返回字段或突变级别的错误。 啊,我的错,更新了 :) 有时只是将这些放在 graphiql 或 graphqlplayground 中,虽然你会出现拼写错误【参考方案2】:@Austio 的答案非常接近,但正确的方法是:
mutation updateUser
user(id: "31ce0260-2c23-4be5-ab78-4a5d1603cbc8", name: "Markus")
id
name
【讨论】:
以上是关于如何在 GraphQL 中执行突变?的主要内容,如果未能解决你的问题,请参考以下文章
如何在突变 graphQL Playground 中传递变量?