Configuration
Gkernel uses yaml files to describe application configuration. Path to folder containing this files should be passed to Kernel constructor. Config files describe application parameters (like port to listen on), web routes, CLI commands, services and event listeners.
Simple example:
import (
webKernel "github.com/bassbeaver/gkernel/web"
)
...
var configPath string
configPath = "/path/to/config"
kernelObj, kernelError := webKernel.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"
webKernel "github.com/bassbeaver/gkernel/web"
kernelResponse "github.com/bassbeaver/gkernel/web/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 := webKernel.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:
- services
- web
- cli
- event_listeners
- parameters
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:
SessionsMiddleware:
arguments: ["sid", "@RedisConnection"]
Where SessionsMiddleware
are service alias and
arguments: ["sid", "@RedisConnection"]
indicates that SessionsMiddleware
service factory requires two arguments and
first argument is just simple string with value sid
and second argument should be a pointer to the RedisConnection
service (this RedisConnection
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.
web
This block describes all configuration related to web part of application (and used by web Kernel).
Web block has next keys:
* http_port
Determines on what port application would be listening for HTTP requests.
* templates_path
Web Kernel of Gkernel uses go html/template package as a template engine to render pages.
This templates are parsed during Kernel startup and web.templates_path
key determines where Kernel should search for your templates.
* shutdown_timeout
Graceful shutdown timeout for http server in milliseconds, if not set default value of 500 will be used.
* routing
Routing key describes routes provided by application. More detailed description will be further.
web.routing
This sub block describes web 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-blocks: * 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 nameurl
- url or the route, url can contain parameters:"/some-page/:param1"
methods
- list of HTTP methods allowed for this routecontroller
- controller to process request matched to this route.IndexController
is the service alias in DI container andPrivatePage
is the method name ofIndexController
service 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 web
block can look like:
web:
http_port: 8081
templates_path: "web/templates"
shutdown_timeout: 5000
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:SetLoggerToRequestContext", 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:SetLoggerToRequestContext
, RequestLoggerSetter:CloseLogger
), these listeners will run at every request.
Also IndexController:loginPage
has AuthService:RedirectIfAuthenticated
listener, this listener will run only during GET /login
request.
cli
This block describes console commands provided by application. A command is a map from CLI arguments to the program logic, designed to process such CLI requests.
CLI block has next sub-blocks: * commands - list of available commands
Command description looks like:
CliController:command1:
name: command1
controller: "CliController:Command1"
help: "first cli command"
Where:
CliController:command1
- command alias (not used by Gkernel)name
- name of command. Gkernel search this name in CLI arguments passed to programcontroller
- controller to process command.CliController
is the service alias in DI container andCommand1
is the method name ofCliController
service to be called to process command.help
- string for full command description shown when running the command with the--help
option. Also,help
strings of all commands CLI Kernel returns byKernel.GetHelp()
orKernel.FormatHelp()
methods.
Whole cli
block can look like:
cli:
commands:
CliController:command1:
name: command1
controller: "CliController:Command1"
help: "first cli command"
event_listeners
This block describes application level event listeners. Can look like:
event_listeners:
- {event: kernelEvent.ApplicationLaunched, listener: "RedisConnectionMiddleware:InitRedisConnection", priority: 10}
- {event: kernelEvent.ApplicationTermination, listener: "RedisConnectionMiddleware: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