Ktor Module 可以用来组织程序码,本身仅是一个 Application 类别的 extension function,让 server 启动时执行而已。Ktor 并没有规定 Module 内部应该如何实作,也没有限制 Module 的颗粒度要多大,官方文件只提到 module 可以是某些 plugin 及 routes 的集合。例如我可以实作一个 Shutdown module,其 extension function 的内部实作是安装 Ktor ShutdownUrl plugin,藉此增加1个 GET route,让外界呼叫此 GET API 後能停止 server。
实作上,我把每个子专案当作是一个 Ktor module,而且都依赖於 infrastrcture module。infrastrcture module 负责安装 Ktor Plugin,提供底层的函式库及功能。我建立了2个子专案 ops 及 club,透过设定 ktor.application.modules 属性值,Ktor 会在启动时依序执行这3个 module 的 extension fuction。设定时要注意 infra module 必须要放在第一个位置。
application {
modules = [
fanpoll.infra.ApplicationKt.main,
fanpoll.ops.OpsProjectKt.opsMain,
fanpoll.club.ClubProjectKt.clubMain
]
}
其中 infra module 的 extension function 内部实作是负责初始化 Ktor plugin 及 ProjectManager
fun Application.main() {
install(LoggingFeature)
install(DatabaseFeature)
install(RedisFeature)
install(Authentication)
// ...以下省略
koin {
modules(
module(createdAtStart = true) {
single { ProjectManager(get()) }
}
)
}
// ...以下省略
}
club module 的 extension function 内部实作是负责初始化 club 专案。第一步是先透过 Koin DI 取得 ProjectManager 物件,然後载入 club 专案设定档,最後再建立 club Project 物件并注册至 ProjectManager
每个子专案可各自定义以下项目,infra module 再根据 project 物件执行相对应的功能
fun Application.clubMain() {
val projectManager = get<ProjectManager>()
val projectConfig = ProjectManager.loadConfig<ClubConfig>(ClubConst.projectId)
projectManager.register(
Project(
ClubConst.projectId,
projectConfig.auth.principalSourceAuthConfigs,
ClubUserType.values().map { it.value },
ClubOpenApi.Instance,
ClubNotification.AllTypes
)
)
// ...以下省略
}
class Project(
override val id: String,
val principalSourceAuthConfigs: List<PrincipalSourceAuthConfig>,
val userTypes: List<UserType>,
val projectOpenApi: ProjectOpenApi,
val notificationTypes: List<NotificationType>? = null
) : IdentifiableObject<String>()
今天从程序开发层面说明如何使用 Ktor Module 进行模组化开发,明天将会从建置部署层面切入,说明如何使用 Gradle Multi-Project Builds 建置专案、还有使用 Gradle Shadow Plugin 及 Docker Compose 打包部署。
我把从第一天到现在每天的 Home 目录都放上 GitHub 了,README.md 里面有说明 ...
身为一个没有Android手机的用户 当要测试程序时,又借不到Android手机,怎麽办呢?? An...
什麽是特徵 根据官网的解释就是 特徵会告诉编译器特定型别与其他型别共享的功能。可以使用特徵定义来抽象...
前言 Tableau 轻松学 系列文章也已经到了尾声,从带着读者从头认识 Tableau 并且调查人...
从我们上一篇设计出的实体关系模型 ( Entity - Relationship Model, E-...