今天要來練習寫一下 GraphQL 基本的 CRUD。
先調整一個東西,就是將 users 資料表當中的 id 欄位,變成是 AUTO INCREMENT,執行以下 SQL 即可:
ALTER TABLE `defaultdb`.`users` CHANGE COLUMN `id` `id` INT NOT NULL AUTO_INCREMENT;
使用 GraphQL,練習資料庫的 CRUD,也就是基本的操作,什麼樣的操作呢?
在撰寫 GraphQL 的模式當中,就是先定義好 Schema,之前已經定義過一個,
也就是在 typedefs.ts 檔案當中,有以下的程式碼:
export const typeDefs = gql`
type Query {
hello: String
allUsers: [User!]!
}
type User {
id: ID!
firstname: String!
lastname: String!
}
`;
也就是 CRUD 當中 R(讀取資料) 的部份,我定義了一個 allUsers 的查詢(query),然後必需回傳 User 陣列,至於什麼是 User 呢,就是上面寫的 type User 那段原始碼,也就是回傳的 User 物件要有三個欄位,分別是 id、firstname、lastname。目前這邊是之前寫過的。
那麼接下來要練習寫一下 CRUD 當中,C(建立資料)、U(更新資料)、D(刪除資料) 的部份。這類型是屬於動作類型,所以在 Schema 中,加上以下的 mutation 原始碼:
type Mutation {
insertUser(firstname: String!, lastname: String!): User!
updateUser(id: Int!, firstname: String!, lastname: String!): User!
deleteUser(id: Int!): Boolean!
}
以下附上 typedefs.ts 檔案,完整的原始碼:
import { gql } from "https://deno.land/x/graphql_tag@0.0.1/mod.ts";
export const typeDefs = gql`
type Query {
hello: String
allUsers: [User!]!
}
type Mutation {
insertUser(firstname: String!, lastname: String!): User!
updateUser(id: Int!, firstname: String!, lastname: String!): User!
deleteUser(id: Int!): Boolean!
}
type User {
id: ID!
firstname: String!
lastname: String!
}
`;
上述的 Schema 定義當中,多了 insertUser、updateUser、deleteUser,所以在 resolvers.ts 檔案當中,就需要去實作,所以加上以下三個函式,這三個函式,都是用來針對資料庫做新增資料、更新資料、刪除資料,都是一些簡易的 SQL:
// 新增資料
async function insertUser(args){
let result = await client.execute(`INSERT INTO users(firstname, lastname) values('${args.firstname}', '${args.lastname}')`);
let getInsertedUser = await client.query("select * from ?? where id = ?", ["users", result.lastInsertId]);
return getInsertedUser[0];
}
// 更新資料
async function updateUser(args){
let result = await client.execute(`UPDATE users SET firstname = '${args.firstname}', lastname = '${args.lastname}' WHERE id = ${args.id}`);
let getUser = await client.query("select * from ?? where id = ?", ["users", args.id]);
return getUser[0];
}
// 刪除資料
async function deleteUser(args){
let result = await client.execute(`DELETE FROM users where ?? = ?`, ["id", args.id]);
return (result.affectedRows === 1 ? true : false);
}
然後,原來的以下程式:
export const resolvers = {
Query: {
hello: () => `Hello World!`,
allUsers: () => allUsers()
}
};
改成以下,也就是在 Mutation 當中,加入 insertUser、updateUser、deleteUser 動作,然後會各自執行對應的函式:
export const resolvers = {
Query: {
hello: () => `Hello World!`,
allUsers: () => allUsers()
},
Mutation: {
insertUser: (_: any, args: any) => insertUser(args),
updateUser: (_: any, args: any) => updateUser(args),
deleteUser: (_: any, args: any) => deleteUser(args)
}
};
上述程式更新完之後,就可以使用 GraphQL 的執行環境來測試一下了,這邊測試的回傳結果,不一定會跟讀者的一樣,因為這邊我反覆測試了很多次。
如下示意:
輸入以下的 mutation:
mutation {
insertUser(firstname: "firstname20", lastname: "lastname20"){
id
firstname
lastname
}
}
執行結果如下圖:
輸入以下的 query:
{
allUsers {
id
firstname
lastname
}
}
執行結果如下圖:
輸入以下的 mutation:
mutation {
updateUser(id: 14, firstname: "firstname14", lastname: "lastname14"){
id
firstname
lastname
}
}
執行結果如下圖:
輸入以下的 mutation:
mutation {
deleteUser(id: 14)
}
執行結果如下圖:
完成了基本 GraphQL CRUD,看了些許資料,以及套件的使用,也算是對 GraphQL 有些瞭解了,是個還滿不錯的工具。