iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

今天要來練習寫一下 GraphQL 基本的 CRUD。

先調整一個東西,就是將 users 資料表當中的 id 欄位,變成是 AUTO INCREMENT,執行以下 SQL 即可:

ALTER TABLE `defaultdb`.`users` CHANGE COLUMN `id` `id` INT NOT NULL AUTO_INCREMENT;

什麼是 CRUD?

使用 GraphQL,練習資料庫的 CRUD,也就是基本的操作,什麼樣的操作呢?

  • C:就是 Create,將資料新增至資料庫中。
  • R:就是 Read,讀取資料庫中的資料,將資料抓出來。
  • U:就是 Update,將資料庫裡的資料,做更新。
  • D:就是 Delete,刪除資料庫的的資料。

定義 GraphQL 的 Schema

在撰寫 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!
}
  • insertUser 動作,這邊定義要帶入兩個參數資料,firstname 和 lastname,然後新增資料成功時,會回傳 User 類型的資料。
  • updateUser 動作,這邊定義要帶入三個參數資料,分別是 id、firstname、lastname,然後更新資料成功時,會回傳 User 類型的資料。
  • deleteUser 動作,這邊定義要帶入 id 資料,然後會回傳布靈值資料。

以下附上 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!
  }
`;

撰寫 Resolver 相關的解析函式

上述的 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 基本的 CRUD

上述程式更新完之後,就可以使用 GraphQL 的執行環境來測試一下了,這邊測試的回傳結果,不一定會跟讀者的一樣,因為這邊我反覆測試了很多次。

如下示意:

insertUser 新增 user 資料

輸入以下的 mutation:

mutation {
  insertUser(firstname: "firstname20", lastname: "lastname20"){
    id
    firstname
    lastname
  }
}

執行結果如下圖:
https://ithelp.ithome.com.tw/upload/images/20220907/200699011pU0qrp5E4.png

allUsers 讀取 users 資料

輸入以下的 query:

{
  allUsers {
    id
    firstname
    lastname
  }
}

執行結果如下圖:
https://ithelp.ithome.com.tw/upload/images/20220907/20069901w28VtCIQuV.png

updateUser 更新 user 資料

輸入以下的 mutation:

mutation {
  updateUser(id: 14, firstname: "firstname14", lastname: "lastname14"){
    id
    firstname
    lastname
  }
}

執行結果如下圖:

https://ithelp.ithome.com.tw/upload/images/20220907/20069901VEqCE2Xr2k.png

deleteUser 刪除 user 資料

輸入以下的 mutation:

mutation {
  deleteUser(id: 14)
}

執行結果如下圖:

https://ithelp.ithome.com.tw/upload/images/20220907/20069901hGFVM2dVrH.png


結語

完成了基本 GraphQL CRUD,看了些許資料,以及套件的使用,也算是對 GraphQL 有些瞭解了,是個還滿不錯的工具。


上一篇
使用 Deno 連線資料庫,搭配 GraphQL API 抓取資料
下一篇
Vite + Vue3 建立頁面 - 首頁
系列文
使用 Vue 3 從 0 到 1 架設網站!!!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言