brick

package module
v1.0.11 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2020 License: MIT Imports: 21 Imported by: 0

README

brick

GoDoc

A Simple Golang HTTP Framework.

Features
Quick Start
// main.go
package main

import (
  "context"
  "os"

  b "github.com/pickjunk/brick"
  bd "github.com/pickjunk/brick/dbr"
  bl "github.com/pickjunk/brick/log"
)

var log = bl.New("brick.main")

func init() {
  // comment out this line if you don't use dbr
  os.Setenv("MYSQL_DSN", "root:123456@/?charset=utf8mb4")
}

func main() {
  r := b.New()

  r.GET("/hello/:name", func(ctx context.Context) {
    w := b.Response(ctx) // http.ResponseWriter
    name := b.Param(ctx, "name") // httprouter.Params.ByName("name")

    w.Write([]byte("hello "+name+"!"))
  })

  // comment out code bellow if you don't use dbr
  rWithDbr := r.Prefix("/dbr").Middlewares(bd.Middleware(nil))

  rWithDbr.GET("/empty", func(ctx context.Context) {
    w := b.Response(ctx) // http.ResponseWriter
    db := bd.Dbr(ctx) // *dbr.Session

    var test struct{}
    err := db.Select(`"empty"`).LoadOneContext(ctx, &test)
    if err != nil {
      log.Panic().Err(err).Send()
    }

    w.Write([]byte(`dbr: SELECT "empty"`))
  })

  r.ListenAndServe()
}
Config With Environments
  • PORT - the port listened to, optional, default 8080
  • MYSQL_DSN - mysql dsn used by dbr, required if use brick/dbr
  • MYSQL_MAX_IDLE - the count of mysql max idle connections, optional, default 1
  • MYSQL_MAX_OPEN - the count of mysql max open connections, optional, default 1
  • MAIL_HOST - the host of mail server, required if use brick/utils/mail
  • MAIL_PORT - the port of mail server, required if use brick/utils/mail
  • MAIL_USER - the user of mail server, required if use brick/utils/mail
  • MAIL_PASSWD - the passwd of mail server, required if use brick/utils/mail
Middlewares
r.Middlewares(
  func(ctx context.Context, next brick.Handle) {
    // do something

    next(ctx)
  },
  func(ctx context.Context, next brick.Handle) {
    // do something

    next(ctx)
  },
).GET(
  "/"
  func(ctx context.Context, next brick.Handle) {
    // do something

    next(ctx)
  },
  func(ctx context.Context) {
    // do something
  },
)
Context
r.Middlewares(
  func(ctx context.Context, next brick.Handle) {
    // context with a key & value
    next(b.WithValue(ctx, "key", value))
  },
).GET(
  "/"
  func(ctx context.Context) {
    // get a value from context by a key
    value := b.Value(ctx, "key").(type) // "type" means a type assertion here
  },
)
HTTP
r.GET("/:name", func(ctx context.Context) {
  r := b.Request(ctx) // *http.Request
  w := b.Response(ctx) // http.ResponseWriter
  ps := b.Params(ctx) // httprouter.Params
  value := b.Param(ctx, "key") // httprouter.Params.ByName("key")
})
SubRoute (Prefix + Middlewares)
subRoute1 := r.Prefix("/sub1")

subRoute2 := r.Prefix("/sub1").Middlewares(
  func(ctx context.Context, next brick.Handle) {
    // do something

    next(ctx)
  },
  func(ctx context.Context, next brick.Handle) {
    // do something

    next(ctx)
  },
)
Graphql
type resolver struct{}

var g = b.NewGraphql(&resolver{})

func init() {
  g.Schema(`
  schema {
    query: Query
  }

  type Query {
    greeting(name: String): String!
  }
  `)
}

func (r *resolver) Greeting(
  ctx context.Context,
  args struct {
    Name  *string
  },
) string {
  if args.Name == nil {
    name := "world"
    args.Name = &name
  }
  return "hello " + args.Name
}

func main() {
  r := b.New()

  r.Graphql("/graphql", g)
}
Opentracing (jaeger-client)
package main

import (
  b "github.com/pickjunk/brick"
  config "github.com/uber/jaeger-client-go/config"
)

func main() {
  r := b.New()

  closer := b.Jaeger(&config.Configuration{
    ServiceName: "brick-example",
    Sampler: &config.SamplerConfig{
      Type:  "const",
      Param: 1,
    },
    Reporter: &config.ReporterConfig{
      LogSpans: true,
    },
  })
  defer closer.Close()

  r.ListenAndServe()
}
CORS
package main

import (
  b "github.com/pickjunk/brick"
  "github.com/rs/cors"
)

func main() {
  r := b.New()

  r.CORS(cors.AllowAll()).GET("/", func(ctx context.Context) {
    // do something
  })

  r.ListenAndServe()
}
Business Error
package main

import (
  b "github.com/pickjunk/brick"
  be "github.com/pickjunk/brick/error"
)

func main() {
  r := b.New()

  r.GET("/", func(ctx context.Context) {
    // Throw will trigger a panic, which internal recover middleware
    // will catch and unmarshal to the response content as
    // `{"code":10001,"msg":"passwd error"}`
    be.Throw(10001, "passwd error")
  })

  r.ListenAndServe()
}
Logger
// create a file named logger.go in your package
// (for a convention, you should create this file in every package,
// so you can simplely call log.xxx() in every package)
package main

import (
  bl "github.com/pickjunk/brick/log"
)

var log = bl.New("component's name, like a namespace, for example, brick.main")

// main.go with the logger.go above in the same package
package main

import (
  b "github.com/pickjunk/brick"
)

func main() {
  r := b.New()

  r.GET("/", func(ctx context.Context) {
    log.Info().Msg("request access")
    // yes, the logger based on zerolog
    // more documents are [here](https://github.com/rs/zerolog)
  })

  r.ListenAndServe()
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Access

func Access(ctx context.Context) map[string]string

Access context, everything added to this map will be logged as the field of access log

func Jaeger

func Jaeger(cfg *config.Configuration) io.Closer

Jaeger setup a jaeger tracer

func Param

func Param(ctx context.Context, key string) string

Param get param from context

func Params

func Params(ctx context.Context) httprouter.Params

Params get params from context

func Request

func Request(ctx context.Context) *http.Request

Request get request from context

func Response

func Response(ctx context.Context) http.ResponseWriter

Response get response from context

func Value

func Value(ctx context.Context, key string) interface{}

Value get value with a specific key

func WithValue

func WithValue(ctx context.Context, key string, v interface{}) context.Context

WithValue create a new context with a specific key & value

Types

type Graphql

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

Graphql struct

func NewGraphql

func NewGraphql(resolver interface{}) *Graphql

NewGraphql create a Graphql struct

func (*Graphql) Schema

func (g *Graphql) Schema(s string)

Schema define graphql schema

type HTTP

type HTTP struct {
	Response http.ResponseWriter
	Request  *http.Request
	Params   httprouter.Params
}

HTTP context

type Handle

type Handle = func(context.Context)

Handle func

type Middleware

type Middleware = func(context.Context, Handle)

Middleware func

type Router

type Router struct {
	*httprouter.Router
	// contains filtered or unexported fields
}

Router thin wrapper for httprouter.Router

func New

func New() *Router

New create a brick Router

func (*Router) CORS

func (r *Router) CORS(c *cors.Cors) *Router

CORS register middlewares

func (*Router) DELETE

func (r *Router) DELETE(path string, middlewaresAndHandle ...interface{}) *Router

DELETE is a shortcut for router.Handle("DELETE", path, middlewaresAndHandle...)

func (*Router) GET

func (r *Router) GET(path string, middlewaresAndHandle ...interface{}) *Router

GET is a shortcut for router.Handle("GET", path, middlewaresAndHandle...)

func (*Router) Graphql

func (r *Router) Graphql(path string, g *Graphql) *Router

Graphql create a graphql endpoint

func (*Router) HEAD

func (r *Router) HEAD(path string, middlewaresAndHandle ...interface{}) *Router

HEAD is a shortcut for router.Handle("HEAD", path, middlewaresAndHandle...)

func (*Router) Handle

func (r *Router) Handle(method, path string, middlewaresAndHandle ...interface{}) *Router

Handle define a route

func (*Router) ListenAndServe

func (r *Router) ListenAndServe()

ListenAndServe is a shortcut for http.ListenAndServe

func (*Router) Middlewares

func (r *Router) Middlewares(layers ...Middleware) *Router

Middlewares register middlewares

func (*Router) OPTIONS

func (r *Router) OPTIONS(path string, middlewaresAndHandle ...interface{}) *Router

OPTIONS is a shortcut for router.Handle("OPTIONS", path, middlewaresAndHandle...)

func (*Router) PATCH

func (r *Router) PATCH(path string, middlewaresAndHandle ...interface{}) *Router

PATCH is a shortcut for router.Handle("PATCH", path, middlewaresAndHandle...)

func (*Router) POST

func (r *Router) POST(path string, middlewaresAndHandle ...interface{}) *Router

POST is a shortcut for router.Handle("POST", path, middlewaresAndHandle...)

func (*Router) PUT

func (r *Router) PUT(path string, middlewaresAndHandle ...interface{}) *Router

PUT is a shortcut for router.Handle("PUT", path, middlewaresAndHandle...)

func (*Router) Prefix

func (r *Router) Prefix(p string) *Router

Prefix append prefix

func (*Router) Serve

func (r *Router) Serve(l net.Listener)

Serve is a shortcut for http.Serve

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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