Dependency Injection
Sometimes you would like to separate routes from your main file.
Normally you would normally decouple them into a plugin like:
// index.ts
const app = new Elysia()
.use(authenRoute)
.use(profileRoute)
// and so on...
// routes/authen.ts
const authen = (app: Elysia) => app
.post('/sign-in', signIn)
.post('/sign-up', signUp)
// index.ts
const app = new Elysia()
.use(authenRoute)
.use(profileRoute)
// and so on...
// routes/authen.ts
const authen = (app: Elysia) => app
.post('/sign-in', signIn)
.post('/sign-up', signUp)
But then sometime, at the main instance introduce some state
, and decorate
that you might need a separated module.
// index.ts
const app = new Elysia()
.decorate('signOut', signOut)
.state('redis', redis)
.use(authenRoute)
.use(profileRoute)
// and so on...
// routes/authen.ts
const authen = (app: Elysia) => app
.post('/sign-in', signIn)
.post('/sign-up', signUp)
// But then there is no type
.post('/sign-out', ({ signOut, store: { db } }) => {
signOut()
db.doSomething()
})
// index.ts
const app = new Elysia()
.decorate('signOut', signOut)
.state('redis', redis)
.use(authenRoute)
.use(profileRoute)
// and so on...
// routes/authen.ts
const authen = (app: Elysia) => app
.post('/sign-in', signIn)
.post('/sign-up', signUp)
// But then there is no type
.post('/sign-out', ({ signOut, store: { db } }) => {
signOut()
db.doSomething()
})
If you hovered over the main app
in index.ts
, you can see that it has some type auto-generated for your main server which might look something like this:
const app: Elysia<{
store: {
redis: Redis;
};
request: {
signOut: () => void;
};
schema: {};
}>
const app: Elysia<{
store: {
redis: Redis;
};
request: {
signOut: () => void;
};
schema: {};
}>
But this type isn't applied to sub-modules.
To apply the type to sub-modules, you can create a plugin which only contains state
and decorate
which caused type side-effect as dependency, and apply to the module you want to use.
const setup = (app: Elysia) => app
.decorate('signOut', signOut)
.state('redis', redis)
// routes/authen.ts
const authen = (app: Elysia) => app
.use(setup)
.post('/sign-in', signIn)
.post('/sign-up', signUp)
// Now it's strictly typed
.post('/sign-out', ({ signOut, store: { db } }) => {
signOut()
db.doSomething()
})
const setup = (app: Elysia) => app
.decorate('signOut', signOut)
.state('redis', redis)
// routes/authen.ts
const authen = (app: Elysia) => app
.use(setup)
.post('/sign-in', signIn)
.post('/sign-up', signUp)
// Now it's strictly typed
.post('/sign-out', ({ signOut, store: { db } }) => {
signOut()
db.doSomething()
})
This will allows you to control access to decorators in modules, this concept is also known as Dependency Injection but only for types.