vue中的突变方法在哪
This is a continuation of a series on GraphQL Actions. The previous tutorial explored GraphQL Queries. This time, we will take a closer look at Mutations. There’s a lot of similarities in the way GraphQL Queries and Mutations work, however, Mutations are more about mutating data than querying for it. In this article, we’ll dive more into it and treat its concepts in details.
这是GraphQL操作系列的延续。 上一教程探讨了GraphQL查询 。 这次,我们将仔细研究突变。 GraphQL查询和突变的工作方式有很多相似之处,但是,突变更多的是关于突变数据而不是查询数据。 在本文中,我们将更深入地研究它,并详细处理其概念。
Mutation in any GraphQL application is very essential to the application’s data integrity. Once the mutation is done incorrectly, the data output of such application will be wrong and if such data is being used for decision making, it could be catastrophic.
任何GraphQL应用程序中的突变对于应用程序的数据完整性都是至关重要的。 一旦错误地完成了突变,该应用程序的数据输出将是错误的,并且如果将此类数据用于决策,则可能是灾难性的。
That is why the mutation request object is not like the query request object which you do not need to prefix with a keyword before making query requests. The mutation prefix before the request is to make sure that request is being intentional and that whoever is making the request knows the consequences of their action.
这就是为什么变异请求对象与查询请求对象不同的原因,在发出查询请求之前,您不需要为该对象添加关键字前缀。 请求之前的突变前缀是为了确保请求是有意的,并且提出请求的人都知道其操作的后果。
Designing a schema for a mutation is quite similar to that of a query. Let us look at the block of code below that shows us how to write a mutation schema:
为突变设计模式与查询非常相似。 让我们看一下下面的代码块,该代码块向我们展示了如何编写变异模式:
let chefs = []
const Mutations = new GraphQLObjectType({
name: 'Mutation',
fields: {
addChef: {
type: ChefType,
kwarg: {
name: { type: GraphQLString },
age: { type: GraphQLInt},
hobby: { type: GraphQLInt},
},
resolve(parent, kwarg) {
kwarg.id = Math.random()
return [...chefs, kwarg]
}
},
}
})
The schema describes a mutation called addChef
that adds the data about a chef to an array (since we are not actually creating a real application). The schema contains some key/value pairs or properties that let GraphQL know that we are trying to create a schema for a Mutation. One of them is the name
property, which we’ve set to the Mutation. Another one is the fields
property that in turn has two other sub-properties, which are addChef
and the resolve
function.
该模式描述了一个名为addChef
的变异,该变异将有关厨师的数据添加到数组中(因为我们实际上并未创建真正的应用程序)。 模式包含一些键/值对或属性,这些属性使GraphQL知道我们正在尝试为Mutation创建模式。 其中之一是name
属性,我们将其设置为Mutation。 另一个是fields
属性,该属性又具有另外两个子属性,分别是addChef
和resolve
函数。
The addChef
object contains information about the Mutation function. It could be named anything. This is the name that would be referred to when we try to mutate a data. The kwarg
object contains the arguments that the function addChef
will expect and their GraphQL data types.
addChef
对象包含有关Mutation函数的信息。 它可以命名为任何东西。 这是我们尝试突变数据时要使用的名称。 该kwarg
对象包含参数,函数addChef
会期待和他们GraphQL数据类型。
Finally, we have the resolve function, which is where all of the mutation actions take place. It takes in two arguments in this instance. One is the parent argument that points to the data linked to the addChef
query, which we do not have in this instance. So, the parent argument isn’t quite useful here. The second argument is kwarg
, which refers to the arguments we have passed into the function.
最后,我们具有解决功能,所有突变动作都在此发生。 在这种情况下,它接受两个参数。 一个是父参数,它指向链接到addChef
查询的数据,在这种情况下,我们没有此参数。 因此,父参数在这里不是很有用。 第二个参数是kwarg
,它指向我们传递给函数的参数。
At this point, we have created a mutation but it still won’t work yet. We need to find a way to let GraphQL know that what we’ve done here is a mutation. In order words, we need to find a way of registering the new instance we just created as a mutation. To register our mutation, we define it like so:
在这一点上,我们已经创建了一个变异,但是它仍然无法正常工作。 我们需要找到一种方法让GraphQL知道我们在这里所做的是一个突变。 换句话说,我们需要找到一种方法来注册刚创建为突变的新实例。 为了注册我们的突变,我们这样定义它:
module.exports = new GraphQLSchema({
mutation: Mutations
})
Having designed a mutation schema and registered it to the application, you can use the mutation addChef
in this case, to add data (a chef) to the chefs array. If for instance, we want to create a new chef, we can run this mutation:
设计了一个变异模式并将其注册到应用程序后,在这种情况下,您可以使用变异addChef
将数据(一个厨师)添加到addChef
数组中。 例如,如果我们要创建一个新的厨师,则可以运行此突变:
mutation {
addChef(name: "Swae Yu", age: "30", hobby:"Swimming"){
id,
age,
name,
hobby
}
}
What we’ve done here is use mutation to add data to the chefs
array. You’ll also notice that we had to define the request inside a mutation object. This is so that GraphQL will recognize that we are not just trying to grab data from somewhere but we want to alter such data.
我们在这里所做的是使用变异将数据添加到chefs
数组中。 您还将注意到,我们必须在一个变异对象内定义请求。 这样GraphQL就会认识到我们不仅在尝试从某处获取数据,而且还想更改此类数据。
As much as we can only use the mutation
keyword to carry out our mutation action, in production or in more robust applications, it will be better to name individual mutations for clarity and ease of use. That said, we could decide to be more descriptive and give a unique name to the mutation we had in the previous example, this will be the result:
尽管我们只能使用mutation
关键字来执行我们的突变操作,无论是在生产中还是在更强大的应用程序中,为了清楚和易于使用,更好地命名单个突变。 就是说,我们可以决定更具描述性,并为上一个示例中的突变赋予唯一的名称,这将是结果:
mutation mutateChef {
addChef(name: "Swae Yu", age: "30", hobby:"Swimming"){
id,
age,
name,
hobby
}
}
Now we can refer to this mutation with it’s unique name, mutateChef
.
现在,我们可以使用唯一的名称mutateChef
来引用此突变。
Consider a situation where we want a user to update the data in our application by passing in new data, maybe from a text input field. This is usually the case in most applications, but at the moment that is not possible in our application since we passed static values directly into our query. What we can do is use variables to pass dynamic data into the query instead.
考虑一种情况,我们希望用户通过传入新数据(可能来自文本输入字段)来更新应用程序中的数据。 在大多数应用程序中通常是这种情况,但是目前在我们的应用程序中这是不可能的,因为我们将静态值直接传递到了查询中。 我们可以做的是使用变量将动态数据传递到查询中。
Thankfully, this is a very straightforward process in GraphQL. Let’s change the mutation query we’ve written previously to use variable inputs:
幸运的是,这是GraphQL中非常简单的过程。 让我们更改我们之前编写的使用变量输入的变异查询:
mutation ($name: String!, $age: Int!, $hobby: String!){
addChef(name: $name, age: $age, hobby:$hobby){
id,
age,
name,
hobby
}
}
The snippet above is a good example of how we can modify our mutation query to use input variables instead of the previous static values. The variables are declared using the $
sign and then followed by the name we want to give the variable. Next we explicitly set a type for the variable. For example the $name
variable was set to a String
. The !
after the string shows that the field or variable is required.
上面的代码段很好地说明了如何修改变异查询以使用输入变量而不是先前的静态值。 变量使用$
符号声明,然后加上我们要赋予变量的名称。 接下来,我们显式设置变量的类型。 例如, $name
变量设置为String
。 !
在字符串表明字段或变量是必需的之后。
Just like in the previous example, we can also give the mutation a unique name. The code snippet below shows a named mutation with dynamic values from variables.
就像在前面的示例中一样,我们还可以给该突变起一个唯一的名称。 下面的代码段显示了一个带有变量动态值的命名突变。
mutation mutateChef($name: String!, $age: Int!, $hobby: String!){
addChef(name: $name, age: $age, hobby:$hobby){
id,
age,
name,
hobby
}
}
Now that we understand what Mutations are all about, we can build a mini GraphQL app to give a more practical experience.
现在我们了解了突变的含义,我们可以构建一个微型GraphQL应用程序以提供更实际的体验。
The application we’ll build should be one that can allow us to perform some basic CRUD operations on a bunch of mock data containing the names of some chefs. In clearer terms, the application will show you how to Create, Update, and Delete a particular chef from an array of chefs using the much talked about GraphQL Mutation.
我们将构建的应用程序应该可以使我们对包含一些厨师姓名的一堆模拟数据执行一些基本的CRUD操作。 更明确地说,该应用程序将向您展示如何使用广受关注的GraphQL突变从一系列厨师中创建,更新和删除特定厨师。
Before we dive into the app, we need to set up a server to send requests to.
在深入研究应用程序之前,我们需要设置服务器以将请求发送到。
First, initialize an empty project with npm init -y
. Then proceed with installing all the necessary dependencies for the application:
首先,使用npm init -y
初始化一个空项目。 然后继续为应用程序安装所有必需的依赖项:
Once the installation is complete, create a config
directory then also created a port.js
file in the directory and then update it with the code below:
安装完成后,创建一个config
目录,然后在目录中创建一个port.js
文件,然后使用以下代码对其进行更新:
export const PORT = process.env.PORT || 9091
In the root directory, create an app.js
file that will serve as our entry file to the application. Then update it with the code below:
在根目录中,创建一个app.js
文件,它将用作我们的应用程序入口文件。 然后使用以下代码对其进行更新:
import express from 'express';
import graphqlHTTP from 'express-graphql';
import { PORT } from './config/port';
import logger from './config/winston';
const app = express();
app.use(cors())
app.use('/graphql', graphqlHTTP({
graphiql: true
}))
app.listen(PORT, () => {
logger.info(`Server now listening for request at port ${PORT}`);
})
Finally go to your package.json
file and create a dev
script with the code below:
最后,转到您的package.json
文件,并使用以下代码创建一个dev
脚本:
"dev": "nodemon --exec babel-node app.js"
This script command allows us to quickly start our application’s local server without typing so many terminal commands.
此脚本命令使我们能够快速启动应用程序的本地服务器,而无需键入太多终端命令。
In the root directory, create a Server
directory. Then also, create a model
and a schema
directory. In the model
directory, create an index.js
file and update it with the code below:
在根目录中,创建一个Server
目录。 然后,还创建一个model
和一个schema
目录。 在model
目录中,创建一个index.js
文件,并使用以下代码对其进行更新:
export const chefs = [
{
id: 1,
name: "Monique Black"
},
{
id: 2,
name: "Chidinma Madukwe"
} ]
Here, we are exporting an array of chefs
containing the mock data we will use to represent the initial chefs we have in this application. Once that is done, create an index.js
file in the schema
directory and update it with the code below:
在这里,我们正在导出一个chefs
数组,其中包含模拟数据,这些数据将用于代表此应用程序中的初始厨师。 完成后,在schema
目录中创建一个index.js
文件,并使用以下代码对其进行更新:
import {
GraphQLObjectType,
GraphQLString,
GraphQLID,
GraphQLList,
GraphQLSchema,
GraphQLNonNull
} from 'graphql'
import { chefs } from '../model/'
const ChefType = new GraphQLObjectType({
name: 'chef',
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString}
})
})
const RootQuery = new GraphQLObjectType({
name: 'RootQuery',
fields: {
chefs: {
type: new GraphQLList(ChefType),
resolve() {
return chefs
}
}
}
})
const Mutations = new GraphQLObjectType({
name: 'Mutation',
fields: {
deleteChef: {
type: ChefType,
args: {
id: { type: new GraphQLNonNull(GraphQLID)}
},
resolve(parent, args) {
const returnedData = chefs.filter(chef => {
return chef.id == args.id
})
return returnedData[0]
}
},
addChef: {
type: new GraphQLList(ChefType),
args: {
name: {type: new GraphQLNonNull(GraphQLString)}
},
resolve(parent, args) {
args.id = Math.floor(Math.random() * 10)
return [...chefs, args]
}
},
updateChef: {
type: ChefType,
args: {
id: { type: new GraphQLNonNull(GraphQLID)},
name: { type: new GraphQLNonNull(GraphQLString)}
},
resolve(parent, args) {
const updateChef = chefs.find(data => {
return data.id == args.id
})
updateChef.name = args.name
return updateChef
}
}
}
})
export const schema = new GraphQLSchema({
query: RootQuery,
mutation: Mutations
})
Although this is a long file of code, this includes everything we’ve touched on through the tutorial. The only few things that were included but not previously covered are the GraphQL types which are:
尽管这是一个很长的代码文件,但这包括我们在本教程中涉及的所有内容。 GraphQL类型仅包含但以前未涵盖的几项内容是:
GraphQLObjectType - what we use to describe the structure of either a query or a mutation object.
GraphQLObjectType-我们用来描述查询或变异对象的结构的对象。
GraphQLNonNull - this tells GraphQL that once a file with a GraphQLNonNull
type is missing in a query, such query or mutation won’t be made. The field becomes a required field.
GraphQLNonNull-这告诉GraphQL,一旦查询中缺少具有GraphQLNonNull
类型的文件,就不会进行这种查询或变异。 该字段成为必填字段。
GraphQLID - This allows a query to be made if an id
parameter is being passed in as either a string or an integer.
GraphQLID-如果以字符串或整数形式传递id
参数,则可以进行查询。
GraphQLList - This lets GraphQL know that the response is going to contain data of similar type in an array. GraphQL types aren’t just limited to these, the rest can be found on the GraphQL official website.
GraphQLList-这使GraphQL知道响应将在数组中包含相似类型的数据。 GraphQL类型不仅限于这些类型,其余的可以在GraphQL官方网站上找到。
Finally, go back to the app.js
file and update it with the code below:
最后,返回到app.js
文件,并使用以下代码对其进行更新:
import express from 'express';
import graphqlHTTP from 'express-graphql';
import cors from 'cors';
import { PORT } from './config/port';
import logger from './config/winston';
import {schema} from './server/schema/';
const app = express();
app.use(cors())
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true
}))
app.listen(PORT, () => {
logger.info(`Server now listening for request at port ${PORT}`);
})
After grabbing the code, run the npm run dev
script command on your terminal to start the local server. You should get this message logged to the console when your server is running successfully.
抓取代码后,在终端上运行npm run dev
script命令以启动本地服务器。 服务器成功运行时,应该将此消息记录到控制台。
"message":"Server now listening for request at port 9090","level":"info"}
Now that we have a server, let’s test our application with Graphiql. Graphiql is a GUI application that is shipped or embedded into the express-graphql
module we installed earlier. To open it up, go to your browser and visit this URL http://localhost:9091/graphql
. You should see a page similar to the one i have below:
现在我们有了服务器,让我们用Graphiql测试我们的应用程序。 Graphiql是一个GUI应用程序,已附带或嵌入到我们先前安装的express-graphql
模块中。 要打开它,请转到浏览器并访问此URL http://localhost:9091/graphql
。 您应该会看到与以下页面相似的页面:
To create a query that will return all the chefs
in our existing dataset, update the left-hand side of the GUI with the snippet below:
要创建将返回现有数据集中所有chefs
的查询,请使用以下代码段更新GUI的左侧:
{
chefs {
id,
name
}
}
Now click the Play button on the GUI and you will have the same output as the one below:
现在,单击GUI上的“ 播放”按钮,您将获得与以下输出相同的输出:
As expected, it returns all the static data we currently have in our chefs
array.
正如预期的那样,它返回了我们的chefs
数组中当前拥有的所有静态数据。
To create a mutation that adds a new chef to the existing chefs dataset, we pass in a new name to the addChef
function we defined in the schema. Here’s example code to add a new chef with the name “Chinwe Eze”:
为了创建将新厨师添加到现有厨师数据集中的突变,我们将新名称传递给在架构中定义的addChef
函数。 这是添加名为“ Chinwe Eze”的新厨师的示例代码:
mutation{
addChef(name: "Chinwe Eze"){
id,
name
}
}
You can verify this functionality by running this snippet in the Graphiql GUI, you should get the same behavior as mine below:
您可以通过在Graphiql GUI中运行此代码段来验证此功能,以下行为应与我的相同:
If you’re wondering why we have an id
of 6
for the new chef, it’s because we are generating random IDs for every new chef. You can check back on the schema to verify this feature.
如果您想知道为什么新厨师的id
为6
,那是因为我们为每个新厨师生成了随机ID。 您可以重新检查架构以验证此功能。
If we wanted to update existing data, we could redefine our mutation and use the updateChef
function we defined in the schema to modify existing data. A typical use case would be a user who wants to update their profile information.
如果我们想更新现有数据,则可以重新定义突变,并使用在模式中定义的updateChef
函数来修改现有数据。 典型的用例是想要更新其个人资料信息的用户。
In our case, if we wanted to update the name of an existing chef, all we need to do is pass in the id
of the chef with the new name to the updateChef
function. Let’s update the chef with the name Monique Black
to Simona White
:
在我们的案例中,如果要更新现有厨师的名称,我们要做的就是将具有新名称的厨师的id
传递给updateChef
函数。 让我们将名称Monique Black
的厨师更新为Simona White
:
You’ll notice that this mutation is quite different from the rest because it takes in two arguments. However, a mutation function isn’t just limited to one or just two arguments, it can take as many arguments as you want. The only thing you should be wary about is whether you are passing in the right arguments.
您会注意到,此变异与其余变异完全不同,因为它包含两个参数。 但是,变异函数不仅限于一个或两个参数,它可以根据需要选择任意数量的参数。 您唯一需要警惕的是您是否传递了正确的论点。
Just like every other previous operation we’ve performed with our mutation, we can delete an existing data, in our case, we’ll delete a chef from our existing array of chefs. Again, we can pass in the id
of a chef to the deleteChef
function we defined in the schema and the chef will be removed.
就像我们对突变执行的所有其他先前操作一样,我们可以删除现有数据,在这种情况下,我们将从现有厨师集中删除一个厨师。 再次,我们可以将厨师的id
传递给在架构中定义的deleteChef
函数,然后将删除厨师。
In this post, we took an in-depth look at GraphQL mutations. We demonstrated its concepts like designing mutation schemas, naming and testing mutations, passing in query variables to our mutations, and so on. We went further to create a mini GraphQL project to give you a more practical example on working with GraphQL mutations in real-world applications.
在这篇文章中,我们深入研究了GraphQL突变。 我们演示了其概念,例如设计突变方案,命名和测试突变,将查询变量传递给我们的突变等。 我们进一步创建了一个迷你GraphQL项目,为您提供了在实际应用中使用GraphQL突变的更实际的示例。
In conclusion, Mutations provides us a very flexible way to perform the CUD in CRUD (Create, Read, Update, Delete) without really going through complex data queries or programming logic. Once a schema has been created, and a relationship exists between related data, then there’s not much programming to be done to get the needed data.
总之,突变为我们提供了一种非常灵活的方式来执行CRUD(创建,读取,更新,删除)中的CUD,而无需真正经历复杂的数据查询或编程逻辑。 一旦创建了架构,并且相关数据之间存在关系,那么就不需要进行太多编程来获取所需的数据。
翻译自: https://www.digitalocean.com/community/tutorials/understanding-mutations-in-graphql
vue中的突变方法在哪