webgo

package module
v1.6.1 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2018 License: MIT Imports: 13 Imported by: 0

README

Build Status

WebGo v2.0 (planned)

  1. Current implementation of logging middleware will be deprecated
  • Logging middleware will be converted to wrapper e.g. middlewares.Log(Handler) This is a clean implementation, to avoid unnecessary complexity and computation from ServeHTTP()
  1. No more capability of enabling access log on selected routes. Access log can either be turned on for all or not.

  2. All middlewares will be moved to a nested folder middlewares rather than being the methods of the type middlewares.

These changes would cause backward incompatibility

WebGo v1.6.1

A lightweight & simple web framework for Go. GoDoc webgo

Update 18 March 2018 (v1.6.1)
  • Added Trailing slash feature. Added a new option TrailingSlash boolean to Route definition. If true, the provided URI pattern will be matched with or without the trailing slash. Default is false.

  • Minor improvement in ServeHTTP method

Requirements
  1. Go 1.8 or higher
Usage

Please refer to the Sample app built using webgo: webgo-sample to see how webgo's capabilities can be used.

Supported HTTP methods are: OPTIONS, HEAD, GET, POST, PUT, PATCH, DELETE.

This framework does not force you to follow any architecture (e.g. MVC), instead is more of a configuration over convention based framework. While using any of the default HTTP response function available, for any status less than 400, the JSON response is wrapped as follows:

{
	data: <payload, any valid JSON data>,
	status: <status code, integer>
}

While using any of the default HTTP response function available, for any status greater than 400, the JSON response is wrapped as follows:

{
	errors: <payload, any valid JSON data>,
	status: <status code, integer>
}
URI patterns

While defining the path of an HTTP route; you can choose from the following 4 different options:

  1. Static path e.g. /v1/api/users
  2. Path with named parameters e.g. /v1/api/users/:userID/photos/:photoID
  • Here userID and photoID are the parameter names.
  1. Path with wildcard e.g. /v2/*
  2. Path with named wildcard parameter. e.g. /v2/:param*
Middlewares

Middlewares and HTTP handlers have the same function signature (same as HTTP standard library's handler function). An execution chain (1 request passing through a set of middlewares and handler function) is stopped immediately after a response is sent. If you'd like the execution to continue even after a response is sent. Each Route specified has a property FallThroughPostResponse which if set to true will continue executing the chain, but no further responses will be written. You can see a sample here.

Available HTTP response functions (JSON)
  1. R200(http.ResponseWriter, payload) to send a JSON response with status 200

  2. R201(http.ResponseWriter, payload) to send a JSON response with status 201

  3. R204(http.ResponseWriter) to send a response header with status 204

  4. R302(http.ResponseWriter, payload) to send a JSON response with status 302

  5. R400(http.ResponseWriter, payload) to send a JSON response with status 400

  6. R403(http.ResponseWriter, payload) to send a JSON response with status 403

  7. R404(http.ResponseWriter, payload) to send a JSON response with status 404

  8. R406(http.ResponseWriter, payload) to send a JSON response with status 406

  9. R451(http.ResponseWriter, payload) to send a JSON response with status 451

Functions to send customized responses
  1. SendResponse(http.ResponseWriter, payload, responseCode) function in responses.go can be used to send a payload wrapped in the data struct, with any status code required.

  2. SendError(http.ResponseWriter, payload, errorCode) function in responses.go can be used to send a payload wrapped in the errors struct, with any status code required.

  3. SendHeader(http.ResponseWriter, responseCode) function in responses.go can be used to send a response header alone, with any HTTP status code required.

  4. Send(http.ResponseWriter, contentType, payload, responseCode) function in responses.go can be used to send a completely custom response.

  5. Render(http.ResponseWriter, payload, responseCode, *template.Template) can be used to render any template.

All HTTP responses are in JSON (if not rendering HTML templates and not using Send).

Configuration

WebGo configuration can be loaded directly from a JSON file using the helper Load("/path/to/json") of the struct Config.

var cfg webgo.Config
cfg.Load("path/to/config.json")

Following options can be provided in the JSON file

{
	"environment":  "", // running mode, it can be "production" or "development"
	"host": "", // Host on which the app should run
	"port": "", // Port on which the app should listen to
	"httpsOnly": false, // If true, only HTTPS server is started
	"httpsPort":  "", // Port on which the HTTPS server should listen to
	"certFile": "", // Certificate file path for HTTPS
	"keyFile": "", // Private key file path of the certificate
	"templatePath": "" // Folder containing all the templates
}
Bencmark

Simple hello world, JSON response {data: "Hello world", status: 200}.

Middlewares: CORS

Options : Logging turned off.

Source : WebGo Sample

Specs:

Machine : MacBook Pro (Retina, 13-inch, Early 2015)

Processor : 2.7 GHz Intel Core i5

Memory : 8 GB 1867 MHz DDR3

Ulimit : 50,000

$ ab -k -n 25000 -c 500 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1757674 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 2500 requests
Completed 5000 requests
Completed 7500 requests
Completed 10000 requests
Completed 12500 requests
Completed 15000 requests
Completed 17500 requests
Completed 20000 requests
Completed 22500 requests
Completed 25000 requests
Finished 25000 requests


Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /nparams
Document Length:        36 bytes

Concurrency Level:      500
Time taken for tests:   0.873 seconds
Complete requests:      25000
Failed requests:        0
Keep-Alive requests:    25000
Total transferred:      4200000 bytes
HTML transferred:       900000 bytes
Requests per second:    28621.57 [#/sec] (mean)
Time per request:       17.469 [ms] (mean)
Time per request:       0.035 [ms] (mean, across all concurrent requests)
Transfer rate:          4695.73 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   3.9      0      37
Processing:     4   17   5.8     15      43
Waiting:        4   16   5.8     15      43
Total:          4   17   7.8     15      66

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     17
  75%     19
  80%     21
  90%     25
  95%     29
  98%     47
  99%     55
 100%     66 (longest request)

How to run the tests?

You need to first start the HTTP server, you need to do the following:

$ cd /path/to/webgo/tests
$ go run main.go

After starting the server, you can run the tests by:

$ cd /path/to/webgo/tests
$ go test

Documentation

Overview

Package webgo is a lightweight framework for building web apps. It has a multiplexer, middleware plugging mechanism & context management of its own. The primary goal of webgo is to get out of the developer's way as much as possible. i.e. it does not enforce you to build your app in any particular pattern, instead just helps you get all the trivial things done faster and easier.

e.g. 1. Getting named URI parameters. 2. Multiplexer for regex matching of URI and such. 3. Inject special app level configurations or any such objects to the request context as required.

Index

Constants

View Source
const (
	// C001 Error Code 1
	C001 = "Invalid number of arguments provided"
	// C002 Error Code 2
	C002 = "Could not unmarshal JSON config file"
	// C003 Error Code 3
	C003 = "App environment not provided in config file, accepted values are `production` or `development`"
	// C004 Error Code 4
	C004 = "App port not provided in config file"
	// C005 Error Code 5
	C005 = "Invalid JSON"
)
View Source
const (
	// HeaderContentType is the key for mentioning the response header content type
	HeaderContentType = "Content-Type"
	// JSONContentType is the MIME type when the response is JSON
	JSONContentType = "application/json"
	// HTMLContentType is the MIME type when the response is HTML
	HTMLContentType = "text/html; charset=UTF-8"

	// ErrInternalServer to send when there's an internal server error
	ErrInternalServer = "Internal server error."
)

Variables

Log is used to log errors, which will print the filename and linenumber

Functions

func R200

func R200(w http.ResponseWriter, data interface{})

R200 - Successful/OK response

func R201

func R201(w http.ResponseWriter, data interface{})

R201 - New item created

func R204

func R204(w http.ResponseWriter)

R204 - empty, no content

func R302

func R302(w http.ResponseWriter, data interface{})

R302 - Temporary redirect

func R400

func R400(w http.ResponseWriter, data interface{})

R400 - Invalid request, any incorrect/erraneous value in the request body

func R403

func R403(w http.ResponseWriter, data interface{})

R403 - Unauthorized access

func R404

func R404(w http.ResponseWriter, data interface{})

R404 - Resource not found

func R406

func R406(w http.ResponseWriter, data interface{})

R406 - Unacceptable header. For any error related to values set in header

func R451

func R451(w http.ResponseWriter, data interface{})

R451 - Resource taken down because of a legal request

func R500

func R500(w http.ResponseWriter, data interface{})

R500 - Internal server error

func Render

func Render(w http.ResponseWriter, data interface{}, rCode int, tpl *template.Template)

Render is used for rendering templates (HTML)

func Render404

func Render404(w http.ResponseWriter, tpl *template.Template)

Render404 - used to render a 404 page

func Send

func Send(w http.ResponseWriter, contentType string, data interface{}, rCode int)

Send sends a completely custom response without wrapping in the `{data: <data>, status: <int>` struct

func SendError

func SendError(w http.ResponseWriter, data interface{}, rCode int)

SendError is used to respond to any request with an error

func SendHeader

func SendHeader(w http.ResponseWriter, rCode int)

SendHeader is used to send only a response header, i.e no response body

func SendResponse

func SendResponse(w http.ResponseWriter, data interface{}, rCode int)

SendResponse is used to respond to any request (JSON response) based on the code, data etc.

func Start

func Start(cfg *Config, router *Router, readTimeout, writeTimeout time.Duration)

Start starts the server with the appropriate configurations

Types

type Config

type Config struct {
	// Env is the deployment environment
	Env string `json:"environment"`
	// Host is the host on which the server is listening
	Host string `json:"host,omitempty"`
	// Port is the port number where the server has to listen for the HTTP requests
	Port string `json:"port"`

	// CertFile is the TLS/SSL certificate file path, required for HTTPS
	CertFile string `json:"certFile,omitempty"`
	// KeyFile is the filepath of private key of the certificate
	KeyFile string `json:"keyFile,omitempty"`
	// HTTPSPort is the port number where the server has to listen for the HTTP requests
	HTTPSPort string `json:"httpsPort,omitempty"`
	// HTTPSOnly if true will enable HTTPS server alone
	HTTPSOnly bool `json:"httpsOnly,omitempty"`

	// TemplatesBasePath is the base path where all the HTML templates are located
	TemplatesBasePath string `json:"templatePath,omitempty"`

	// Data holds the full json config file data as bytes
	Data []byte `json:"-"`
}

Config is used for reading app's configuration from json file

func (*Config) Load

func (cfg *Config) Load(filepath string)

Load config file from the provided filepath

func (*Config) Validate

func (cfg *Config) Validate()

Validate the config parsed into the Config struct

type ErrorData

type ErrorData struct {
	ErrCode        int
	ErrDescription string
}

ErrorData used to render the error page

type Errors

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

Errors is the custom error for webgo error handling

func New

func New(str string) *Errors

New returns a new instance of Errors struct

func (*Errors) Error

func (e *Errors) Error() string

type Globals

type Globals struct {

	// All the app configurations
	Cfg *Config

	// All templates, which can be accessed anywhere from the app
	Templates map[string]*htpl.Template

	// This can be used to add any app specifc data, which needs to be shared
	// E.g. This can be used to plug in a new DB driver, if someone does not want to use MongoDb
	App map[string]interface{}
}

Globals struct to hold configurations which are shared with all the request handlers via context.

func (*Globals) Add

func (g *Globals) Add(key string, data interface{})

Add a custom global config

func (*Globals) Init

func (g *Globals) Init(cfg *Config, tpls map[string]*htpl.Template)

Init initializes the Context and set appropriate values

type Middlewares

type Middlewares struct{}

Middlewares has all the default middlewares provided by webgo

func (*Middlewares) Cors

func (m *Middlewares) Cors(rw http.ResponseWriter, req *http.Request)

Cors is a basic Cors middleware definition.

func (*Middlewares) CorsOptions

func (m *Middlewares) CorsOptions(rw http.ResponseWriter, req *http.Request)

CorsOptions is a cors middleware just for Options request - adding this helped remove the request method check (an `if` block to check the request type) from Cors middleware

type Route

type Route struct {
	// Name is unique identifier for the route
	Name string
	// Method is the HTTP request method/type
	Method string
	// Pattern is the URI pattern to match
	Pattern string
	// TrailingSlash if set to true, the URI will be matched with or without
	// a trailing slash. Note: It does not *do* a redirect.
	TrailingSlash bool

	// HideAccessLog if enabled will not print the basic access log to console
	HideAccessLog bool

	// FallThroughPostResponse if enabled will execute all the handlers even if a response was already sent to the client
	FallThroughPostResponse bool

	// Handler is a slice of http.HandlerFunc which can be middlewares or anything else. Though only 1 of them will be allowed to respond to client.
	// subsequent writes from the following handlers will be ignored
	Handler []http.HandlerFunc
	G       *Globals // App globals
	// contains filtered or unexported fields
}

Route defines a route for each API

type Router

type Router struct {
	HideAccessLog bool
	NotFound      http.HandlerFunc
	// contains filtered or unexported fields
}

Router is the HTTP router

func InitRouter

func InitRouter(routes []*Route) *Router

InitRouter initializes Router settings

func (*Router) ServeHTTP

func (rtr *Router) ServeHTTP(rw http.ResponseWriter, req *http.Request)

ServeHTTP is the required `ServeHTTP` implementation to listen to HTTP requests

type Templates

type Templates struct {
	Tpls map[string]*template.Template
}

Templates stores all the templates the app will use, and is given to all the request handlers via context

func (*Templates) Load

func (t *Templates) Load(files map[string]string)

Load templates, all the HTML files are parsed and made available for instant use

type WC

type WC struct {
	Params map[string]string
	Route  *Route
}

WC is the webgocontext

func Context

func Context(r *http.Request) *WC

Context returns the WebgoContext injected inside the HTTP request context

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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