Configuration

Configs

Alpas uses strongly typed config classes for configuring the framework. All these configs live in the configs folder.

Custom Configs

Any classes that implement dev.alpas.config interface will be discovered and loaded automatically without you having to do anything to load it. You can then later ask for a singleton copy of your config class using a DI container.

Here is an example of how you could create your own config class and then how to access its properties from a controller:


class AdminConfig(env: Environment) : Config {
    val adminEmail = env("ADMIN_EMAIL", "admin@example.com")
}


class AdminController : Controller() {
    fun show(call: HttpCall) {
        val email = call.make<AdminConfig>().adminEmail
    }
}

/tip/ Instead of hard coding configurable variables that you use in different parts of your app, we highly recommend that you use a config class instead. Configs are strongly typed, get loaded automatically, and, if you want, can easily overwrite values using environment variables.

Overriding Core Configs

Since Alpas is a convention based web framework, almost everything is configured with some sane defaults. In case you want to change the default values or add new values to one of the core config classes, you can do it easily.

To change a core config, create a new config class that extends the core config and override the properties you want to change.

Let's say you want to change the default extension of your view templates from .peb, which is set in dev.alpas.view.ViewConfig class, to .twig. To do this, first create a new class under configs folder and override the value like so:


class ViewConfig(env: Environment) : dev.alpas.view.ViewConfig(env) {
    // change existing config
    override val templateExtension = ".twig"

    // add new config
    val layoutTemplate = "layouts/app"
}

/info/ Just like custom config classes, once declared, Alpas automatically loads these extended config classes instead of the parent core config classes. So don't worry about how to load them; just declare and forget!

/tip/ Depending on what you are trying to accomplish, you may be able to avoid extending core config classes by simply setting the appropriate variables in your .env file.

Environment

There are situations when you want to set some configs used in your app based on an environment. This allows you, for an example, to set values based on whether you are developing your app or deploying it.

You also don't want these configs to be compiled with your app as you want to easily deploy your app without having to recompile a deployment copy after changing some configurations.

Also, if you are using some third-party API keys/secrets, you don't want to hard code these and include them in version control. This is very risky from a security standpoint.

To make this flexible, Alpas allows you to configure values in an .env file that lives in the root of your project. The variables in this file get loaded automatically and are available for you in pretty much anywhere you need.

/info/ When you initialize your app using alpas init command, an .env file with some defaults is automatically created for you.

It is very important that you don't commit this .env file in the app's source control for mainly two reasons. First, this file could contain some secret API keys that you don't want to accidentally make available for everyone. Second, different developers on your team might want to use different environment configurations. This is true for different servers as well.

When you need to share some configurations with your team, the convention is to use an .env.example file that usually contains the same keys but with different placeholder values.

/alert/ You must have an .env file in your root project during development and right next to your final jar file during deployment.

/info/ If an .env.testing file is present, this gets loaded instead of .env in test mode. This allows you to have the flexibility of running tests with a different set of configurations.

System Environment Variables

In addition to the variables defined in your .env file, Alpas loads all your system wide environment variables and makes them available in the same manner. In fact, system wide environment variables take precedence over the variables defined in your .env file.

/tip/ We highly recommend using system wide environment variables for more critical configurations such as secret keys and API keys rather than defining them in your .env file.

Accessing Variables

In some places, such as the config classes, if you ask for an environment variable as a constructor parameter, Alpas automatically injects an instance of dev.alpas.Environment. In other places, such as your controllers, you can access any available environment variables through an env object.

Here is an example of how you could access an environment variable named SSO_SHARED_SECRET from your controller:


class SsoLoginController : Controller() {
    fun login(call: HttpCall) {
        val ssoSecret:String? = call.env('SSO_SHARED_SECRET')
    }
}

Checking your environment

The dev.alpas.Environment class has a few more convenient properties that you could use to determine the current environment and query some of its properties.

  • isProduction

Check if your app is running in production mode. If APP_LEVEL environment variable is set to one of prod, production, or live, then it is considered to be in production mode.

  • isDev

Check if your app is in development mode. If APP_LEVEL environment variable is set to one of dev, debug, or local, then it is considered to be in development mode.

  • storagePath

The full path to a folder named storage where the "byproducts" created during the runtime such as logs, file sessions, etc. are saved. This folder should always be at the root of your project during development and next to your jar file during production.