gogo

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jan 20, 2019 License: MIT Imports: 34 Imported by: 3

README

gogo

CircleCI Coverage GoDoc

NOTE: This is VERSION 1 compactible upgrade!

gogo is an open source, high performance RESTful api framework for the Golang programming language.

It's heavily inspired from rails and neko.

Installation

$ go get github.com/dolab/gogo/cmd/gogo
  • Create application using scaffold tools
# show gogo helps
$ gogo -h

# create a new application
$ gogo new myapp

# fix application import path
$ cd myapp
$ source env.sh

# generate controller
# NOTE: you should update application.go and add app.Resource("/user", User) route by hand
$ gogo g c user

# generate middleware
$ gogo g w session

# generate model
$ gogo g m user

# run test
$ make

# run development server
$ make godev

Getting Started

  • Normal
package main

import (
	"net/http"

	"github.com/dolab/gogo"
)

func main() {
	// load config from config/application.json
	// app := gogo.New("development", "/path/to/[config/application.json]")

	// load config from filename
	// app := gogo.New("development", "/path/to/config.json")

	// use default config
	app := gogo.NewDefaults()

	// GET /
	app.GET("/", func(ctx *gogo.Context) {
		ctx.Text("Hello, gogo!")
	})

	// GET /hello/:name
	app.HandlerFunc(http.MethodGet, "/hello/:name", func(w http.ResponseWriter, r *http.Request) {
		params := gogo.NewAppParams(r)

		name := params.Get("name")
		if name == "" {
			name = "gogo"
		}

		w.WriteHeader(http.StatusOK)
		w.Write([]byte("Hello, " + name + "!"))
	})

	app.Run()
}
  • Using middlewares
package main

import (
	"github.com/dolab/gogo"
)

func main() {
	app := gogo.NewDefaults()

	// avoid server quit by registering a recovery middleware
	app.Use(func(ctx *gogo.Context) {
		if panicErr := recover(); panicErr != nil {
			ctx.Logger.Errorf("[PANICED] %v", panicErr)

			ctx.Return(map[string]interface{}{
				"panic": panicErr,
			})
			return
		}

		ctx.Next()
	})

	// GET /
	app.GET("/", func(ctx *gogo.Context) {
		panic("Oops ~ ~ ~")
	})

	app.Run()
}
  • Using group
package main

import (
	"encoding/base64"
	"net/http"
	"strings"

	"github.com/dolab/gogo"
)

func main() {
	app := gogo.NewDefaults()

	// avoid server quit by registering recovery func global
	app.Use(func(ctx *gogo.Context) {
		if panicErr := recover(); panicErr != nil {
			ctx.Logger.Errorf("[PANICED] %v", panicErr)

			ctx.Return(map[string]interface{}{
				"panic": panicErr,
			})
		}

		ctx.Next()
	})
	

	// GET /
	app.GET("/", func(ctx *gogo.Context) {
		panic("Oops ~ ~ ~")
	})

	// prefix resources with /v1 and apply basic auth middleware for all sub-resources
	// NOTE: it combines recovery middleware from previous.
	v1 := app.Group("/v1", func(ctx *gogo.Context) {
		auth := ctx.Header("Authorization")
		if !strings.HasPrefix(auth, "Basic ") {
			ctx.Abort()

			ctx.SetStatus(http.StatusForbidden)
			ctx.Return()
			return
		}

		b, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
		if err != nil {
			ctx.Logger.Errorf("Base64 decode error: %v", err)
			ctx.Abort()

			ctx.SetStatus(http.StatusForbidden)
			ctx.Return()
			return
		}

		tmp := strings.SplitN(string(b), ":", 2)
		if len(tmp) != 2 || tmp[0] != "gogo" || tmp[1] != "ogog" {
			ctx.Abort()

			ctx.SetStatus(http.StatusForbidden)
			ctx.Return()
			return
		}

		// settings which can used by following middlewares and handler
		ctx.Set("username", tmp[0])

		ctx.Next()
	})

	// GET /v1
	v1.GET("/", func(ctx *gogo.Context) {
		username := ctx.MustGet("username").(string)

		ctx.Text("Hello, " + username + "!")
	})

	app.Run()
}
  • Use Resource Controller

You can implement a controller with optional Index, Create, Explore, Show, Update and Destroy methods, and use app.Resource("/myresource", &MyController) to register all RESTful routes auto.

NOTE: When your resource has a inheritance relationship, there MUST NOT be two same id key. you can overwrite default id key by implementing ControllerID interface.

package main

import (
	"github.com/dolab/gogo"
)

type GroupController struct{}

// GET /group
func (t *GroupController) Index(ctx *gogo.Context) {
	ctx.Text("GET /group")
}

// GET /group/:group
func (t *GroupController) Show(ctx *gogo.Context) {
	ctx.Text("GET /group/" + ctx.Params.Get("group"))
}

type UserController struct{}

// overwrite default :user key with :id
func (t *UserController) ID() string {
	return "id"
}

// GET /group/:group/user/:id
func (t *UserController) Show(ctx *gogo.Context) {
	ctx.Text("GET /group/" + ctx.Params.Get("group") + "/user/" + ctx.Params.Get("id"))
}

func main() {
	app := gogo.NewDefaults()

	// register group controller with default :group key
	group := app.Resource("/group", &GroupController{})

	// nested user controller within group resource
	// NOTE: it overwrites default :user key by implmenting ControllerID interface.
	group.Resource("/user", &UserController{})

	app.Run()
}

Configures

  • Server
{
	"addr": "localhost",
	"port": 9090,
	"throttle": 3000, // RPS, throughput of per-seconds
	"slowdown": 30000, // TPS, concurrency of server
	"request_timeout": 30,
	"response_timeout": 30,
	"ssl": false,
	"ssl_cert": "/path/to/ssl/cert",
	"ssl_key": "/path/to/ssl/key",
	"request_id": "X-Request-Id"
}

TODOs

  • server config context
  • support http.Request context
  • scoffold && generator
  • mountable third-part app

Thanks

Author

Spring MC

LICENSE

The MIT License (MIT)

Copyright (c) 2016

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Documentation

Index

Constants

View Source
const (
	DefaultMaxMultiformBytes = 32 << 20 // 32M
	DefaultMaxHeaderBytes    = 64 << 10 // 64k
)

http config

View Source
const (
	DefaultHttpRequestID       = "X-Request-Id"
	DefaultMaxHttpRequestIDLen = 32
	DefaultHttpRequestTimeout  = 30 // 30s
	DefaultHttpResponseTimeout = 30 // 30s
)

server config

View Source
const (
	RenderDefaultContentType = "text/plain; charset=utf-8"
	RenderJsonContentType    = "application/json"
	RenderJsonPContentType   = "application/javascript"
	RednerXmlContentType     = "text/xml"
)
View Source
const (
	SchemaConfig = "gogo://config"
)

internal schema

Variables

View Source
var (
	DefaultServerConfig = &ServerConfig{
		Addr:      "127.0.0.1",
		Port:      9090,
		Ssl:       false,
		RequestID: DefaultHttpRequestID,
	}

	DefaultLoggerConfig = &LoggerConfig{
		Output:       "stderr",
		LevelName:    "info",
		FilterFields: []string{"password", "token"},
	}

	DefaultSectionConfig = &SectionConfig{
		Server: DefaultServerConfig,
		Logger: DefaultLoggerConfig,
	}
)
View Source
var (
	ErrHeaderFlushed = errors.New("Response headers have been written!")
	ErrConfigSection = errors.New("Config section does not exist!")
	ErrSettingsKey   = errors.New("Settings key is duplicated!")
	ErrHash          = errors.New("The hash function does not linked into the binary!")
)
View Source
var (
	// FindModeConfigFile returns config file for specified run mode.
	// You could custom your own run mode config file by overwriting.
	FindModeConfigFile = func(runMode, srcPath string) string {

		srcPath = path.Clean(srcPath)

		finfo, ferr := os.Stat(srcPath)
		if ferr != nil {
			return SchemaConfig
		}

		if !finfo.IsDir() && (finfo.Mode()&os.ModeSymlink == 0) {
			return srcPath
		}

		filename := "application.json"
		switch RunMode(runMode) {
		case Development:

			filename = "application.development.json"

		case Test:

			filename = "application.test.json"

		case Production:

		}

		file := path.Join(srcPath, "config", filename)
		if _, err := os.Stat(file); os.IsNotExist(err) {
			file = path.Join(srcPath, "config", "application.json")
		}

		return file
	}
)

Functions

func IsGIDHex

func IsGIDHex(s string) bool

IsGIDHex returns whether s is a valid hex representation of a GID. See the GIDHex function.

Types

type AppConfig

type AppConfig struct {
	Mode RunMode `json:"mode"`
	Name string  `json:"name"`

	Sections map[RunMode]*json.RawMessage `json:"sections"`
}

AppConfig defines config component of gogo It implements Configer interface

func NewAppConfig

func NewAppConfig(filename string) (*AppConfig, error)

NewAppConfig returns *AppConfig by parsing application.json

func NewAppConfigFromDefault

func NewAppConfigFromDefault() (*AppConfig, error)

NewAppConfigFromDefault returns *AppConfig of defaults

func NewAppConfigFromString

func NewAppConfigFromString(s string) (*AppConfig, error)

NewAppConfigFromString returns *AppConfig by parsing json string

func (*AppConfig) RunMode

func (config *AppConfig) RunMode() RunMode

RunMode returns the current mode of *AppConfig

func (*AppConfig) RunName

func (config *AppConfig) RunName() string

RunName returns the application name

func (*AppConfig) Section

func (config *AppConfig) Section() *SectionConfig

Section is shortcut of retreving app server and logger configurations at one time It returns SectionConfig if exists, otherwise returns DefaultSectionConfig instead

func (*AppConfig) SetMode

func (config *AppConfig) SetMode(mode RunMode)

SetMode changes config mode

func (*AppConfig) UnmarshalJSON

func (config *AppConfig) UnmarshalJSON(v interface{}) error

UnmarshalJSON parses JSON-encoded data of section and stores the result in the value pointed to by v. It returns ErrConfigSection error if section of the current mode does not exist.

type AppLogger

type AppLogger struct {
	*logger.Logger
	// contains filtered or unexported fields
}

AppLogger defines log component of gogo, it implements Logger interface with pool support

func NewAppLogger

func NewAppLogger(output, filename string) *AppLogger

NewAppLogger returns *AppLogger inited with args

func (*AppLogger) New

func (alog *AppLogger) New(requestID string) Logger

New returns a new Logger with provided requestID which shared writer with current logger

func (*AppLogger) RequestID

func (alog *AppLogger) RequestID() string

RequestID returns request id binded to the logger

func (*AppLogger) Reuse

func (alog *AppLogger) Reuse(lg Logger)

Reuse puts the Logger back to pool for later usage

type AppParams

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

AppParams defines params component of gogo

func NewAppParams

func NewAppParams(r *http.Request, params httpdispatch.Params) *AppParams

NewAppParams returns an *AppParams with *http.Request and httpdispatch.Params

func NewParams

func NewParams(r *http.Request) *AppParams

NewParams returns an *AppParams with *http.Request and context httpdispatch.Params

func (*AppParams) File

File retrieves multipart uploaded file of HTTP POST request

func (*AppParams) Get

func (p *AppParams) Get(name string) string

Get returns the first value for the named component of the request. NOTE: httpdispatch.Params takes precedence over URL query string values.

func (*AppParams) GetBool

func (p *AppParams) GetBool(name string) (bool, error)

func (*AppParams) GetFloat

func (p *AppParams) GetFloat(name string) (float64, error)

func (*AppParams) GetInt

func (p *AppParams) GetInt(name string) (int, error)

func (*AppParams) GetInt16

func (p *AppParams) GetInt16(name string) (int16, error)

func (*AppParams) GetInt32

func (p *AppParams) GetInt32(name string) (int32, error)

func (*AppParams) GetInt64

func (p *AppParams) GetInt64(name string) (int64, error)

func (*AppParams) GetInt8

func (p *AppParams) GetInt8(name string) (int8, error)

func (*AppParams) GetUint16

func (p *AppParams) GetUint16(name string) (uint16, error)

func (*AppParams) GetUint32

func (p *AppParams) GetUint32(name string) (uint32, error)

func (*AppParams) GetUint64

func (p *AppParams) GetUint64(name string) (uint64, error)

func (*AppParams) GetUint8

func (p *AppParams) GetUint8(name string) (uint8, error)

func (*AppParams) Gob

func (p *AppParams) Gob(v interface{}) error

Gob decode request body with gob codec

func (*AppParams) HasForm

func (p *AppParams) HasForm(name string) bool

HasForm returns whether named param is exist for POST/PUT request body.

func (*AppParams) HasQuery

func (p *AppParams) HasQuery(name string) bool

HasQuery returns whether named param is exist for URL query string.

func (*AppParams) Json

func (p *AppParams) Json(v interface{}) error

Json unmarshals request body with json codec

func (*AppParams) Post

func (p *AppParams) Post(name string) string

Post returns the named comonent of the request by calling http.Request.FormValue()

func (*AppParams) RawBody

func (p *AppParams) RawBody() ([]byte, error)

RawBody returns request body and error if exist while reading.

func (*AppParams) Xml

func (p *AppParams) Xml(v interface{}) error

Xml unmarshals request body with xml codec

type AppRoute

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

AppRoute defines route component of gogo

func NewAppRoute

func NewAppRoute(prefix string, server *AppServer) *AppRoute

NewAppRoute creates a new app route with specified prefix and server

func (*AppRoute) Any

func (r *AppRoute) Any(path string, handler Middleware)

Any is a shortcut for all request methods

func (*AppRoute) CleanModdilewares

func (r *AppRoute) CleanModdilewares()

CleanModdilewares removes all registered middlewares of AppRoute NOTE: it's useful in testing cases.

func (*AppRoute) DELETE

func (r *AppRoute) DELETE(path string, handler Middleware)

DELETE is a shortcut of route.Handle("DELETE", path, handler)

func (*AppRoute) GET

func (r *AppRoute) GET(path string, handler Middleware)

GET is a shortcut of route.Handle("GET", path, handler)

func (*AppRoute) Group

func (r *AppRoute) Group(prefix string, middlewares ...Middleware) *AppRoute

Group returns a new *AppRoute which has the same prefix path and middlewares

func (*AppRoute) HEAD

func (r *AppRoute) HEAD(path string, handler Middleware)

HEAD is a shortcut of route.Handle("HEAD", path, handler)

func (*AppRoute) Handle

func (r *AppRoute) Handle(method string, uri string, handler Middleware)

Handle registers a new resource by Middleware

func (*AppRoute) Handler

func (r *AppRoute) Handler(method, uri string, handler http.Handler)

Handler registers a new resource by http.Handler

func (*AppRoute) HandlerFunc

func (r *AppRoute) HandlerFunc(method, uri string, handler http.HandlerFunc)

HandlerFunc registers a new resource by http.HandlerFunc

func (*AppRoute) Middlewares

func (r *AppRoute) Middlewares() []Middleware

Middlewares returns registered middlewares of AppRoute

func (*AppRoute) MockHandle

func (r *AppRoute) MockHandle(method string, path string, response http.ResponseWriter, handler Middleware)

MockHandle mocks a new resource with specified response and handler, useful for testing

func (*AppRoute) OPTIONS

func (r *AppRoute) OPTIONS(path string, handler Middleware)

OPTIONS is a shortcut of route.Handle("OPTIONS", path, handler)

func (*AppRoute) PATCH

func (r *AppRoute) PATCH(path string, handler Middleware)

PATCH is a shortcut of route.Handle("PATCH", path, handler)

func (*AppRoute) POST

func (r *AppRoute) POST(path string, handler Middleware)

POST is a shortcut of route.Handle("POST", path, handler)

func (*AppRoute) PUT

func (r *AppRoute) PUT(path string, handler Middleware)

PUT is a shortcut of route.Handle("PUT", path, handler)

func (*AppRoute) ProxyHandle

func (r *AppRoute) ProxyHandle(method string, path string, proxy *httputil.ReverseProxy, filters ...ResponseFilter)

ProxyHandle registers a new resource with a proxy

func (*AppRoute) Resource

func (r *AppRoute) Resource(resource string, controller interface{}) *AppRoute

Resource generates routes with controller interfaces, and returns a group routes with resource name.

Example:

article := r.Resource("article")
	GET		/article			Article.Index
	POST	/article			Article.Create
	HEAD	/article/:article	Article.Explore
	GET		/article/:article	Article.Show
	PUT		/article/:article	Article.Update
	DELETE	/article/:article	Article.Destroy

func (*AppRoute) ServeHTTP

func (r *AppRoute) ServeHTTP(resp http.ResponseWriter, req *http.Request)

ServeHTTP implements http.Handler by proxy to wrapped Handler

func (*AppRoute) SetHandler

func (r *AppRoute) SetHandler(handler Handler)

SetHandler replaces hanlder of AppRoute

func (*AppRoute) Static

func (r *AppRoute) Static(path, root string)

Static serves files from the given dir

func (*AppRoute) Use

func (r *AppRoute) Use(middlewares ...Middleware)

Use registers new middlewares to the route TODO: ignore duplicated middlewares?

type AppServer

type AppServer struct {
	*AppRoute
	// contains filtered or unexported fields
}

AppServer defines server component of gogo

func New

func New(runMode, srcPath string) *AppServer

New creates application server with config resolved from file <srcPath>/config/application[.<runMode>].json. NOTE: You can custom resolver by overwriting FindModeConfigFile.

func NewAppServer

func NewAppServer(config Configer, logger Logger) *AppServer

NewAppServer returns *AppServer inited with args

func NewDefaults added in v1.1.0

func NewDefaults() *AppServer

NewDefaults creates a *AppServer for quick start

func NewWithConfiger

func NewWithConfiger(config Configer) *AppServer

NewWithConfiger creates application server with custom Configer and default Logger, see Configer for implements a new config provider.

func NewWithLogger

func NewWithLogger(config Configer, logger Logger) *AppServer

NewWithLogger creates application server with custom Configer and Logger

func (*AppServer) Config

func (s *AppServer) Config() Configer

Config returns app config of the app server

func (*AppServer) Mode

func (s *AppServer) Mode() string

Mode returns run mode of the app server

func (*AppServer) Run

func (s *AppServer) Run()

Run starts the http server with httpdispatch.Router handler

func (*AppServer) RunWithHandler

func (s *AppServer) RunWithHandler(handler Handler)

RunWithHandler runs the http server with given handler It's useful for embbedding third-party golang applications.

func (*AppServer) ServeHTTP

func (s *AppServer) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface with throughput and concurrency support. NOTE: It servers client by dispatching request to AppRoute.

type Configer

type Configer interface {
	RunMode() RunMode
	RunName() string
	SetMode(mode RunMode)
	Section() *SectionConfig
	UnmarshalJSON(v interface{}) error
}

Configer represents application configurations

type Context

type Context struct {
	Response Responser
	Request  *http.Request
	Params   *AppParams
	Logger   Logger
	// contains filtered or unexported fields
}

Context defines context of a request

func NewContext

func NewContext() *Context

NewContext returns a *Context with *AppServer

func (*Context) Abort

func (c *Context) Abort()

Abort forces to stop call chain.

func (*Context) Action

func (c *Context) Action() string

Action returns action name of routed handler

func (*Context) AddHeader

func (c *Context) AddHeader(key, value string)

AddHeader adds response header with key/value pair

func (*Context) Controller

func (c *Context) Controller() string

Controller returns controller name of routed handler

func (*Context) Get

func (c *Context) Get(key string) (v interface{}, ok bool)

Get returns a value of the key

func (*Context) GetFinal

func (c *Context) GetFinal(key string) (v interface{}, ok bool)

GetFinal returns a frozen value of the key

func (*Context) HasHeader

func (c *Context) HasHeader(key string) bool

HasHeader returns true if request sets its header for canonicaled specified key

func (*Context) HasRawHeader

func (c *Context) HasRawHeader(key string) bool

HasRawHeader returns true if request sets its header with specified key

func (*Context) HashedReturn

func (c *Context) HashedReturn(hasher crypto.Hash, body ...interface{}) error

HashedReturn returns response with ETag header calculated hash of response.Body dynamically

func (*Context) Header

func (c *Context) Header(key string) string

Header returns request header value of canonicaled specified key

func (*Context) Json

func (c *Context) Json(data interface{}) error

Json returns response with json codec and Content-Type: application/json header

func (*Context) JsonP

func (c *Context) JsonP(callback string, data interface{}) error

JsonP returns response with json codec and Content-Type: application/javascript header

func (*Context) MustGet

func (c *Context) MustGet(key string) interface{}

MustGet returns a value of key or panic when key doesn't exist

func (*Context) MustGetFinal

func (c *Context) MustGetFinal(key string) interface{}

MustGetFinal returns a frozen value of key or panic when it doesn't exist

func (*Context) MustSetFinal

func (c *Context) MustSetFinal(key string, value interface{})

MustSetFinal likes SetFinal, but it panics if key is duplicated.

func (*Context) Next

func (c *Context) Next()

Next executes the remain middlewares in the chain. NOTE: It ONLY used in the middlewares!

func (*Context) RawHeader

func (c *Context) RawHeader(key string) string

RawHeader returns request header value of specified key

func (*Context) Redirect

func (c *Context) Redirect(location string)

Redirect returns a HTTP redirect to the specific location.

func (*Context) Render

func (c *Context) Render(w Render, data interface{}) error

Render responses client with data rendered by Render

func (*Context) RequestID

func (c *Context) RequestID() string

RequestID returns request id of the Context

func (*Context) RequestURI

func (c *Context) RequestURI() string

RequestURI returns request raw uri of http.Request

func (*Context) Return

func (c *Context) Return(body ...interface{}) error

Return returns response with auto detected Content-Type

func (*Context) Set

func (c *Context) Set(key string, value interface{})

Set binds a new value with key for the context

func (*Context) SetFinal

func (c *Context) SetFinal(key string, value interface{}) error

SetFinal binds a value with key for the context and freezes it

func (*Context) SetHeader

func (c *Context) SetHeader(key, value string)

SetHeader sets response header with key/value pair

func (*Context) SetStatus

func (c *Context) SetStatus(code int)

SetStatus sets response status code

func (*Context) Text

func (c *Context) Text(data interface{}) error

Text returns response with Content-Type: text/plain header

func (*Context) Xml

func (c *Context) Xml(data interface{}) error

Xml returns response with xml codec and Content-Type: text/xml header

type ContextHandle

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

ContextHandle wraps extra info for handler, such as package name, controller name and action name, etc.

func NewContextHandle

func NewContextHandle(server *AppServer, handler http.HandlerFunc, filters []Middleware) *ContextHandle

NewContextHandle returns new *ContextHandle with handler info parsed

func (*ContextHandle) Handle

func (ch *ContextHandle) Handle(w http.ResponseWriter, r *http.Request, params httpdispatch.Params)

Handle implements httpdispatch.Handler interface

type ControllerCreate

type ControllerCreate interface {
	Create(c *Context)
}

ControllerCreate is an interface that wraps the Create method. It is used by Resource for registering POST /resource route handler.

type ControllerDestroy

type ControllerDestroy interface {
	Destroy(c *Context)
}

ControllerDestroy is an interface that wraps the Destroy method. It is used by Resource for registering DELETE /resource/:id route handler.

type ControllerDispatch

type ControllerDispatch interface {
	DISPATCH(c *Context)
}

ControllerDispatch is an interface that allows custom router for Resource.

type ControllerExplore

type ControllerExplore interface {
	Explore(c *Context)
}

ControllerExplore is an interface that wraps the Explore method. It is used by Resource for registering HEAD /resource/:id route handler.

type ControllerID

type ControllerID interface {
	ID() string
}

ControllerID is an interface that allows custom resource id name with Resource.

type ControllerIndex

type ControllerIndex interface {
	Index(c *Context)
}

ControllerIndex is an interface that wraps the Index method. It is used by Resource for registering GET /resource route handler.

type ControllerShow

type ControllerShow interface {
	Show(c *Context)
}

ControllerShow is an interface that wraps the Show method. It is used by Resource for registering GET /resource/:id route handler.

type ControllerUpdate

type ControllerUpdate interface {
	Update(c *Context)
}

ControllerUpdate is an interface that wraps the Update method. It is used by Resource for registering PUT /resource/:id route handler.

type DefaultRender

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

DefaultRender responses with default Content-Type header

func (*DefaultRender) ContentType

func (render *DefaultRender) ContentType() string

func (*DefaultRender) Render

func (render *DefaultRender) Render(v interface{}) error

type FakeHandle

type FakeHandle struct {
	*ContextHandle
	// contains filtered or unexported fields
}

FakeHandle defines a wrapper of handler for testing

func NewFakeHandle

func NewFakeHandle(server *AppServer, handler http.HandlerFunc, filters []Middleware, w http.ResponseWriter) *FakeHandle

NewFakeHandle returns new handler with stubbed http.ResponseWriter

func (*FakeHandle) Handle

func (ch *FakeHandle) Handle(w http.ResponseWriter, r *http.Request, params httpdispatch.Params)

Handle implements httpdispatch.Handler interface

type GID

type GID string

GID is a unique ID identifying a value. It must be exactly 12 bytes long.

func GIDHex

func GIDHex(s string) GID

GIDHex returns a GID from the provided hex representation. Calling this function with an invalid hex representation will cause a runtime panic. See the IsGIDHex function.

func NewGID

func NewGID() GID

NewGID returns a new unique GID.

func NewGIDWithTime

func NewGIDWithTime(t time.Time) GID

NewGIDWithTime returns a dummy GID with the timestamp part filled with the provided number of seconds from epoch UTC, and all other parts filled with zeroes. It is useful only for queries filter with ids generated before or after the specified timestamp.

func (GID) Counter

func (id GID) Counter() int32

Counter returns the incrementing value part of the id. It's a runtime error to call this method with an invalid id.

func (GID) Hex

func (id GID) Hex() string

Hex returns a hex representation of the GID.

func (GID) Mac

func (id GID) Mac() []byte

Mac returns the 3-byte mac addr id part of the id. It's a runtime error to call this method with an invalid id.

func (GID) Pid

func (id GID) Pid() uint16

Pid returns the process id part of the id. It's a runtime error to call this method with an invalid id.

func (GID) String

func (id GID) String() string

String returns a hex string representation of the id. Example: GIDHex("4d88e15b60f486e428412dc9").

func (GID) Time

func (id GID) Time() time.Time

Time returns the timestamp part of the id. It's a runtime error to call this method with an invalid id.

func (GID) Valid

func (id GID) Valid() bool

Valid returns true if id is valid. A valid id must contain exactly 12 bytes.

type Handler

type Handler interface {
	http.Handler

	Handle(string, string, httpdispatch.Handler)
	ServeFiles(string, http.FileSystem)
}

Handler represents server handlers

type HashRender

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

HashRender responses with Etag header calculated from render data dynamically. NOTE: This always write response by copy if the render data is an io.Reader!!!

func (*HashRender) ContentType

func (render *HashRender) ContentType() string

func (*HashRender) Render

func (render *HashRender) Render(v interface{}) error

type JsonRender

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

JsonRender responses with Content-Type: application/json header It transform response data by json.Marshal.

func (*JsonRender) ContentType

func (render *JsonRender) ContentType() string

func (*JsonRender) Render

func (render *JsonRender) Render(v interface{}) error

type JsonpRender

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

JsonpRender responses with Content-Type: application/javascript header It transform response data by json.Marshal.

func (*JsonpRender) ContentType

func (render *JsonpRender) ContentType() string

func (*JsonpRender) Render

func (render *JsonpRender) Render(v interface{}) error

type Logger

type Logger interface {
	New(requestID string) Logger
	Reuse(log Logger)
	RequestID() string
	SetLevelByName(level string) error
	SetColor(color bool)

	Print(v ...interface{})
	Printf(format string, v ...interface{})
	Debug(v ...interface{})
	Debugf(format string, v ...interface{})
	Info(v ...interface{})
	Infof(format string, v ...interface{})
	Warn(v ...interface{})
	Warnf(format string, v ...interface{})
	Error(v ...interface{})
	Errorf(format string, v ...interface{})
	Fatal(v ...interface{})
	Fatalf(format string, v ...interface{})
	Panic(v ...interface{})
	Panicf(format string, v ...interface{})
}

Logger defines interface of application log apis.

type LoggerConfig

type LoggerConfig struct {
	Output    string `json:"output"` // valid values [stdout|stderr|null|path/to/file]
	LevelName string `json:"level"`  // valid values [debug|info|warn|error]

	FilterFields []string `json:"filter_fields"` // sensitive fields which should filter out when logging
}

LoggerConfig defines config spec of AppLogger

func (*LoggerConfig) Level

func (l *LoggerConfig) Level() logger.Level

Level returns logger.Level by its name

type Middleware

type Middleware func(ctx *Context)

Middleware represents request filters and resource handler NOTE: It is the filter's responsibility to invoke ctx.Next() for chainning.

type Render

type Render interface {
	ContentType() string
	Render(v interface{}) error
}

Render represents HTTP response render

func NewDefaultRender

func NewDefaultRender(w Responser) Render

func NewHashRender

func NewHashRender(w Responser, hasher crypto.Hash) Render

func NewJsonRender

func NewJsonRender(w Responser) Render

func NewJsonpRender

func NewJsonpRender(w Responser, callback string) Render

func NewTextRender

func NewTextRender(w Responser) Render

func NewXmlRender

func NewXmlRender(w Responser) Render

type Response

type Response struct {
	http.ResponseWriter
	// contains filtered or unexported fields
}

Response extends http.ResponseWriter with extra metadata

func (*Response) Before

func (r *Response) Before(filter ResponseFilter)

Before registers filters which invoked before response has written

func (*Response) Flush

func (r *Response) Flush()

Flush tryes flush to client if possible

func (*Response) FlushHeader

func (r *Response) FlushHeader()

FlushHeader writes response headers with status and reset size, it also invoke before filters

func (*Response) HeaderFlushed

func (r *Response) HeaderFlushed() bool

HeaderFlushed returns true if response headers has written

func (*Response) Reset

func (r *Response) Reset(w http.ResponseWriter)

Reset resets the current *Response with new http.ResponseWriter

func (*Response) Size

func (r *Response) Size() int

Size returns size of response body written

func (*Response) Status

func (r *Response) Status() int

Status returns current response status code

func (*Response) Write

func (r *Response) Write(data []byte) (size int, err error)

Write writes data to client, and returns size of data written or error if exits.

func (*Response) WriteHeader

func (r *Response) WriteHeader(code int)

WriteHeader sets response status code only by overwrites underline

type ResponseFilter

type ResponseFilter func(w Responser, b []byte) []byte

ResponseFilter defines filter interface applied to response

type Responser

type Responser interface {
	http.ResponseWriter
	http.Flusher

	Before(filter ResponseFilter) // register before filter
	Size() int                    // return the size of response body
	Status() int                  // response status code
	HeaderFlushed() bool          // whether response header has been sent?
	FlushHeader()                 // send response header
	Reset(w http.ResponseWriter)  // reset response with new http.ResponseWriter
}

Responser represents HTTP response interface

func NewResponse

func NewResponse(w http.ResponseWriter) Responser

NewResponse returns a Responser with w passed. NOTE: It sets default response status code to http.StatusOK

type RunMode

type RunMode string

RunMode defines app run mode

const (
	Development RunMode = "development"
	Test        RunMode = "test"
	Production  RunMode = "production"
)

run mode

func (RunMode) IsDevelopment

func (mode RunMode) IsDevelopment() bool

IsDevelopment returns true if mode is development

func (RunMode) IsProduction

func (mode RunMode) IsProduction() bool

IsProduction returns true if mode equals to production

func (RunMode) IsTest

func (mode RunMode) IsTest() bool

IsTest returns true if mode is test

func (RunMode) IsValid

func (mode RunMode) IsValid() bool

IsValid returns true if mode is valid

func (RunMode) String

func (mode RunMode) String() string

type SectionConfig

type SectionConfig struct {
	Server *ServerConfig `json:"server"`
	Logger *LoggerConfig `json:"logger"`
}

SectionConfig defines config spec for internal usage

type ServerConfig

type ServerConfig struct {
	Addr           string `json:"addr"`
	Port           int    `json:"port"`
	RTimeout       int    `json:"request_timeout"`  // unit in second
	WTimeout       int    `json:"response_timeout"` // unit in second
	MaxHeaderBytes int    `json:"max_header_bytes"` // unit in byte

	Ssl     bool   `json:"ssl"`
	SslCert string `json:"ssl_cert"`
	SslKey  string `json:"ssl_key"`

	Throttle  int    `json:"throttle"` // in time.Second/throttle ms
	Slowdown  int    `json:"slowdown"`
	RequestID string `json:"request_id"`
}

ServerConfig defines config spec of AppServer

type StatusCoder

type StatusCoder interface {
	StatusCode() int
}

StatusCoder represents HTTP response status code it is useful for custom response data with response status code

type TextRender

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

TextRender responses with Content-Type: text/plain header It transform response data by stringify.

func (*TextRender) ContentType

func (render *TextRender) ContentType() string

func (*TextRender) Render

func (render *TextRender) Render(v interface{}) error

type XmlRender

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

XmlRender responses with Content-Type: text/xml header It transform response data by xml.Marshal.

func (*XmlRender) ContentType

func (render *XmlRender) ContentType() string

func (*XmlRender) Render

func (render *XmlRender) Render(v interface{}) error

Directories

Path Synopsis
cmd
skeleton

Jump to

Keyboard shortcuts

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