Folder Structure

Flow
|user Request==> API Gateway ==> API Service| ==> Route Folder ==> Controller Folder ==> Service Folder ==> Repository Folder ==> dcConenct | Database |
repository
ประกอบไปด้วยฟังก์ชั่นสำหรับเชื่อมต่อ database เพื่อ ดึงข้อมูล เพิ่มข้อมูล แก้ไขข้อมูล
โดยจะแยกตามประเภทของข้อมูลและ ประเภทของการดึงข้อมูล
จากรูปจะแบ่งการจัดการข้อมูลเป็น 2 ส่วน คือ jwt และ userและ แบ่งเป็น 2 ไฟล์คือ
commands.ts จะมีฟังก์ชั่น เพิ่ม แก้ไข หรือลบข้อมูล เช่น เพิ่มพนักงาน, ลบพนักงาน
queries.ts จะมีฟังก์ชั่น เพื่อดึงข้อมูล เช่น ดึงข้อมูลพนักงานทั้งหมด, ดึงข้อมูลพนักงานตามรหัสพนักงาน
services
เป็นส่วนของ business model จะเป็นตัวกลางระหว่าง repository กับ controller ทำหน้าที่ประมวลผลหรือ คิดคำนวณข้อมูลต่างๆตามที่ controller ร้องขอ
โดยจะแยกตามประเภทของ service เช่น - jwt ซึ่งใช้ในการจัดการเกี่ยวกับระบบ jwt - user ซึ่งใช้ในการจัดการเกี่ยวกับระบบ user
เช่น การสร้าง jwt token 1. controller จะร้องขอ jwt token ใหม่ 2. service สร้าง token ขั้นมา 3. service ส่งไป insert ผ่าน repository 4. service ส่งค่า jwt token ที่สร้างมาใหม่คืนให้ controller
controller
ไฟล์ Controller จะรับ Request จาก Routes และนำ Requrest ไปหาผลลัพธ์เพื่อส่งกลับไปเป็น HTTP Response
static Login = async (
req: Request<any, any, LoginBodyType, IpQueryRequestType>,
res: Response,
next: NextFunction
): promiseResponseDTO<string | UserDTO> => {
try {
const { userId, password, org, trackingstatus } = req.body;
if (!isLoginBodyType(req.body)) return BadRequest(res, 'bad param');
const userData = await this.userManager.Login(org, userId, password);
const jwtToken = await this.jwtGenerator.CreateToken(
userData,
req.query.ipAddress,
trackingstatus || 'F'
);
this.setToken(res, jwtToken.token, jwtToken.refreshToken);
return res.send({ ...userData, token: jwtToken.token });
} catch (err: any) {
return BadRequest(res, err.message);
}
};
middleware
ฟังก์ชั่นที่สามารถเข้าไปจัดการกับ request object (req) , response object (res) และ ฟังก์ชั่น next() ที่อยู่กระบวนการเกิดของ request-response cycle next() คือฟังก์ชั่นที่อยู่ใน express router ซึ่งเมื่อมีการเรียกใช้งาน จะเป็นการไปทำงานใน middleware ฟังก์ชั่นในลำดับถัดไป จากฟังก์ชั่นปัจจุบัน
เช่น - เรา controller ต้องการรู้ IP ที่ส่งเข้ามาแต่จะให้ตัว controller มี code ที่ดึงค่า IP จาก header มาทุกครั้งก็ ดูจะเป็นการเขียน code ที่ซ้ำกันเยอะเกิน เราลยทำ middleware เพื่อที่จะ set ip address ใส่ไว้ใน request เพื่อให้ตัว controller สามารถดึงมาใช้ได้เลย - ต้องการเช็ค ตัว request body ว่าข้อมูลที่ส่งมามีครบตามที่ต้องการหรือไม่
export const setIPAddress = (req: Request, res: Response, next: NextFunction) => {
const ip = requestIp.getClientIp(req);
req.query.ipAddress = ip == null ? 'Unknown' : ip;
next();
};
export const RequireJWTtoken = (req: Request, res: Response, next: NextFunction) => {
const token = getToken(req);
if (!token) {
return BadRequest(res, 'A token is required for authentication');
}
next();
};
routes
เก็บ router path ของ api ควรจะเป็นไฟล์ไฟล์เดียว แต่อาจจะเก็บแยกเป็น V1, V2 ของแต่ละ version ของ api ก็ได้
เป็นส่วนใช้ middleware ในการจัดการข้อมูลก่อนที่จะถึง controller ที่เราต้องการให้ทำงานเป็นตัวหลักโดยที่ถ้า middleware ตัวไหนไม่ผ่านก็จะไม่ทำ middleware ตัวต่อไป
เช่น /api/user/logout RequireJWTtoken : มี jwttoken ส่งมารึป่าว VerifyToken : token ที่ส่งมาถูกต้องมั้ย LoginController.Logout : เมื่อผ่าน middleware ข้างต้นแล้วถึงจะมา จัดการ logout
#src/index.ts
const app = express();
app.use(setIPAddress);
app.use('/', routes);
#src/routes/index.ts
const router = express.Router();
router.post('/api/user/login', LoginController.Login);
router.post('/api/user/logout', RequireJWTtoken, VerifyToken, LoginController.Logout);
router.post('/api/user/changepassword', RequireJWTtoken, VerifyToken, LoginController.Logout);
router.post('/api/user/forcepassword', RequireJWTtoken, VerifyToken, LoginController.ForcePassword);
router.post('/api/user/refresh-token', LoginController.RefreshToken);
utils
Utilities and Helpers ที่ต้องเอาไว้แชร์ Application เช่น function ที่เอาไว้ใช้คำนวณ offset ของ query ที่ใช้สำกรับการแบ่งหน้า, function ที่เอาไว้จัดการกับ response ว่า error handle มาเป็นแบบนี้ต้องส่ง status code เป็นอะไร
__tests__
จะมีโครงสร้างเหมือน src สำหรับเอาไว้ทำ unit test โดนเรื่อง unit test จะพูดถึงในหัวข้อเรื่อง jest
Last updated