vue中的突变方法在哪_了解GraphQL中的突变

益炜
2023-12-01

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 Mutation schema)

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属性,该属性又具有另外两个子属性,分别是addChefresolve函数。

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
})

创建变异 (Creating a Mutation)

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就会认识到我们不仅在尝试从某处获取数据,而且还想更改此类数据。

命名突变 (Naming Mutations)

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来引用此突变。

将查询变量传递给突变 (Passing Query Variables to Mutations)

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
  }
}

建立一个应用程序 (Building an App)

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突变从一系列厨师中创建,更新和删除特定厨师。

设置开发服务器 (Setting Up a Development Server)

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初始化一个空项目。 然后继续为应用程序安装所有必需的依赖项:

  • npm i express express-graphql app-root-path

    npm我表达express-graphql应用程序根路径

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文件,然后使用以下代码对其进行更新:

config/port.js
config / port.js
export const PORT = process.env.PORT || 9091

创建其他项目文件 (Creating Other Project Files)

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文件,它将用作我们的应用程序入口文件。 然后使用以下代码对其进行更新:

app.js
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脚本:

package.json
package.json
"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.

此脚本命令使我们能够快速启动应用程序的本地服务器,而无需键入太多终端命令。

创建应用逻辑和API (Creating the App Logic and API)

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文件,并使用以下代码对其进行更新:

/server/model/index.js
/server/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文件,并使用以下代码对其进行更新:

./server/schema/index.js
./服务器/架构/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文件,并使用以下代码对其进行更新:

app.js
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}`);
})

启动服务器 (Starting the server)

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"}

在Graphiql上测试突变 (Testing the Mutations on Graphiql)

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数组中当前拥有的所有静态数据。

创建新厨师 (Creating a New Chef)

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.

如果您想知道为什么新厨师的id6 ,那是因为我们为每个新厨师生成了随机ID。 您可以重新检查架构以验证此功能。

更新现有厨师 (Updating an Existing Chef)

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.

您会注意到,此变异与其余变异完全不同,因为它包含两个参数。 但是,变异函数不仅限于一个或两个参数,它可以根据需要选择任意数量的参数。 您唯一需要警惕的是您是否传递了正确的论点。

删除厨师 (Deleting a Chef)

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函数,然后将删除厨师。

结论 (Conclusion)

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中的突变方法在哪

 类似资料: