biu

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jan 12, 2018 License: LGPL-3.0 Imports: 29 Imported by: 0

README

BIU

a set of toolkits for go-restful.

GitHub release GoDoc Go Report Card

Installation

go get -u github.com/tuotoo/biu

Examples

pkg-examples

Contributing

All our projects follow the GitFlow branching model, from development to release. If you are not familiar with it, there are several guides and tutorials to make you understand what it is about.

Documentation

Overview

Example
package main

import (
	"strconv"

	"github.com/emicklei/go-restful"
	"github.com/tuotoo/biu"
)

// Foo controller
type Foo struct{}

// WebService implements CtlInterface
func (ctl Foo) WebService(ws biu.WS) {
	ws.Route(ws.GET("/").To(biu.Handle(ctl.getBar)).
		Param(ws.QueryParameter("num", "number").DataType("integer")).
		Doc("Get Bar").DefaultReturns("Bar", Bar{}), &biu.RouteOpt{
		Errors: map[int]string{
			100: "num not Number",
		},
	})

	// add more routes as you like:
	// ws.Route(ws.POST("/foo"),nil)
	// ...
}

// Bar is the response of getBar
type Bar struct {
	Msg string `json:"msg"`
	Num int    `json:"num"`
}

func (ctl Foo) getBar(ctx biu.Ctx) {
	numStr := ctx.QueryParameter("num")
	num, err := strconv.Atoi(numStr)
	if ctx.ContainsError(err, 100) {
		return
	}
	ctx.ResponseJSON(Bar{Msg: "bar", Num: num})
}

func main() {
	restful.Filter(biu.LogFilter())
	biu.AddServices("/v1", nil,
		biu.NS{
			NameSpace:  "foo",
			Controller: Foo{},
			Desc:       "Foo Controller",
		},
	)
	// Note: you should add swagger service after adding services.
	// swagger document will be available at http://localhost:8080/v1/swagger
	swaggerService := biu.NewSwaggerService(biu.SwaggerInfo{
		Title:        "Foo Bar",
		Description:  "Foo Bar Service",
		ContactName:  "Tuotoo",
		ContactEmail: "jqs7@tuotoo.com",
		ContactURL:   "https://tuotoo.com",
		Version:      "1.0.0",
		RoutePrefix:  "/v1",
	})
	restful.Add(swaggerService)
	biu.Run(":8080", nil)
}
Output:

Index

Examples

Constants

View Source
const MIME_HTML_FORM = "application/x-www-form-urlencoded"

nolint MIME_HTML_FORM is application/x-www-form-urlencoded header

Variables

View Source
var CommonResponse = func(w http.ResponseWriter,
	code int, message string, data interface{}) {
	if err := writeJSON(w, http.StatusOK, CommonResp{
		Code:    code,
		Message: message,
		Data:    data,
	}); err != nil {
		Warn("json encode", Log().Err(err))
	}
}

CommonResponse is a response func. just replace it if you'd like to custom response.

Functions

func AddErrDesc

func AddErrDesc(m map[int]string)

AddErrDesc adds map of code-message to stdCodeDesc

func AddServices

func AddServices(prefix string, filters []restful.FilterFunction, wss ...NS)

AddServices adds services with namespace.

func AssertJSON

func AssertJSON(t *testing.T, data []byte, v interface{})

AssertJSON unmarshal a json data, and assert the error.

func AuthFilter

func AuthFilter(code int) restful.FilterFunction

AuthFilter checks if request contains JWT, and sets UserID in Attribute if exists,

func CheckError

func CheckError(err error, log *LogEvt) bool

CheckError is a convenience method to check error is nil. If error is nil, it will return true, else it will log the error and return false

func CheckToken added in v0.1.0

func CheckToken(token string) (userID string, err error)

CheckToken accept a jwt token and returns the uid in token.

func ContainsError

func ContainsError(w http.ResponseWriter, err error, code int) bool

ContainsError is a convenience method to check error is nil. If error is nil, it will return false, else it will log the error, make a CommonResp response and return true. if code is 0, it will use err.Error() as CommonResp.message.

func Debug

func Debug(msg string, evt *LogEvt)

Debug starts a new message with info level.

func Error

func Error(msg string, evt *LogEvt)

Error starts a new message with error level.

func Fatal

func Fatal(msg string, evt *LogEvt)

Fatal starts a new message with fatal level. The os.Exit(1) function is called by the Msg method.

func Filter

func Filter(f func(ctx Ctx)) restful.FilterFunction

Filter transform a biu handler to a restful.FilterFunction

func Handle

func Handle(f func(ctx Ctx)) restful.RouteFunction

Handle transform a biu handler to a restful.RouteFunction.

func Info

func Info(msg string, evt *LogEvt)

Info starts a new message with info level.

func LogFilter

func LogFilter() restful.FilterFunction

LogFilter logs

{
	remote_addr,
	method,
	uri,
	proto,
	status_code,
	content_length,
}

for each request

func Logger

func Logger() zerolog.Logger

Logger get the default logger of biu.

Example
package main

import (
	"os"

	"github.com/rs/zerolog"
	"github.com/tuotoo/biu"
)

func main() {
	biu.SetLoggerOutput(os.Stdout)
	biu.Debug("hello", biu.Log())
	biu.SetLoggerLevel(zerolog.InfoLevel)
	biu.Debug("hello", biu.Log())
	biu.Info("hello", biu.Log().Int("int", 1))
}
Output:

func NewRBACModel

func NewRBACModel() (model.Model, error)

NewRBACModel returns a basic RBAC model.

Example
package main

import (
	"github.com/casbin/casbin"
	"github.com/tuotoo/biu"
)

func main() {
	model, err := biu.NewRBACModel()
	if err != nil {
		panic(err)
	}
	casbin.NewEnforcer(model, "policy.csv")
}
Output:

func NewSwaggerService

func NewSwaggerService(info SwaggerInfo) *restful.WebService

NewSwaggerService creates a swagger webservice in /swagger

func Panic

func Panic(msg string, evt *LogEvt)

Panic starts a new message with panic level. The message is also sent to the panic function.

func ParseToken added in v0.1.0

func ParseToken(token string) (*jwt.Token, error)

ParseToken parse a token string.

func RefreshToken added in v0.1.0

func RefreshToken(token string) (newToken string, err error)

RefreshToken accepts a valid token and returns a new token with new expire time.

func ResponseError

func ResponseError(w http.ResponseWriter, msg string, code int)

ResponseError is a convenience method to response an error code and message. It uses jsoniter for marshalling the value.

func ResponseJSON

func ResponseJSON(w http.ResponseWriter, v interface{})

ResponseJSON is a convenience method for writing a value wrap in CommonResp as JSON. It uses jsoniter for marshalling the value.

func Run

func Run(addr string, cfg *RunConfig)

Run starts up a web server with default container.

func SetLoggerLevel

func SetLoggerLevel(level zerolog.Level)

SetLoggerLevel sets the log level of logger.

func SetLoggerOutput

func SetLoggerOutput(w io.Writer)

SetLoggerOutput sets the output of logger.

func Sign

func Sign(userID string) (token string, err error)

Sign returns a signed jwt string.

Example
biu.JWTTimeout(4 * time.Second).
	JWTSecret("hello world").
	JWTRefreshTimeout(5 * time.Second)
token, _ := biu.Sign("user")
ctx := &biu.Ctx{
	Request: &restful.Request{
		Request: &http.Request{
			Header: map[string][]string{
				"Authorization": {token},
			},
		},
	},
}
u1, err := ctx.IsLogin()
if err != nil {
	panic(err)
}
fmt.Println(u1)
u2, err := biu.CheckToken(token)
if err != nil {
	panic(err)
}
fmt.Println(u2)
time.Sleep(time.Second * 2)
newToken, err := biu.RefreshToken(token)
if err != nil {
	panic(err)
}
_, err = biu.CheckToken(newToken)
if err != nil {
	panic(err)
}

time.Sleep(time.Second * 3)
// token is expired, newToken is still valid
_, err = ctx.IsLogin()
fmt.Println(err != nil)
_, err = biu.CheckToken(token)
fmt.Println(err != nil)
_, err = biu.CheckToken(newToken)
if err != nil {
	panic(err)
}
time.Sleep(time.Second)
// cant refresh token if refresh timeout is reached
_, err = biu.RefreshToken(newToken)
fmt.Println(err != nil)

ctx2 := &biu.Ctx{
	Request: &restful.Request{
		Request: &http.Request{
			Header: map[string][]string{
				"Authorization": {"wtf"},
			},
		},
	},
}
_, err = ctx2.IsLogin()
fmt.Println(err != nil)
Output:

user
user
true
true
true
true

func Warn

func Warn(msg string, evt *LogEvt)

Warn starts a new message with warn level.

func WrapHandler

func WrapHandler(f func(ctx Ctx)) http.HandlerFunc

WrapHandler wraps a biu handler to http.HandlerFunc

Types

type CT

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

CT is a controller testing object.

func NewCT

func NewCT(ctl CtlInterface) *CT

NewCT creates a controller testing object.

Example
package main

import (
	"testing"

	"github.com/levigross/grequests"
	"github.com/stretchr/testify/assert"
	"github.com/tuotoo/biu"
)

// Testing Foo controller in package example.
var fooCT = biu.NewCT(Foo{})
var _ func(t *testing.T)

func main() {
	_ = func(t *testing.T) {
		req := func(num string, code int) (rst Bar) {
			resp := fooCT.AssertHandler(t, "GET", "/",
				&grequests.RequestOptions{
					QueryStruct: struct {
						Num string `url:"num"`
					}{
						Num: num,
					},
				})
			assert.Equal(t, code, resp.Code)
			biu.AssertJSON(t, resp.Data, &rst)
			return rst
		}
		req("abc", 100)
		resp := req("123", 0)
		assert.Equal(t, "bar", resp.Msg)
		assert.Equal(t, 123, resp.Num)
	}
}
Output:

func (CT) AssertHandler

func (ct CT) AssertHandler(t *testing.T, method, path string,
	option *grequests.RequestOptions, v ...string) *CommonRespRawData

AssertHandler requests a handler with error assert and returns a CommonRespRawData.

func (CT) Handler

func (ct CT) Handler(method, path string,
	option *grequests.RequestOptions, v ...string) (*grequests.Response, error)

Handler creates a request for testing handler.

type CommonResp

type CommonResp struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data"`
}

CommonResp with code, message and data

type CommonRespRawData

type CommonRespRawData struct {
	Code    int
	Message string
	Data    json.RawMessage
}

CommonRespRawData is a common response with json.RawMessage

type Container

type Container struct{ *restful.Container }

Container of restful

func New

func New() Container

New creates a new restful container.

func (*Container) AddServices

func (c *Container) AddServices(prefix string,
	filters []restful.FilterFunction, wss ...NS,
)

AddServices adds services with namespace for container.

func (*Container) NewSwaggerService

func (c *Container) NewSwaggerService(info SwaggerInfo) *restful.WebService

NewSwaggerService creates a swagger webservice in /swagger

func (*Container) Run

func (c *Container) Run(addr string, cfg *RunConfig)

Run starts up a web server for container.

type CtlFuncs

type CtlFuncs map[string]ctlCtx

CtlFuncs is a map contains all handler of a controller. the key of CtlFuncs is "Method Path" of handler.

func GetCtlFuncs

func GetCtlFuncs(ctlInterface CtlInterface) CtlFuncs

GetCtlFuncs returns the handler map of a controller.

func (CtlFuncs) NewTestServer

func (m CtlFuncs) NewTestServer(method, path string) *httptest.Server

NewTestServer returns a Test Server.

type CtlInterface

type CtlInterface interface {
	WebService(WS)
}

CtlInterface is the interface of controllers

type Ctx

type Ctx struct {
	*restful.Request
	*restful.Response
	*restful.FilterChain
}

Ctx wrap *restful.Request and *restful.Response in one struct.

func (*Ctx) ContainsError

func (ctx *Ctx) ContainsError(err error, code int, v ...interface{}) bool

ContainsError is a convenience method to check error is nil. If error is nil, it will return false, else it will log the error, make a CommonResp response and return true. if code is 0, it will use err.Error() as CommonResp.message.

func (*Ctx) IsLogin

func (ctx *Ctx) IsLogin() (userID string, err error)

IsLogin gets JWT token in request by OAuth2Extractor, and parse it with CheckToken.

func (*Ctx) ResponseError

func (ctx *Ctx) ResponseError(msg string, code int)

ResponseError is a convenience method to response an error code and message. It uses jsoniter for marshalling the value.

func (*Ctx) ResponseJSON

func (ctx *Ctx) ResponseJSON(v interface{})

ResponseJSON is a convenience method for writing a value wrap in CommonResp as JSON. It uses jsoniter for marshalling the value.

func (*Ctx) ResponseStdErrCode

func (ctx *Ctx) ResponseStdErrCode(code int, v ...interface{})

ResponseStdErrCode is a convenience method response a code with msg in Code Desc.

func (*Ctx) UserID

func (ctx *Ctx) UserID() string

UserID returns UserID stored in attribute.

type LogEvt

type LogEvt = zerolog.Event

LogEvt is alias of zerolog.Event

func Log

func Log() *LogEvt

Log returns *zerolog.Event.

type NS

type NS struct {
	NameSpace    string       // url parent of controller
	Controller   CtlInterface // controller implement CtlInterface
	Desc         string       // description of controller of namespace
	ExternalDesc string       // external documentation of controller
	ExternalURL  string       // external url of ExternalDesc
}

NS contains configuration of a namespace

type RouteOpt

type RouteOpt struct {
	Auth   bool
	Errors map[int]string
}

RouteOpt contains some options of route.

type RunConfig

type RunConfig struct {
	BeforeShutDown func()
	AfterShutDown  func()
}

RunConfig is the running config of container.

type Setter added in v0.1.0

type Setter struct{}

Setter is a setter for setting global options.

func JWTRefreshTimeout added in v0.1.0

func JWTRefreshTimeout(timeout time.Duration) Setter

JWTRefreshTimeout sets refresh timeout for JWT.

func JWTSecret added in v0.1.0

func JWTSecret(secret string) Setter

JWTSecret sets secret for JWT.

func JWTTimeout added in v0.1.0

func JWTTimeout(timeout time.Duration) Setter

JWTTimeout sets timeout for JWT.

func (Setter) JWTRefreshTimeout added in v0.1.0

func (Setter) JWTRefreshTimeout(timeout time.Duration) Setter

JWTRefreshTimeout sets refresh timeout for JWT.

func (Setter) JWTSecret added in v0.1.0

func (Setter) JWTSecret(secret string) Setter

JWTSecret sets secret for JWT.

func (Setter) JWTTimeout added in v0.1.0

func (Setter) JWTTimeout(timeout time.Duration) Setter

JWTTimeout sets timeout for JWT.

type SwaggerInfo

type SwaggerInfo struct {
	Title          string
	Description    string
	TermsOfService string
	ContactName    string
	ContactURL     string
	ContactEmail   string
	LicenseName    string
	LicenseURL     string
	Version        string
	WebServicesURL string
	DisableCORS    bool
	// route prefix of swagger service
	// swagger service will running under
	// http://<api>/<RoutePrefix>/swagger
	RoutePrefix string
}

SwaggerInfo contains configuration of swagger documents.

type WS

type WS struct {
	*restful.WebService
}

WS extends *restful.WebService

func (WS) Route

func (ws WS) Route(builder *restful.RouteBuilder, opt *RouteOpt)

Route creates a new Route using the RouteBuilder and add to the ordered list of Routes.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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