Skip to content

8.5 · GraphQL queries + mutations catalog

บทนี้สรุป GraphQL operations ทั้งหมดที่ vtrc-rc-backoffice ส่งไป vtrc-api — รวม 120 queries + 94 mutations — จัดเป็นกลุ่มฟีเจอร์ พร้อมทั้งระบุไฟล์ที่เก็บและวิธีใช้


ภาพรวม

ประเภทไฟล์บรรทัดจำนวน operations
Queries (main)src/graphql/queries.js4,108120
Mutations (main)src/graphql/mutations.js2,20894
Queries (WorkForce)src/graphql/WorkForce/queries.js~1,500~40
Mutations (WorkForce)src/graphql/WorkForce/mutations.js~900~30
Re-exportsrc/graphql/index.js5

รูปแบบนิยาม — ตัวอย่าง

js
// src/graphql/queries.js (ตัวอย่าง shape)
import gql from "graphql-tag";

const FETCH_USERS = gql`
  query FetchUsers($page: Int, $limit: Int, $search: String) {
    fetchUsers(page: $page, limit: $limit, search: $search) {
      id
      username
      firstName
      lastName
      email
      role { id name }
    }
  }
`;

// ไฟล์ปิดท้ายด้วย export default { ... } ไม่ใช่ export const
export default {
  FETCH_USERS,
  // ... 120 queries
};

ข้อระวังเรื่องรูปแบบ

  1. ใช้ export default { ... } ไม่ใช่ export const — ทำให้ grep หา ^export const ไม่เจอ
  2. ชื่อ query ในไฟล์เป็น UPPER_SNAKE_CASE แต่ operation name ใน gql เป็น camelCase (เช่น FetchUsers)
  3. มี snapshot หลายตัวqueries_bk.js, queries_bk-061265.js, mutations_bk.js — ห้ามใช้

วิธี import ใน component

js
// แบบที่ 1: import ทั้ง object (พบบ่อยในไฟล์เก่า)
import Queries from "../graphql/queries";
import Mutations from "../graphql/mutations";

// ใช้
this.props.client.query({
  query: Queries.FETCH_USERS,
  variables: { page: 1, limit: 20 },
});

// แบบที่ 2: import เฉพาะตัว (พบในไฟล์ใหม่)
import { useQuery } from "@apollo/react-hooks";
import Queries from "../graphql/queries";

const { data, loading } = useQuery(Queries.FETCH_USERS, {
  variables: { page: 1 },
});

ข้อสังเกต

  • ไฟล์เก่าใช้ withApollo HOC + this.props.client.query() (class component)
  • ไฟล์ใหม่ใช้ useQuery hook (function component) — แต่ก็ยังอิงจาก Apollo v2

Queries — จัดกลุ่มตามฟีเจอร์

1. Auth / user / role

Queryความหมาย
MEข้อมูลผู้ใช้ปัจจุบัน
FETCH_USERSรายการผู้ใช้ทั้งหมด
FETCH_USER_BY_IDรายละเอียดผู้ใช้รายคน
FETCH_ROLESรายการ role
FETCH_PERMISSIONSรายการ permission
CHECK_TOKENตรวจ token ที่ login

2. Organization / career / course

Queryความหมาย
FETCH_ORGANIZATIONSรายการหน่วยงาน
FETCH_ORGANIZATION_GROUPSกลุ่มหน่วยงาน
FETCH_CAREERSรายการเส้นทางอาชีพ
FETCH_COURSESรายการหลักสูตร
FETCH_COURSE_BY_IDรายละเอียดหลักสูตร

3. Document / policy

Queryความหมาย
FETCH_DOCUMENTSรายการเอกสาร
FETCH_DOCUMENT_GROUPSกลุ่มเอกสาร
FETCH_POLICIESรายการนโยบาย
FETCH_POLICY_OFFICER_DOCSเอกสารนโยบายสำหรับเจ้าหน้าที่

4. Hospital / medical claim

Queryความหมาย
FETCH_HOSPITALSรายการโรงพยาบาล
FETCH_HOSPITAL_HRโรงพยาบาลฝั่ง HR
FETCH_HOSPITAL_PAIDการเบิกที่จ่ายแล้ว
FETCH_HOSPITAL_FAILEDการเบิกที่ล้มเหลว
FETCH_SICKNESS_NAMESรายการชื่อโรค

5. Leave (ระบบลา)

Queryความหมาย
FETCH_LEAVESรายการใบลา
FETCH_LEAVE_HRใบลาฝั่ง HR
FETCH_LEAVE_STUDIESใบลาศึกษา
FETCH_LEAVE_STUDIES_PAYMENTSการเบิกค่าเล่าเรียน
FETCH_LEAVE_STUDIES_SCHOLARทุนการศึกษา
FETCH_DELEGATESผู้รับมอบฉันทะ

6. Welfare / fund

Queryความหมาย
FETCH_OTHER_WELFAREสวัสดิการอื่น
FETCH_FUNDSกองทุนสงเคราะห์
FETCH_BANK_BRANCHESสาขาธนาคาร

7. News / notification

Queryความหมาย
FETCH_NEWSรายการข่าว
FETCH_NEWS_BY_IDรายละเอียดข่าว
FETCH_NOTIFICATIONSการแจ้งเตือน

8. System / dashboard

Queryความหมาย
FETCH_DASHBOARD_STATSสถิติหน้าแรก
FETCH_SETTINGSการตั้งค่าระบบ
FETCH_ABOUT_USเกี่ยวกับเรา

9. Recruitment

Queryความหมาย
FETCH_ANNOUNCEMENTSประกาศรับสมัคร
FETCH_CANDIDATESผู้สมัคร
FETCH_PREVIEW_EMAILpreview อีเมล

10. WorkForce module (ไฟล์ WorkForce/queries.js)

Queryความหมาย
FETCH_EMPLOYEESรายการพนักงาน
FETCH_POSITIONS_MANAGEตำแหน่งบริหาร
FETCH_POSITIONS_TECHNICALตำแหน่งวิชาการ
FETCH_PROFESSIONAL_LICENSESใบประกอบวิชาชีพ (typo — Perfessional)
FETCH_MANPOWER_MANAGEอัตรากำลัง
FETCH_LEARNINGหลักสูตรฝึกอบรม

Mutations — จัดกลุ่มตามฟีเจอร์

1. Auth / user / role

Mutationความหมาย
LOGINเข้าสู่ระบบ
LOGIN_BACKOFFICElogin สำหรับ backoffice (ต่างจาก vtrc-web)
REFRESH_TOKENขอ token ใหม่
CREATE_USERสร้างผู้ใช้
UPDATE_USERแก้ไขผู้ใช้
DELETE_USERลบผู้ใช้
CHANGE_PASSWORDเปลี่ยนรหัสผ่าน
FORGET_PASSWORDลืมรหัสผ่าน
CONFIRM_USER_A1 / CONFIRM_USER_A2ยืนยันผู้ใช้ 2 ขั้น
SET_PASSWORD_FIRST_TIMEตั้งรหัสผ่านครั้งแรก

2. Organization / career / course

Mutationความหมาย
CREATE_ORGANIZATIONสร้างหน่วยงาน
UPDATE_ORGANIZATIONแก้ไขหน่วยงาน
DELETE_ORGANIZATIONลบหน่วยงาน
CREATE_CAREER / UPDATE_CAREER / DELETE_CAREERจัดการเส้นทางอาชีพ
CREATE_COURSE / UPDATE_COURSE / DELETE_COURSEจัดการหลักสูตร

3. Document / policy

Mutationความหมาย
CREATE_DOCUMENTสร้างเอกสาร
UPDATE_DOCUMENTแก้ไขเอกสาร
DELETE_DOCUMENTลบเอกสาร
CREATE_POLICYสร้างนโยบาย

4. Hospital / medical claim

Mutationความหมาย
CREATE_HOSPITALสร้างโรงพยาบาล
UPDATE_HOSPITAL_PAIDอัปเดตการจ่าย
REJECT_HOSPITAL_CLAIMปฏิเสธการเบิก
IMPORT_HOSPITALimport หลายรายการ

5. Leave (ระบบลา)

Mutationความหมาย
CREATE_LEAVEสร้างใบลา
APPROVE_LEAVEอนุมัติใบลา
REJECT_LEAVEปฏิเสธใบลา
CREATE_LEAVE_STUDIES_PAYMENTสร้างการเบิกค่าเล่าเรียน
APPROVE_LEAVE_STUDIES_PAYMENTอนุมัติการเบิก
CREATE_DELEGATEตั้งผู้รับมอบฉันทะ

6. Welfare / fund

Mutationความหมาย
CREATE_OTHER_WELFAREสร้างสวัสดิการอื่น
APPROVE_OTHER_WELFAREอนุมัติสวัสดิการ
CREATE_FUNDสร้างกองทุน
UPDATE_FUNDแก้ไขกองทุน

7. News / notification

Mutationความหมาย
CREATE_NEWSสร้างข่าว
UPDATE_NEWSแก้ไขข่าว
DELETE_NEWSลบข่าว
MARK_NOTIFICATION_READทำเครื่องหมายว่าอ่านแล้ว

8. Recruitment

Mutationความหมาย
CREATE_ANNOUNCEMENTสร้างประกาศรับสมัคร
UPDATE_CANDIDATE_STATUSอัปเดตสถานะผู้สมัคร
SEND_EMAIL_CANDIDATEส่งอีเมลให้ผู้สมัคร

9. WorkForce module (ไฟล์ WorkForce/mutations.js)

Mutationความหมาย
CREATE_EMPLOYEEสร้างพนักงาน
UPDATE_EMPLOYEEแก้ไขพนักงาน
CREATE_POSITION_MANAGEสร้างตำแหน่งบริหาร
ASSIGN_MANPOWERกำหนดอัตรากำลัง

10. Misc / utility

Mutationความหมาย
UPLOAD_FILEอัปโหลดไฟล์
DELETE_FILEลบไฟล์
EVENT_LOGบันทึก log event

รูปแบบ query ที่ต้องระวัง

Query ที่ return ฟิลด์เยอะมาก

graphql
# ตัวอย่าง — query ที่ดึงฟิลด์เกือบทั้งตาราง
query FetchLeaveStudiesPayments($id: ID!) {
  fetchLeaveStudiesPayments(id: $id) {
    id
    user { id firstName lastName lastNameEn idCard position { id name } organization { id name } }
    amount
    status
    approver { id firstName }
    attachments { id filename url }
    course { id name startDate endDate }
    scholar { id name gpa }
    paymentHistory { id amount date method }
    # ... อีก 30+ ฟิลด์
  }
}

ปัญหา: return payload ใหญ่ ทำให้ response ช้าและ server โหลดหนัก

คำแนะนำ: ดึงเฉพาะฟิลด์ที่ใช้ — แต่ทำได้ยากเพราะใช้ร่วมกันหลาย component

Query ที่มี $search ที่เป็น string ยาว

graphql
query FetchUsers($search: String) {
  fetchUsers(search: $search) { ... }
}

ถ้าผู้ใช้ค้นหาด้วยคำยาว — backend อาจต้อง LIKE '%search%' ทำให้ query DB ช้า (ดู Volume 9 บท 8.4 เรื่อง index)

Mutation ที่รับ input ขนาดใหญ่

graphql
mutation CreateOtherWelfare($input: OtherWelfareInput!) {
  createOtherWelfare(input: $input) { id }
}

OtherWelfareInput มีฟิลด์ 50+ ทำให้ validation ฝั่ง server หนัก และถ้า field validation ผิด 1 ตัว — request ทั้งหมดล้มเหลว


N+1 pattern — ที่พบบ่อย

js
// ในหน้า list ที่มี relation
const { data } = useQuery(Queries.FETCH_LEAVES);
// แล้วใน render:
data.fetchLeaves.map((leave) => (
  <LeaveCard
    key={leave.id}
    leave={leave}
    approver={/* ดึงแยก */}
  />
));

// ใน LeaveCard:
const { data: approverData } = useQuery(Queries.FETCH_USER_BY_ID, {
  variables: { id: leave.approverId },
});

ปัญหา: ถ้ามี 20 รายการใน list จะเกิด 20 request FETCH_USER_BY_ID แยก — เป็น N+1 problem

คำแนะนำ: ให้ query หลัก (FETCH_LEAVES) return relation (approver) มาด้วย — ลดจำนวน request


ข้อระวังเมื่อแก้ไข query

1. อย่าลบฟิลด์โดยไม่ตรวจ

ถ้าลบฟิลด์จาก query (เช่น ลบ email ออกจาก FETCH_USERS) — component อื่นที่อ่าน data.fetchUsers[i].email จะได้ undefined และอาจพัง

วิธีที่ปลอดภัย:

  1. grep ชื่อ query ในไฟล์ทั้งหมด เพื่อหาผู้ใช้
  2. ตรวจว่าทุก component ที่ใช้ query นั้น ยังใช้ฟิลด์ที่จะลบหรือไม่
  3. ถ้าไม่มีผู้ใช้ — ลบได้

2. ระวังการเปลี่ยนชื่อ operation

ถ้าเปลี่ยน FetchUsersGetUsers — ต้องเปลี่ยนทุกที่ที่ import และเรียกใช้

3. อย่าเพิ่ม fragment ในไฟล์เก่า

ไฟล์ queries.js ไม่ได้ใช้ fragment — ทุก query เขียนฟิลด์ตรงๆ ถ้าจะเพิ่ม fragment ต้องทำทั้งไฟล์ ไม่งั้นจะผสม style


เปรียบเทียบกับ vtrc-web

ด้านvtrc-rc-backofficevtrc-web
Query count120~80
Mutation count94~50
รูปแบบ exportexport default { ... }เหมือนกัน
Fragmentไม่ใช้ไม่ใช้
ไฟล์ WorkForceมี (แยก)ไม่มี
withApolloใช้ (module เก่า)ใช้
useQueryใช้ (module ใหม่)ใช้บ้าง

เคล็ดลปตอนค้นหา query

หาว่า query ทำอะไร

  1. grep ชื่อ query ใน src/graphql/queries.js
  2. ดู operation name + argument + return type
  3. ถ้าไม่ชัด — ดูใน Volume 3 บท 3.2 สำหรับ resolver

หาว่าใครใช้ query นี้

bash
# ใน IDE — ใช้ Grep tool
pattern: "FETCH_USERS"
path: src/pages

จะเจอไฟล์ทุกตัวที่ import + เรียก query นี้

หาว่า query ตรงกับ resolver ไหนฝั่ง server

ดู vtrc-api/api/src/typeDefs/*.js และ vtrc-api/api/src/resolvers/*.js (ดู Volume 3)


ขั้นตอนถัดไป

ไป บท 7.6 Component + Recoil + MUI architecture