11.1 · API topology
บทนี้วาดภาพรวมว่าระบบ VTRC มี API services กี่ตัว, แต่ละตัวใช้ transport อะไร, ใครเรียกใคร, และควรเลือกใช้ตัวไหนเมื่อไร
ภาพรวม — 3 services
┌─────────────────────────────┐
│ vtrc-web / vtrc-rc-backoffice │
│ (frontend — ทุก layer) │
└─────────────────────────────┘
│
│ HTTPS
│ GraphQL + REST
▼
┌─────────────────────────────┐
│ vtrc-api │
│ port 8081 │
│ - GraphQL /api/graphql │
│ - REST (file, PDF, upload) │
│ - 265 GraphQL ops │
│ - 30 REST endpoints │
└─────────────────────────────┘
│
│ GraphQL via
│ END_POINT_CENTRALIZE
│ (CLIENT_TARGET ตัวอย่าง :8082;
│ CODE_DEFAULT APP_PORT=8080)
▼
┌─────────────────────────────┐
│ cu-central-api │
│ APP_PORT default 8080 │
│ - GraphQL /api/graphql │
│ - REST /auth/* (signin, ...) │
│ - 83 GraphQL ops │
│ - 5 REST endpoints │
│ - SourceDB sharding │
└─────────────────────────────┘
┌─────────────────────────────┐
│ centralize-api (NestJS) │ ← caller ไม่ยืนยันใน workspace
│ port 3000 │ (อาจถูกเรียกจาก vtrc-api
│ - REST /api/* │ ผ่าน env อื่น หรือ
│ - 17 endpoints │ ถูกเรียกโดย service อื่น
│ - Swagger /docs │ นอก workspace นี้)
└─────────────────────────────┘1. vtrc-api — service หลัก
ข้อมูลพื้นฐาน
| ด้าน | ค่า |
|---|---|
| ภาษา | JavaScript (ESM, Node.js) |
| Framework | Apollo Server 2 + Express |
| Port | 8081 (default APP_PORT) |
| GraphQL path (prod) | /api/graphql |
| GraphQL path (UAT) | /api-uat/graphql |
| REST path | ใต้ root / (env API_PREFIX_PATH) |
| DB | MariaDB (2 schemas: vtrc + vtrc-centralize) |
| ORM | Sequelize |
| API docs | ไม่มี (ไม่มี Swagger สำหรับ GraphQL) |
หน้าที่
- เป็น service เดียว ที่ frontend ทั้งคู่ (
vtrc-web,vtrc-rc-backoffice) คุยด้วยตรง ๆ - รับ request จากผู้ใช้ทุกประเภท (พนักงาน, HR, admin)
- ส่วนใหญ่ forward ไป cu-central-api สำหรับข้อมูล HR master
Entry point
1:121:index.js
import express from 'express'
import routes from './routes'
// ...
const server = new ApolloServer({
typeDefs,
resolvers,
schemaDirectives: { auth },
context: async ({ req }) => { /* ... */ },
formatError: graphqlFormatError,
})
server.applyMiddleware({ app, path: API_SERVICE_PATH }) // /api/graphqlดูรายละเอียดใน Volume 3 บท 3.1
2. cu-central-api — service ที่ vtrc-api เรียก
ข้อมูลพื้นฐาน
| ด้าน | ค่า |
|---|---|
| ภาษา | JavaScript (ESM, Node.js 12) |
| Framework | Apollo Server 2 + Express |
| Port | CODE_DEFAULT APP_PORT=8080 (CLIENT_TARGET ใน vtrc .env.example อาจเป็น 8082; compose มัก 8000; EXPOSE 9000 ≠ listen) |
| GraphQL path | /api/graphql |
| REST path | /auth/* (signin, signout, token, signinbypass) |
| DB | MSSQL (5 connections, แต่ละ connection เป็น schema ต่างกัน) |
| ORM | Sequelize (dialect tedious) |
| Auth เสริม | LDAP/Active Directory (ldapjs) |
| Cache | Redis (session + short-lived) |
| API docs | ไม่มี |
หน้าที่
- เป็น legacy CU auth/HR service ที่ vtrc-api forward ไปผ่าน
END_POINT_CENTRALIZE - จัดการ authentication (LDAP bind, JWT issue, session)
- ให้ข้อมูล HR master (พนักงาน, ตำแหน่ง, สาขา, payroll, leave balance) จาก HRMI MSSQL
- มี SourceDB sharding — แยกข้อมูลตามหน่วยงาน (โรงพยาบาลจุฬา, สภากาชาดฯ, ...)
ทำไม frontend ไม่คุยตรง
- เพราะ vtrc-api เป็น gateway ที่แปลงข้อมูล, เพิ่ม business logic, และคุม auth ของระบบ VTRC
- frontend ไม่รู้จัก cu-central-api และไม่รู้ SourceDB ของผู้ใช้
ดูรายละเอียดใน Volume 4
3. centralize-api — NestJS facade
ข้อมูลพื่นฐาน
| ด้าน | ค่า |
|---|---|
| ภาษา | TypeScript |
| Framework | NestJS 9 |
| Port | 3000 (default PORT) |
| Global prefix | api → ทุก path เริ่มด้วย /api/ |
| REST path | /api/* (17 endpoints) |
| GraphQL | ไม่มี |
| DB | MSSQL (2 connections: center + nbc) |
| ORM | TypeORM 0.3 |
| Validation | class-validator + class-transformer |
| API docs | Swagger/OpenAPI ที่ /docs |
หน้าที่
- เป็น read-mostly facade สำหรับ HRMI MSSQL
- ให้ข้อมูล employee, organization, position, payroll — คล้าย cu-central-api แต่เป็น NestJS
- ใช้ raw SQL เกือบทั้งหมด ไม่ได้ใช้ ORM feature เต็มที่
Caller ไม่ยืนยัน
- ใน workspace นี้ ไม่พบหลักฐาน ว่าใครเรียก centralize-api
END_POINT_CENTRALIZEใน vtrc-api ชี้ไป cu-central-api (CLIENT_TARGET ตัวอย่าง 8082; CODE_DEFAULT 8080) ไม่ใช่ centralize-api (port 3000)- ทีมงานระบุว่าอาจถูกเรียกผ่าน env
NEW_CENTRAIL_APIหรือCENTRALIZE_SERVERในbenefit-api— แต่ repo เหล่านั้นไม่อยู่ใน workspace
ดูรายละเอียดใน Volume 5
Transport comparison — GraphQL vs REST
| ด้าน | GraphQL | REST |
|---|---|---|
| vtrc-api | ใช้ (265 ops) | ใช้ (30 endpoints — file, PDF, export) |
| cu-central-api | ใช้ (83 ops) | ใช้ (5 endpoints — auth เท่านั้น) |
| centralize-api | ไม่มี | ใช้ (17 endpoints) |
ทำมีทั้งคู่
- GraphQL ใช้สำหรับ query/mutation ทั่วไป — ยืดหยุ่น, frontend เลือก field
- REST ใช้สำหรับ binary data (file, PDF, Excel) ที่ GraphQL ไม่เหมาะ
เลือกใช้ตัวไหนเมื่อไร
| ต้องการ | ใช้ |
|---|---|
| ดึง/แก้ข้อมูลทั่วไป | GraphQL |
| ดาวน์โหลด PDF (payslip, tax) | REST |
| อัปโหลดไฟล์ | GraphQL Upload scalar หรือ REST multer |
| Export Excel/ZIP | REST |
| ดึงรายงานสรุป | REST |
| Authentication (login, refresh) | cu-central-api REST /auth/* |
Endpoint count ต่อ service
vtrc-api GraphQL 265 ops REST 30 endpoints รวม 295
cu-central-api GraphQL 83 ops REST 5 endpoints รวม 88
centralize-api REST 17 endpoints รวม 17
ระบบรวม 400 API surfacePath convention
vtrc-api
| Environment | GraphQL | REST |
|---|---|---|
| Production | https://vtrcapi.redcross.or.th/api/graphql | https://vtrcapi.redcross.or.th/<path> |
| UAT | https://uat-vtrcapi.redcross.or.th/api-uat/graphql | https://uat-vtrcapi.redcross.or.th/<path> |
API_PREFIX_PATH env กำหนด prefix ของ REST — ค่า default คือ string ว่าง (prod) ทำให้ path เป็น /file/:id, /upload, ...
cu-central-api
| Environment | GraphQL | REST |
|---|---|---|
(CLIENT_TARGET ตัวอย่างใน vtrc .env.example) | http://localhost:8082/api/graphql | http://localhost:8082/auth/signin |
(CODE_DEFAULT APP_PORT=8080) | http://localhost:8080/api/graphql | http://localhost:8080/auth/signin |
cu-central-api ไม่เปิดสู่ internet โดยตรง — เรียกผ่าน vtrc-api เท่านั้น (compose มัก map 8000; Dockerfile EXPOSE 9000 ≠ listen)
centralize-api
| Environment | REST | Docs |
|---|---|---|
| Production | http://10.188.128.160:3000/api/* | http://10.188.128.160:3000/docs |
| Local | http://localhost:3000/api/* | http://localhost:3000/docs |
centralize-api อยู่ใน intranet (LAN) เท่านั้น
ใครเรียกใคร — call graph
vtrc-web ─────┐
├─► vtrc-api ──► cu-central-api (GraphQL + REST auth)
vtrc-rc- │ │
backoffice ───┘ ├─► LDAP/AD (auth)
├─► MSSQL shards (HRMI data)
├─► Redis (session)
├─► SSO HTTP API
├─► HRMI HTTP API (external REST)
├─► SMTP/SMS gateway
└─► Conicle SFTP
centralize-api ─► MSSQL (center + nbc)
(caller ภายนอก workspace)สำคัญ
- frontend ทั้งคู่คุย vtrc-api อย่างเดียว — ไม่มีการเรียก cu-central-api หรือ centralize-api โดยตรง
- vtrc-api → cu-central-api เป็นการ forward ที่ซับซ้อน (retry, refresh token) — ดู บท 10.9
- centralize-api เป็นเกาะ ใน workspace นี้ — caller ยังไม่ยืนยัน
Port summary
| Service | Port | Transport | เปิดสู่ internet? |
|---|---|---|---|
| vtrc-api | 8081 | HTTPS | ใช่ (ผ่าน reverse proxy) |
| cu-central-api | CODE_DEFAULT 8080 (CLIENT_TARGET ตัวอย่าง 8082; compose มัก 8000) | HTTP (internal) | ไม่ (เรียกจาก vtrc-api เท่านั้น) |
| centralize-api | 3000 | HTTP (intranet) | ไม่ (เฉพาะ LAN) |
Tech stack comparison
| ด้าน | vtrc-api | cu-central-api | centralize-api |
|---|---|---|---|
| ภาษา | JS (ESM) | JS (ESM) | TypeScript |
| Framework | Apollo 2 + Express | Apollo 2 + Express | NestJS 9 |
| Node | 14+ | 12 | 16+ |
| ORM | Sequelize | Sequelize | TypeORM |
| DB | MariaDB | MSSQL | MSSQL |
| Cache | Redis (optional) | Redis | ไม่มี |
| Auth | JWT (HS256) + apiKey | JWT (HS256) + apiKey + LDAP | JWT guard (bypassed) |
| Validation | GraphQL schema | GraphQL schema | class-validator |
| Docs | ไม่มี | ไม่มี | Swagger |
| Test | ไม่มี | ไม่มี | ไม่มี (มี config แต่ไม่มี spec) |