Skip to content
CodeSook
CodeSook

06.Controller Runtime

Controller runtime

สำหรับ Effect จะต้องใช้ runtime ในการรัน Runtime ของ Effect ชื่อว่า fiber

อย่างที่บอกไปก่อนหน้าว่า function ของเราต้องมี Layers ก่อนจึงจะทำงานได้
เราสามารถเอา Layers ทั้งหลายมารวมๆกันไว้ในที่เดียว แล้วสร้าง Runtime ที่มี Layers เหล่านั้นอยู่
เวลาเราเอา Runtime นี้ไปใช้งานเราก็ไม่ต้องคอย เอา Layers ไป inject เอง ตัว Runtime มันจะทำให้แบบ auto

Terminal window
src
├── configure
├── controllers
├── index.ts
├── repositories
├── runtimes
└── index.ts
├── schema
├── services
├── telemetry
└── types

เราก็จะสร้าง servcies runtime แบบนี้

import { Layer, ManagedRuntime } from "effect"
import { EmployeeRepositoryContext } from "../repositories/employees/index.js"
import PrismaClientContext from "../repositories/prisma.js"
import { EmployeeServiceContext } from "../services/employee/index.js"
const PrismaClientLive = PrismaClientContext.Live
const EmployeeServiceLive = EmployeeServiceContext.Live.pipe(
Layer.provide(EmployeeRepositoryContext.Live),
Layer.provide(PrismaClientLive),
)
export const ServicesLive = Layer.mergeAll(
EmployeeServiceLive,
)
export const ServicesRuntime = ManagedRuntime.make(ServicesLive)
// ^? ManagedRuntime<EmployeeServiceContext | OvertimeServiceContext | Resource, never>

แก้ที่ controller ให้มาเรียกใช้ ServicesRuntime แบบนี้

import { ServicesRuntime } from "../../runtimes/index.js"
... other stuff ...
app.get("/", getManyDocs, async (c) => {
const parseResponse = Helpers.fromObjectToSchemaEffect(getManyResponseSchema)
const program = EmployeeServiceContext.pipe(
// ^? Effect.Effect<..., never, EmployeeServiceContext>
Effect.tap(() => Effect.log("start finding many employees")),
Effect.andThen(svc => svc.findMany()),
Effect.andThen(parseResponse),
Effect.andThen(data => c.json(data, 200)),
Effect.tap(() => Effect.log("test")),
Effect.catchTags({
FindManyEmployeeError: () => Effect.succeed(c.json({ message: "find many error" }, 500)),
ParseError: () => Effect.succeed(c.json({ message: "parse error" }, 500)),
}),
Effect.annotateLogs({ key: "annotate" }),
Effect.withLogSpan("test"),
Effect.withSpan("controller /"),
)
const result = await ServicesRuntime.runPromise(program)
return result
})

จะเห็นว่าที่ program เราต้องการ EmployeeServiceContext แต่ว่าก็ไม่มี Error เพราะว่า