คู่มือติดตั้งและเชื่อมต่อ
การ deploy ระบบขึ้น server และการเชื่อมต่อจาก API SMT Front / API OPA Front
สารบัญ
1. สถาปัตยกรรมระบบ
[Client ภายนอก]
│
▼
https://pvd.ktam.co.th
│
├── /WSSMTFront → API SMT Front ──→ API SMT Back (Back อยู่ภายใน ห้ามออกตรง)
└── /OPA_SMT → API OPA Front ──→ API OPA Back
│ ▲
push log / เช็คสถานะ │ │ ตอบสถานะเปิด-ปิด
▼ │
KTAM-API-CENTER (ระบบนี้)
- KTAM-API-CENTER เรียกออกภายนอกได้เฉพาะ
https://pvd.ktam.co.thเท่านั้น (ใช้ตอน health check) - ฝั่ง Back ห้ามเรียก API-CENTER โดยตรง — Front เป็นผู้ relay log ของ Back และส่งต่อสถานะเปิด/ปิดให้ Back
- ไม่ใช้ database — ทะเบียน API เก็บที่
App_Data/apis.jsonและ log เก็บที่App_Data/logs/yyyyMMdd.jsonl
2. ขึ้น server แล้วต้องเปลี่ยน path หรือไม่?
ไม่ต้องเปลี่ยน path ของ endpoint ที่ลงทะเบียนไว้ — ทั้ง 836 เส้นเก็บเป็น path สัมพัทธ์ (เช่น
/api/SMT/setcustomerchangepassword_v2) แยกจาก BaseUrl ดังนั้น URL จริง = BaseUrl + path เหมือนเดิมทุกสภาพแวดล้อมสิ่งที่อาจต้องปรับเมื่อ deploy มีเพียง 2 จุด:
| กรณี | สิ่งที่ต้องแก้ | แก้ที่ไหน |
|---|---|---|
ชื่อ IIS application ของ Front ไม่ตรงกับที่ตั้งไว้ (ปัจจุบัน WSSMTFront และ OPA_SMT) |
แก้ BaseUrl ของ service นั้น |
App_Data/apis.json ของ API-CENTER |
| URL ของ API-CENTER บน server (เช่น ย้ายจาก localhost ไป server จริง) | แก้ URL ที่ Front ใช้เรียกเข้ามา (เช็คสถานะ / push log) | appsettings.json ของ SMT Front และ OPA Front |
ฝั่ง Back ไม่ต้องแก้อะไรเลย เพราะ API-CENTER ไม่เรียก Back ตรง และ Back ไม่เรียก API-CENTER ตรง
3. การติดตั้ง KTAM-API-CENTER บน server (IIS)
3.1 เตรียมเครื่อง server
- ติดตั้ง .NET 10 Hosting Bundle (ASP.NET Core Runtime + IIS Module) แล้ว restart IIS
- เปิด role IIS พร้อม WebSocket ไม่จำเป็น — ระบบใช้ HTTP ปกติ
3.2 Publish โปรเจค
cd C:\Nilecon\Project\KTAM\CENTER-API\CENTER-API dotnet publish -c Release -o C:\publish\KTAM-API-CENTER
โฟลเดอร์ publish จะมี
App_Data/apis.json (ทะเบียน API ทั้ง 836 เส้น) ติดไปด้วยอัตโนมัติ3.3 สร้าง site บน IIS
- สร้าง Application Pool ใหม่ → .NET CLR = No Managed Code
- สร้าง Website/Application ชี้ physical path ไป
C:\publish\KTAM-API-CENTER - สำคัญ: ให้สิทธิ์
IIS_IUSRS(หรือ identity ของ App Pool) Modify ที่โฟลเดอร์App_Dataเพราะระบบเขียนไฟล์ log และบันทึกสถานะเปิด/ปิดลงไฟล์ - แนะนำติดตั้งเป็นระบบภายใน (intranet) — หน้าเว็บนี้ไม่ควรเปิด public
3.4 ทดสอบหลังติดตั้ง
# เปิด browser ไปที่หน้า Dashboard http://<server>:<port>/ # ทดสอบ REST API GET http://<server>:<port>/api/center/status → ต้องได้ JSON รายการ 4 services
4. ค่า config ที่ต้องตรวจสอบ (appsettings.json ของ API-CENTER)
"CenterApi": {
"SystemName": "KTAM-API-CENTER",
"GatewayEndpoint": "https://pvd.ktam.co.th", // host เดียวที่อนุญาตให้ health check ออก
"DataFolder": "App_Data", // ที่เก็บ apis.json และ log
"LogRetentionDays": 30, // เก็บ log กี่วัน (เกินแล้วลบอัตโนมัติ)
"MaxBodyLength": 20000 // ตัด body ที่ยาวเกิน (ตัวอักษร)
}
5. การเชื่อมต่อจากฝั่ง Front (SMT Front / OPA Front)
ติดตั้งให้แล้วทั้ง 4 โปรเจค — เพิ่ม
ApiCenter/ApiCenterMiddleware.cs + section "ApiCenter" ใน appsettings.json ของ
WSSMTFront, WSSMTBack, API_OPA_FRONT, API_OPA_BACK และเพิ่ม Controllers/CenterRelayController.cs ใน Front ทั้งสองสำหรับ relay ฝั่ง Back
สิ่งเดียวที่ต้องแก้ตอน deploy คือค่า ApiCenter:BaseUrl ให้ตรงกับ server จริง (middleware เป็นแบบ fail-open — ถ้า center ล่มหรือ URL ผิด ระบบเดิมทำงานตามปกติ)
| โปรเจค | Mode | ServiceId | BaseUrl ชี้ไปที่ |
|---|---|---|---|
| WSSMTFront | direct | smt-front | KTAM-API-CENTER (เช่น https://uat-pvd.ktam.co.th/APICENTER) |
| WSSMTBack | relay | smt-back | SMT Front (https://uat-pvd.ktam.co.th/WSSMTFront) |
| API_OPA_FRONT | direct | opa-front | KTAM-API-CENTER (เช่น https://uat-pvd.ktam.co.th/APICENTER) |
| API_OPA_BACK | relay | opa-back | OPA Front (https://uat-pvd.ktam.co.th/OPA_SMT) |
รายละเอียด config ใน
appsettings.json ของโปรเจค Front:"ApiCenter": {
"BaseUrl": "http://<server-api-center>:<port>",
"ServiceId": "smt-front", // opa-front สำหรับ OPA
"BackServiceId": "smt-back", // opa-back สำหรับ OPA
"StatusCacheSeconds": 30
}
5.1 เช็คสถานะเปิด/ปิดก่อนให้บริการ —
GET /api/center/status/{serviceId}?path=...// ตัวอย่าง: เรียกตอนรับ request (ควร cache ผลไว้ตาม StatusCacheSeconds เพื่อไม่ให้หน่วง)
public async Task<bool> IsApiEnabledAsync(string path)
{
var url = $"{_centerBaseUrl}/api/center/status/{_serviceId}?path={Uri.EscapeDataString(path)}";
using var resp = await _httpClient.GetAsync(url);
if (!resp.IsSuccessStatusCode) return true; // center ล่ม → เปิดให้บริการตามปกติ (fail-open)
var json = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
return json.RootElement.GetProperty("enabled").GetBoolean();
}
// ใน middleware หรือ action filter ของ Front
if (!await IsApiEnabledAsync(HttpContext.Request.Path))
{
context.Response.StatusCode = 503;
await context.Response.WriteAsJsonAsync(new { success = false, message = "API ปิดให้บริการชั่วคราว" });
return;
}
5.2 ส่ง log หลังตอบ response —
POST /api/center/logs// แนะนำยิงแบบ fire-and-forget เพื่อไม่หน่วง response
public void PushLog(HttpContext ctx, int statusCode, long durationMs,
string requestBody, string responseBody, string correlationId)
{
var entry = new
{
serviceId = _serviceId, // "smt-front" หรือ "opa-front"
method = ctx.Request.Method,
path = ctx.Request.Path.Value,
statusCode,
durationMs,
clientIp = ctx.Connection.RemoteIpAddress?.ToString(),
correlationId,
requestBody, // ควร mask ข้อมูล sensitive เช่น password/pin
responseBody
};
_ = _httpClient.PostAsJsonAsync($"{_centerBaseUrl}/api/center/logs", entry); // ไม่ await
}
คำแนะนำด้านความปลอดภัย: mask ค่า password, PIN, เลขบัตร, token ใน requestBody/responseBody ก่อนส่งมาเก็บที่ API-CENTER เสมอ
6. การส่ง log ของฝั่ง Back (relay ผ่าน Front)
ติดตั้งให้แล้ว: Back ทั้งสอง (WSSMTBack, API_OPA_BACK) ใช้ middleware ตัวเดียวกันในโหมด
relay —
เช็คสถานะและส่ง log ผ่านเส้น /api/CenterRelay/* ของ Front ซึ่ง Front จะ forward ต่อไปยัง KTAM-API-CENTER ให้อัตโนมัติ
หลักการทำงานของ relay:
- แบบที่ 1 (แนะนำ): Front เป็นคนบันทึก log แทน Back — Front รู้อยู่แล้วว่าเรียก Back เส้นไหน ได้ status อะไร ใช้เวลาเท่าไร ให้ Front ส่ง log 2 รายการต่อ 1 request (ของตัวเอง serviceId=
smt-frontและของ Back serviceId=smt-back) - แบบที่ 2: Back เก็บ log ลงไฟล์/ตารางชั่วคราวของตัวเอง แล้วให้ Front มีตัว job ดึงไป relay เป็นชุดผ่าน
POST /api/center/logs/batch
// ตัวอย่างแบบที่ 1 — ใน Front หลังเรียก Back เสร็จ
var backLog = new
{
serviceId = _backServiceId, // "smt-back" หรือ "opa-back"
method = "POST",
path = "/api/smt/setcustomerchangepassword_v2", // path ของ Back ที่เรียก
statusCode = (int)backResponse.StatusCode,
durationMs = backElapsedMs,
correlationId, // ใช้ตัวเดียวกับ log ของ Front เพื่อ trace ข้ามชั้นได้
requestBody = maskedBackRequest,
responseBody = maskedBackResponse
};
_ = _httpClient.PostAsJsonAsync($"{_centerBaseUrl}/api/center/logs", backLog);
// ตัวอย่างแบบที่ 2 — batch relay
// POST {center}/api/center/logs/batch body: [ {log1}, {log2}, ... ]
การเปิด/ปิดของ Back ก็เช่นกัน — Front ดึงสถานะ
smt-back/opa-back จาก GET /api/center/status แล้วตัดสินใจไม่ส่งต่อไป Back เมื่อถูกปิด7. Checklist ก่อนใช้งานจริง
- ☐ ติดตั้ง .NET 10 Hosting Bundle บน server และ restart IIS แล้ว
- ☐ App Pool = No Managed Code และ
IIS_IUSRSมีสิทธิ์ Modify ที่App_Data - ☐ เปิด
GET /api/center/statusแล้วเห็น 4 services ครบ - ☐
BaseUrlใน apis.json ตรงกับชื่อ IIS application จริงของ Front (WSSMTFront,OPA_SMT) - ☐ ตั้งค่า
ApiCenter:BaseUrlใน appsettings ของ SMT Front / OPA Front ชี้มาที่ server API-CENTER - ☐ ทดสอบปิด API 1 เส้นจากหน้า "จัดการ API" แล้วยิงเส้นนั้น → Front ต้องตอบ 503
- ☐ ยิง request ทดสอบแล้วเห็น log ขึ้นในหน้า "Log Request/Response"
- ☐ ข้อมูล sensitive (password/PIN/token) ถูก mask ก่อนส่ง log
- ☐ กดปุ่ม "ตรวจสถานะปลายทาง" ในหน้าจัดการ API แล้ว Front ทั้งสองตอบกลับ