11. Implement Employee Services
Let’s create interface for Employee Repository
เราจะมาสร้าง interface หรือ type กันก่อน เหมือนเดิม
ตรงนี้สำคัญมาก
เราจะต้องเห็นภาพรวมก่อนว่าจะทำอะไรบ้าง จะมีอะไรบ้าง
โดยคนที่สร้าง interface เหล่านี้จะเป็นคนที่ต้องทำงานในส่วนของ Business logic หรือก็คือคนที่เขียน services นั่นแหละ
interface หรือ type นี้จะเป็นคนบอก controller ว่ามีอะไรให้ใช้บ้าง
จะเห็นว่า Business หรือ Service คือศูนย์กลางของ app เรา
Folder Structure
src├── configure/├── controllers/├── index.ts├── repositories│ ├── employees5 collapsed lines
│ │ ├── creates.ts│ │ ├── finds.ts│ │ ├── index.ts│ │ ├── removes.ts│ │ └── updates.ts│ └── prisma.ts├── schema8 collapsed lines
│ ├── branded.ts│ ├── employee.ts│ ├── employeeWithRelations.ts│ ├── general.ts│ ├── helpers.ts│ ├── index.ts│ ├── overtime.ts│ └── overtimeWithRelations.ts├── services│ ├── employee│ │ ├── create.ts│ │ ├── finds.ts│ │ ├── index.ts│ │ ├── removes.ts│ │ └── updates.ts└── types ├── repositories │ ├── employee.ts └── services ├── employee.ts
Interface for Employee Service
เราจะมาสร้าง interface หรือ type สำหรับ Employee Service กันก่อน
ย้ำอีกที เหตุผลก็คือ
อยากให้เห็นภาพก่อนว่าจะต้องทำอะไรบ้าง Services ที่จะสร้าง Business ต้องการอะไรบ้าง เราทำ REST API เรามี Services อะไรให้ Controller เรียกใช้ได้บ้าง
types/services/employee.ts
import type { Branded, EmployeeSchema, EmployeeWithRelationsSchema } from "../../schema/index.js"
export type EmployeeService = { create: (data: EmployeeSchema.CreateEmployee) => Promise<EmployeeSchema.Employee> findMany: () => Promise<EmployeeWithRelationsSchema.EmployeeWithRelationsArray> findOneById: (id: Branded.EmployeeId) => Promise<EmployeeWithRelationsSchema.EmployeeWithRelations | null> update: (id: Branded.EmployeeId, data: EmployeeSchema.UpdateEmployee) => Promise<EmployeeSchema.Employee | null> removeById: (id: Branded.EmployeeId) => Promise<EmployeeSchema.Employee | null>}
เราจะทำ Dependencies injection เหมือนกันแต่ถ้าดูจาก interface ด้านบน จะไม่รู้ว่าเราก็ทำ Dependencies injection นะ
Create Employee Services
เราจะยังทำ dependencies injection เหมือนเดิม
ถ้าอยากได้ Create employee service ก็ต้องส่ง Employee Repository เข้ามาก่อน
services/employee/create.ts
import type { EmployeeRepository } from "../../types/repositories/employee.js"import type { EmployeeService } from "../../types/services/employee.js"
export function create(employeeRepository: EmployeeRepository): EmployeeService["create"] { return async (data) => { const employee = await employeeRepository.create(data) return employee }}
Find Employee Services
services/employee/finds.ts
import type { EmployeeRepository } from "../../types/repositories/employee.js"import type { EmployeeService } from "../../types/services/employee.js"
export function findMany(employeeRepository: EmployeeRepository): EmployeeService["findMany"] { return async () => { return employeeRepository.findManyWithRelations() }}
export function findOneById(employeeRepository: EmployeeRepository): EmployeeService["findOneById"] { return async (id) => { return employeeRepository.findByIdWithRelations(id) }}
Update Employee Services
services/employee/updates.ts
import type { EmployeeRepository } from "../../types/repositories/employee.js"import type { EmployeeService } from "../../types/services/employee.js"
export function update(employeeRepository: EmployeeRepository): EmployeeService["update"] { return async (id, data) => { return employeeRepository.update(id, data) }}
Remove Employee Services
services/employee/removes.ts
import type { EmployeeRepository } from "../../types/repositories/employee.js"import type { EmployeeService } from "../../types/services/employee.js"
export function removeById(employeeRepository: EmployeeRepository): EmployeeService["removeById"] { return (id) => { return employeeRepository.remove(id) }}
Export all employee services
ตรงนี้ก็ทำคล้ายๆเดิม export ทุก functions ที่ file index.ts
import type { EmployeeRepository } from "../../types/repositories/employee.js"import type { EmployeeService } from "../../types/services/employee.js"import * as Creates from "./create.js"import * as Finds from "./finds.js"import * as Removes from "./removes.js"import * as Updates from "./updates.js"
export function initEmployeeService(employeeRepository: EmployeeRepository): EmployeeService { return { create: Creates.create(employeeRepository), findMany: Finds.findMany(employeeRepository), findOneById: Finds.findOneById(employeeRepository), removeById: Removes.removeById(employeeRepository), update: Updates.update(employeeRepository), }}