使用Amplify框架调用GraphQL API

简而言之

本篇文章将介绍如何使用Amplify框架访问GraphQL API。
由于GraphQL的架构已经准备好,我们将主要列举前端与后端进行连接时的具体代码。

实践

当你使用Amplify CLI构建API时,会生成三个文件:queries.js、mutations.js和subscriptions.js。每个查询、变更和订阅都以模块的形式导出,因此你可以从调用方的文件中导入所需的内容。如果直接导入,将包含所有字段,如果只想获取必要的字段,可以删除字段或将其写入到其他文件中。在以下示例中,我们假设使用Nuxt项目,在存储文件中执行GraphQL的各个操作,但无论是从Vue的App.vue还是从React的App.js,基本的graphql方法的编写方式都是相同的。

import { API, graphqlOperation } from 'aws-amplify';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';

export const state = () => ({
  todos:[] ,
  subscription: null
})

export const mutations = {
 /**
   * 取得したtodoデータをstateにセット
   */
  setTodos(state, Todo) {
    state.todos = todo
  },
 /**
   * サブスクリプションをセット
   */
  setSubscription(state, subscription) {
    state.subscription = subscription
  },
}

export const actions = {
  /**
   * Todo一覧を取得
   */
  async listTodos({ state, commit }) {
    try {
      const { data } = await API.graphql(graphqlOperation(listTodos))
      commit('setTodos', data.listTodos.items)
    } catch (e) {
      console.error(e)
    }
  }
  /**
   * Todoを作成
   */
  async createTodo(context, { todo }) {
    try {
      await API.graphql(
        graphqlOperation(createTodo, {
          input:{
            name: todo.name,
            description: todo.description,
            priority: todo.priority
          }
        })
      )
    } catch (e) {
      console.error(e)
    }
  },
  /**
   * Todoの作成を購読
   */
  async subscribe({ state, commit }) {
    const subscription = await API.graphql(graphqlOperation(onCreateTodo)).subscribe({
      next: eventData => {
        const todo = eventData.value.data.onCreateTodo
        commit('updateTodos', [...state.todos, todo])
      }
    })
    commit('setSubscription', subscription)
  },
  /**
   * Todo作成の購読解除
   */
  unsubscribe({ state }) {
    if (!state.subscription) return
    state.subscription.unsubscribe()
  },

首先,在文件的开头导入所需的模块。

import { API, graphqlOperation } from 'aws-amplify';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { onCreateTodo } from './graphql/subscriptions';

如果按照以下的方式编写graphql方法,只需要导入API即可,但是为了更简洁地编写,我们还会导入graphqlOperation。


  await API.graphql({
        query: createTodo,
        variables: {input: todo},
      });

为了减小捆绑大小,您还可以选择仅导入特定类别(在这种情况下是api)。

import API from '@aws-amplify/api';

在中国的本地语言(中文)中,将下面的句子改述为大约只有一种说法:

使用GraphQL的API调用可以像这样写:await API.graphql(graphqlOperation(查询, 参数))。

const { data } = await API.graphql(graphqlOperation(listTodos))
      commit('setTodos', data.listTodos.items)

将返回值赋值给一个名为data的常量,并从对象中提取所需的数据传递给名为’setTodos’的mutation(vuex)。
在此情况下,假设items中存储了一个Todo数组。

await API.graphql(
        graphqlOperation(createTodo, {
          input: {
            name: todo.name,
            description: todo.description,
            priority: todo.priority
            due: todo.due
          }
        })
      )

在Todo的创建中,传递了参数。
参数以对象的形式进行描述,input属性的值存储了一个包含多个属性的对象。
以createTodo函数和名为input的变量名的对象进行传递。
以下是mutations.js文件中的查询语言。

export const createTodo = /* GraphQL */ `
  mutation CreateTodo($input: CreateTodoInput!) {
    createTodo(input: $input) {
      id
      name
      description
      priority
      due
    }
  }
`;

直接この$input変数に先ほどのinputの値を代入します。

await API.graphql(
        graphqlOperation(createTodo, {
          name: todo.name,
          description: todo.description
        })
      )

如果按照这样写的话,还需要修改模式语言方面的代码。

export const createTodo = /* GraphQL */ `
  mutation CreateTodo($input: CreateTodoInput!) {
    createTodo(input: {name:$name, description:$description}) {
      id
      name
      description
      priority
      due
    }
  }
`;

在这个例子中,通过两个变量$name和$description分别接收值。尽管这种写法可能显得冗长,但在希望明确接收值的情况下,可以使用这种方式在模式语言中写作。

由于创建了新的todo,您应该立即显示所创建的内容,但在上述存储文件中,没有使用常量等来接收createTodo的返回值,也没有调用mutation(vuex)。
这是因为正在通过subscription订阅todo的创建事件。

const subscription = await API.graphql(graphqlOperation(onCreateTodo)).subscribe({
      next: eventData => {
        const todo = eventData.value.data.onCreateTodo
        commit('updateTodos', [...state.todos, todo])
      }
    })
    commit('setSubscription', subscription)

在中间,查询和变更的写法与之前相同,但在API.graphql()之后,会使用方法链继续调用subscribe()。
在其中,还会接着使用next:,并在箭头函数中编写使用接收到的数据的处理逻辑。
所谓的接收到的数据是指在onCreateTodo触发时返回的选择集中指定的字段的数据。
在这里,数据被以eventData的名称接收,并嵌套在value→data→onCreateTodo中,最终可以获取到已创建的todo数据。
如果将这些数据传递给mutation(vuex),它将帮助我们更新state中的todos,所以在createTodo中不需要进行commit(也不需要)。
那么,我们所接收的subscription常量又是什么呢?
这是为了停止订阅事件(取消订阅)而接收的Subscription接口。
通过将其保存在state中,我们可以在任意时间点调用取消订阅处理(unsubscribe)。

unsubscribe({ state }) {
    if (!state.subscription) return
    state.subscription.unsubscribe()
  }

如果不执行这个取消订阅操作,那么从订阅开始,事件将一直处于等待状态,所以需要在实例删除时(例如 Nuxt 中的 destroyed 钩子)或其他相应的时机调用此过程。

总结

在介绍使用Amplify框架时可以简单地通过API.graphql()方法连接后端。本次介绍仅涉及基本内容,希望能够在以后介绍如何使用过滤器进行筛选、使用AppSyncSDK的编写方式,以及与S3的连接并进行图像发送处理等方面的内容。

广告
将在 10 秒后关闭
bannerAds