Skip to main content

TW Controllers

Tegral Web Controllers provides classes and various utilities for building Ktor applications within Tegral.

Features include:

  • Letting Tegral manage your application settings and application lifecycle management
  • Defining your own Ktor modules and controllers as Tegral DI components, and automatically installing them to their appropriate applications.
  • Multiple Ktor applications support within the same DI environment
  • Easy Ktor testing within the DI environment with controllers and modules
Package information
Package nameCatalog dependencyFull Gradle name
tegral-web-controllerstegralLibs.web.controllersguru.zoroark.tegral:tegral-web-controllers:VERSION
tegral-web-controllers-testtegralLibs.web.controllers.testguru.zoroark.tegral:tegral-web-controllers-test:VERSION

Installation

Install the Controllers feature within your application (you do not need to do this if using AppDefaults/AppDSL).

install(WebControllersFeature)

Getting Started

The Controllers extension uses three types of components to do its job.

Note that you will still need to register your components using the usual put() functions.

KtorApplication

The primary class that will host the actual Ktor application needs to inherit from KtorApplication.

This class is responsible for providing the core configuration of the application. This is done by overriding the settings property.

Behind the scenes, this is the class that "holds" the Ktor application instance and is responsible for startup and stopping. All of this is done in KtorApplication.

info

You do not need to add this class yourself when using AppDSL/AppDefaults. A default application class is created for you with sane defaults and uses the web configuration to configure the port and host.

Here is an example:

class MyApplication(scope: InjectionScope) : KtorApplication(scope) {
override val settings get() = KtorApplicationSettings(Netty, port = 8080)
}
caution

Do not forget the get() after val settings, otherwise you will be performing an unsafe injection if you use DI components when building your settings object.

KtorModule

A Ktor module (not to be confused with a Tegral DI module) is a class that inherits from KtorModule. This is a module in the Ktor sense: an extension function on top of Application that adds features, routes, etc.

// As with any regular Tegral DI component, the 'scope: InjectionScope' parameter
// is optional if you do not need it.
class MyModule(scope: InjectionScope) : KtorModule() {
override fun Application.install() {
install(...) {
...
}

routing {
...
}
}
}

KtorController

Ktor controllers are identical to Ktor modules but are more convenient for adding routes and eliminate the need to explicitly call routing { } in the module.

// As with any regular Tegral DI component, the 'scope: InjectionScope' parameter
// is optional if you do not need it.
class MyController(scope: InjectionScope) : KtorController() {
override fun Routing.install() {
get("/hello") {
call.respondText("Hello World!")
}
}
}

Installation order

In case you need to control the order in which your components are installed, you can pass a priority integer to KtorController and KtorModule constructors.

class MyController(scope: InjectionScope) : KtorController(10) {
...
}

class MyModule(scope: InjectionScope) : KtorModule(200) {
...
}

By default:

  • Applications' setup() have a priority of Int.MAX_VALUE and are always installed first.
  • Modules have a priority of 500.
  • Controllers have a priority of 300.

Modules and controllers are installed in the decreasing order of their priority, from largest to smallest.

Controllers and modules that have the same priority are installed in an arbitrary order. Make sure you use priorities if you need a specific order, even if the default order happens to just work for you.

Multiple Ktor apps

Tegral Web Controller supports hosting multiple independent Ktor applications under the same environment.

In order to differentiate between applications (e.g. which controllers are installed where), you can give your applications a name and tell your controllers and modules to install themselves only onto applications of a specific name:

const val AppOneName = "app-one"
const val AppTwoName = "app-two"

class AppOne(scope: InjectionScope) : KtorApplication(scope, AppOneName) {
...
}

class AppTwo(scope: InjectionScope) : KtorApplication(scope, AppTwoName) {
...
}

class ModuleA : KtorModule(restrictToAppName = AppOneName) {
// This module is only installed on AppOne
...
}

class ModuleB : KtorModule(restrictToAppName = AppTwoName) {
// This module is only installed on AppOne
...
}

If you do not specify a name for your application, it gets the name null by default. null is a valid name and has no special meaning (other than that it is the name used by default).