🔨
俺でもわかるGraphQLでデータ更新(3)
はじめに
前回はIDによる検索でした。今回はデータ更新系をやってみます。GraphQL界ではMutation
というかっこいい名前で呼ばれてるやつです[1]。
コード
index.js
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Task {
id: ID!
name: String!
isActive: Boolean!
createdAt: Int
updatedAt: Int
owner: String
}
type Query {
tasks: [Task]
task(id: ID!): Task
}
# ❶
type Mutation {
addTask(name: String!): [Task]
completeTask(id: ID!): [Task]
deleteTask(id: ID!): [Task]
}
`;
const tasks = [
{ id: 1, name: "Soak in an Onsen", isActive: true },
{ id: 2, name: "Sing Karaoke", isActive: false },
{ id: 3, name: "See cherry blossom", isActive: true },
]
// ❷
const newId = () => { return Math.max(...tasks.map((t) => t.id)) + 1 }
const resolvers = {
Query: {
tasks: () => tasks,
task (parent, args, context, info) {
const { id } = args;
return context.db.find((task) => task.id == id)
}
},
// ❸
Mutation: {
addTask: async (parent, args, context) => {
context.db.push({
id: newId(),
...args,
isActive: true,
createdAt: Math.floor(Date.now()/1000),
updatedAt: Math.floor(Date.now()/1000)
})
return context.db
},
completeTask: async (parent, args, context) => {
const targetTask = context.db.find(t => t.id == args.id)
if (!targetTask) {
throw new Error("No such task")
} else {
const idx = context.db.indexOf(targetTask)
context.db[idx].isActive = !context.db[idx].isActive;
context.db[idx].updatedAt = Math.floor(Date.now()/1000);
return context.db
}
},
deleteTask: async (parent, task, context) => {
const targetTask = context.db.find(t => t.id == task.id)
if (!targetTask) {
throw new Error("No such task")
} else {
const idx = context.db.indexOf(targetTask)
context.db.splice(idx, 1);
return context.db
}
}
}
};
const server = new ApolloServer({
typeDefs,
resolvers,
context: { db: tasks }
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
変更点は以下
-
Mutation
の型(Type)を定義。いずれも[Task]
としてタスクの配列を返すようにしておきました - IDを自動で採番する関数作成
- ❶のTypeに対応する
Resolver
の関数を書く
こんな感じで機能を足していけばいいみたいです。直感的にわかりやすいですね。
クエリ
これでひととおりCRUDできるようになりました。
# Write your query or mutation here
mutation add {
addTask(name: "Buy some milk") {
id
name
}
}
mutation delete {
deleteTask(id: 5) {
id
name
}
}
query list {
tasks {
id
name
isActive
createdAt
updatedAt
owner
}
}
mutation done {
completeTask(id: 4) {
id
name
isActive
}
}
次回
これでTODOとしてはひととおりのCRUD機能が揃いましたので、次回は以前に書いた以下のSvelteのフロントエンド(REST版)を変更して、今回のGraphQLバックエンドに繋げてみたいと思います。
シリーズ
- 俺でもわかるGraphQLでリスト表示(1)
- 俺でもわかるGraphQLでサーチ(2)
- 俺でもわかるGraphQLでデータ更新(3)
- 俺でもわかるGraphQLでsvelte-apolloクライアント(4)
- 俺でもわかるGraphQLで基本のTodoアプリをSvelteとApolloでやってみる(5)
-
かっこいいけど、わかりやすい呼び名ではないですね。Create, Update, Deleteの総称としていい名前が思いつかなかったのでしょうか ↩︎
Discussion