Skip to content

Facade

Facades provide a public API for cross-module access. When one module needs to use functionality from another module, it should inject a Facade, not a Service or Repo.

Invalid cross-module access will result in a build error and runtime exception.

users/users.facade.ts
const Users = Vla.createModule('Users')
class UserFacade extends Users.Facade {
service = this.inject(UserService)
async getUser(id: string) {
return this.service.findById(id)
}
async hasPermission(userId: string, permission: string) {
return this.service.checkPermission(userId, permission)
}
}
// posts/posts.service.ts
const Posts = Vla.createModule('Posts')
class PostService extends Posts.Service {
users = this.inject(UserFacade) // ✅ Cross-module access
async createPost(userId: string, data: PostData) {
const canPost = await this.users.hasPermission(userId, 'post:create')
if (!canPost) {
throw new Error('Permission denied')
}
// Create post...
}
}
  • Public interface for cross-module dependencies

transient - New instance created per usage.

static readonly scope = 'transient'

Facades inherit the inject() method.

  • Scope: transient (new instance per usage)
  • Purpose: Public interface for modules
  • Can inject: Services, Repos (same module), other Facades, Resources, Contexts
  • Best practices: Only expose what other modules need