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 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.IndexControlleris the service alias in DI container andPrivatePageis 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