使用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的连接并进行图像发送处理等方面的内容。