balaur

package module
v0.0.0-...-ed03032 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 11, 2015 License: MIT Imports: 9 Imported by: 0

README

#Balaur An app container for goji app

Build Status GoDoc views

#Table of contents

#Usage NOTE You don't have to follow this structure, you are free to define your own structure, this structure is just my convention

For example I have a web app and it has 2 parts, user and blog, with balaur it would be like this:

Structure

├── main.go
├── blog
│   ├── app.go
│   ├── controller.go
│   ├── middleware.go
│   ├── config.toml
│   ├── middlewares.toml
│   └── routes.toml
└── user
    ├── app.go
    ├── controller.go
    ├── middleware.go
    ├── config.toml
    ├── middlewares.toml
    └── routes.toml

user app.go should handle creation of user app and boot the app (the same applies to blog)

here's what the basic app should look like

package user
import (
	"github.com/sendyhalim/balaur"
)

func init() {
	var ctrl = &UserController{}
	// 1st param is the directory path relative to your root app
	// 2nd param is the configs (app, route, and middleware must be supplied)
	// 3rd param is RouteRegistrar interface
	// 4th param is MiddlewareRegistrar interface 
	// by default basic registrar will be created for you if you pass nil but of course you can create your own registrar 
	// as long as it conforms the interface
	var app = balaur.NewApp("user", map[string]string{
		"app":        "config.toml",
		"route":      "routes.toml",
		"middleware": "middlewares.toml",
	}, nil, nil)
    
    // register the controller, it will be mapped by route registrar
	app.Controllers["user"] = ctrl
	// register middlewares, the middleware will be registered for the app's parent route (set in routes.toml)
	// app.Controller["authMiddleware"] = authMiddleware
	// then in middlewares.toml:
	// [[middleware]]
	// key = "authMiddleware" 
	app.Boot()
}

App config (config.toml)

name = "User App"

routes config (routes.toml)

parent = "/*"

[[route]]
path       = "/users"
verb       = "GET"
controller = "user"
method     = "Index"

[[route]]
path       = "/users/:id"
verb       = "GET"
controller = "user"
method     = "Get"

User controller.go

package user

import (
	"net/http"
	"github.com/sendyhalim/balaur/context"
)

type UserController struct {
}

func (a *UserController) Index(c context.ContextInterface, r *http.Request) (string, int) {
	return "User index!", http.StatusOK
}

func (a *UserController) Get(c context.ContextInterface, r *http.Request) (string, int) {
	return "User id: " + c.GetParam("id"), http.StatusOK
}

then in main.go

package main

import (
	_ "myproject/user"
	_ "myproject/blog"
	"github.com/sendyhalim/balaur"
	"github.com/zenazn/goji"
)

func main() {
    // balaur.GetApp(appName)
	goji.Handle("/*", balaur.GetApp("User App").Mux)
	goji.Handle("/*", balaur.GetApp("Blog App").Mux)
	goji.Serve()
}

#Custom

##Route Registrar You can inject your own route registrar by creating custom registrar and inject it(3rd param) when you use balaur.NewApp().

type RouteRegistrar interface {
	// 1st param is goji Mux
	// 2nd param is routes config (balaur already convert routes config as Config interface)
	// 3rd param is the mapping of app controllers
	RegisterRoutes(*web.Mux, []Config, map[string]interface{})
}

By creating your own custom route registrar, you can gain full flexibility on controller methods. Here's balaur.BasicRouteRegistrar code (full)

type ControllerMethod func(context.ContextInterface, *http.Request) (string, int)

type BasicRouteRegistrar struct {
	// ControllerMethodWrapper is assigned when NewBasicRouteRegistrar() is called
	ControllerMethodWrapper func(ControllerMethod) web.HandlerFunc
}

func (r *BasicRouteRegistrar) RegisterRoutes(mux *web.Mux, routes []Config, controllers map[string]interface{}) {
	for _, config := range routes {
		controller := config.Get("controller", true)
		method := config.Get("method", true)
		verb := config.Get("verb", true)
		path := config.Get("path", true)
		methodInterface := reflect.ValueOf(controllers[controller]).MethodByName(method).Interface()
		methodValue := methodInterface.(func(context.ContextInterface, *http.Request) (string, int))
		handler := r.ControllerMethodWrapper(methodValue)

		switch verb {
		case "GET":
			mux.Get(path, handler)
		case "POST":
			mux.Post(path, handler)
		case "PUT":
			mux.Put(path, handler)
		case "DELETE":
			mux.Delete(path, handler)
		}
	}
}

As you can see by creating custom registrar, you can also modify controller methods type. If you only want to use different context (by default goji context is used), just do this

var routeRegistrar *BasicRouteRegistrar = balaur.NewBasicRouteRegistrar()
routeRegistrar.ControllerMethodWrapper = func(method balaur.ControllerMethod) web.HandlerFunc {
	fn := func(c web.C, w http.ResponseWriter, r *http.Request) {
		// as long as it conforms context.ContextInterface, then you can inject any 
		// custom context to  BasicRouteRegistrar's  ControllerMethod
		response, code := method(&GorillaContext, r)
		// do something else..
	}
	return web.HandlerFunc(fn)	
}

// create app and inject routeRegistrar manually
var app = balaur.NewApp("user", map[string]string{
		"app":        "config.toml",
		"route":      "routes.toml",
		"middleware": "middlewares.toml",
}, routeRegistrar, nil)

##Middleware Registrar You can inject your own middleware registrar by creating custom registrar and inject it (4th param) when you use balaur.NewApp().

type MiddlewareRegistrar interface {
	// 1st param is goji Mux
	// 2nd param is middlewares config (balaur already convert middlewares config as Config interface)
	// 3rd param is the mapping of app controllers
	RegisterMiddlewares(*web.Mux, []Config, map[string]interface{})
}

BasicMiddlewareRegistrar is really simple, it just maps the middleware config based on its index

type BasicMiddlewareRegistrar struct {}

func (r *BasicMiddlewareRegistrar) RegisterMiddlewares(mux *web.Mux, middlewareConfigs []Config, middlewares map[string]interface{}) {
	for _, m := range middlewareConfigs {
		key := m.Get("key", true)

		mux.Use(middlewares[key])
	}
}

TODOs

  • Better API documentation
  • Scaffolding tools (automatic app generation e.g balaur mkapp blog then create the basic templates inside the given dir)

Notes

for now balaur only use toml as config, but it will support more config types in the future (such as json)

Support

I will always improve and support this project as I'm using balaur for most of my projects.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AddApp

func AddApp(app *App)

func RemoveApp

func RemoveApp(name string)

func TotalApps

func TotalApps() int

Types

type App

type App struct {
	Name                    string
	Priority                int
	Controllers             map[string]interface{}
	Middlewares             map[string]interface{}
	ControllerMethodWrapper func(method ControllerMethod) web.HandlerFunc
	Mux                     *web.Mux
	AppRouteRegistrar       RouteRegistrar
	AppMiddlewareRegistrar  MiddlewareRegistrar
	// contains filtered or unexported fields
}

func GetApp

func GetApp(name string) *App

func NewApp

func NewApp(dir string, configs map[string]string, rr RouteRegistrar, mr MiddlewareRegistrar) *App

func (*App) Boot

func (a *App) Boot()

func (*App) Config

func (a *App) Config(section string) Config

type BasicMiddlewareRegistrar

type BasicMiddlewareRegistrar struct {
}

func NewBasicMiddlewareRegistrar

func NewBasicMiddlewareRegistrar() *BasicMiddlewareRegistrar

func (*BasicMiddlewareRegistrar) RegisterMiddlewares

func (r *BasicMiddlewareRegistrar) RegisterMiddlewares(mux *web.Mux, middlewareConfigs []Config, middlewares map[string]interface{})

type BasicRouteRegistrar

type BasicRouteRegistrar struct {
	ControllerMethodWrapper func(ControllerMethod) web.HandlerFunc
}

func NewBasicRouteRegistrar

func NewBasicRouteRegistrar() *BasicRouteRegistrar

func (*BasicRouteRegistrar) RegisterRoutes

func (r *BasicRouteRegistrar) RegisterRoutes(mux *web.Mux, routes []Config, controllers map[string]interface{})

type Config

type Config interface {
	Get(string, bool) string
	GetArray(string, bool) []string
	GetChildren(string, bool) []Config
}

func NewConfig

func NewConfig(path string) Config

type ControllerMethod

type ControllerMethod func(context.ContextInterface, *http.Request) (string, int)

type MiddlewareRegistrar

type MiddlewareRegistrar interface {
	RegisterMiddlewares(*web.Mux, []Config, map[string]interface{})
}

type RouteRegistrar

type RouteRegistrar interface {
	RegisterRoutes(*web.Mux, []Config, map[string]interface{})
}

type TomlConfig

type TomlConfig struct {
	// contains filtered or unexported fields
}

func NewTomlConfig

func NewTomlConfig(path string) *TomlConfig

func (*TomlConfig) Get

func (tmc *TomlConfig) Get(key string, errorIfNotExist bool) string

func (*TomlConfig) GetArray

func (tmc *TomlConfig) GetArray(key string, errorIfNotExist bool) []string

func (*TomlConfig) GetChildren

func (tmc *TomlConfig) GetChildren(key string, errorIfNotExist bool) []Config

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL