Skip to content

Configuration

Gkernel uses yaml files to describe application configuration. Path to folder containing these files should be passed to Kernel constructor. Config files describe application parameters (like port to listen on, environment etc.), routes, services and event listeners.

Simple example:

import (
    "github.com/bassbeaver/gkernel"
)

...

var configPath string
configPath = "/path/to/config"
kernelObj, kernelError := gkernel.NewKernel(configPath)

It's a good idea to get this path as program argument. This approach is used in gkernel skeleton application:

import (
    "flag"
    "fmt"
    "github.com/bassbeaver/gkernel"
    kernelResponse "github.com/bassbeaver/gkernel/response"
    "net/http"
    "net/http/pprof"
    "os"
)

...

// --- Processing application's arguments and flags
flags := flag.NewFlagSet("flags", flag.PanicOnError)
configPathFlag := flags.String("config", "", "Path to config file")
flagsErr := flags.Parse(os.Args[1:])
if nil != flagsErr {
    panic(flagsErr)
}

// --- Creating application Kernel
var configPath string
if "" == *configPathFlag {
    curBinDir, curBinDirError := os.Getwd()
    if curBinDirError != nil {
        fmt.Println("Failed to determine path to own binary file")
        panic(curBinDirError)
    }
    configPath = curBinDir + "/config"
} else {
    configPath = *configPathFlag
}

kernelObj, kernelError := gkernel.NewKernel(configPath)
if nil != kernelError {
    panic(kernelError)
}

Code above searches for program argument config passed to application during its start, if no argument found it tries to find config directory in its working directory and panics if failed to locate config files path.

For example, if you build you app binary to /etc/gkernel-app and put your config files to /configs/gkernel-app-config it could be like:

/etc/gkernel-app -config /configs/gkernel-app-config

Configuration file overview

Configuration file has next root keys:

  • http_port
  • app_env  
  • templates_path  
  • services  
  • routing  
  • event_listeners  
  • parameters  

http_port

Determines on what port application would be listening for requests.

app_env

Determines current application's environment. This is just a flag thet signals to application's code in what regime it is running. Typically application can have two environments: dev and prod, but you are free to use as many environments as you want.

templates_path

Gkernel uses go html/template package as a template engine to render pages. This templates are parsed during Kernel startup and templates_path key determines where Kernel should search for your templates.

services

services block describes all services in the application. Reading this block Kernel learns what services should be registered in DI container.

Each service should have alias and arguments.
Example:

services:

  Sessions:
    arguments: ["sid", "@SessionsRedisConnection"]

Where Sessions are service alias and

arguments: ["sid", "@SessionsRedisConnection"]

indicates that Sessions service factory requires two arguments and first argument is just simple string with value sid and second argument should be a pointer to the SessionsRedisConnection service (this SessionsRedisConnection service have also to be described in config file).

I want to bring your attention to that config file only describes services and service-factories arguments, and you have to register that factories in your application code.

For more information about services and DI container see "Services and DI container" section.

routing

This block describes routes provided by application. A route is a map from a URL path to the program logic, designed to process requests to that URL (we call that logic - Controller).

Routing block has next sub-blocs: * routes - list of available routes * event_listeners - request-level event listeners common for all routes

Route description looks like:

IndexController:privatePage:
  url: "/private-page"
  methods: ["GET"]
  controller: "IndexController:PrivatePage"
  event_listeners:
    - {event: kernelEvent.RequestReceived, listener: "AuthService:RedirectToLoginIfNotAuthenticated", priority: 41}

Where:

  • IndexController:privatePage - route name
  • url - url or the route, url can contain parameters: "/some-page/:param1"
  • methods - list of HTTP methods allowed for this route
  • controller - controller to process request matched to this route. IndexController is the service alias in DI container and PrivatePage is the name of method to be called to process request.
  • event_listeners - list of request-level event listeners for this route, for more information see "Events and listeners" section.

Whole routing block can look like:

routing:

  routes:

    IndexController:index:
      url: "/"
      methods: ["GET"]
      controller: "IndexController:Index"

    IndexController:loginPage:
      url: "/login"
      methods: ["GET"]
      controller: "IndexController:LoginPage"
      event_listeners:
        - {event: kernelEvent.RequestReceived, listener: "AuthService:RedirectIfAuthenticated", priority: 41}

  event_listeners:
    - {event: kernelEvent.RequestReceived, listener: "RequestLoggerSetter:CreateLogger", priority: 15}
    - {event: kernelEvent.RequestTermination, listener: "RequestLoggerSetter:CloseLogger", priority: 100}

We can see here two routes IndexController:index and IndexController:loginPage. Routes have two common event listeners (RequestLoggerSetter:CreateLogger, RequestLoggerSetter:CloseLogger), this listeners will run at every request.

Also IndexController:loginPage has AuthService:RedirectIfAuthenticated listener, this listener will run only during GET /login request.

event_listeners

This block describes application level event listeners. Can look like:

event_listeners:
  - {event: kernelEvent.ApplicationLaunched, listener: "SessionsMiddleware:InitRedisConnection", priority: 10}
  - {event: kernelEvent.ApplicationTermination, listener: "SessionsMiddleware:CloseRedisConnection", priority: 10}

For more information see "Events and listeners" section.

parameters

This block is simple key-value storage for some application parameters that can change in different environments or run cases.

For example, you need some timeout value for some process and you want this timeout be 30 sec on prod server and 60 sec on dev server. You need to pass this value to corresponding service (in services configuration block). In such case you can define timeout_value parameter, use it by name as service-factory parameter in services section and it's will be stored in parameters section. So for different servers you should only change parameters section of config file.

Example part of config file for prod server:

services:

  SomeService:
    arguments: ["#timeout_value"]

parameters:
  timeout_value: 30

Example part of config file for dev server:

services:

  SomeService:
    arguments: ["#timeout_value"]

parameters:
  timeout_value: 60