Giter VIP home page Giter VIP logo

binder's Introduction

binder

Go web micro-framework - http handlers without the http.Request/http.ResponseWriter clutter

binder is currently used in production.

Documentation : http://godoc.org/github.com/SoCloz/binder

Works with pat or using standard net/http handler.

Without binder :

func ViewItemHandler(w http.ResponseWriter, r *http.Request) {
	id := r.URL.Query().Get("id")
    // Fetch item from DB
	item, err := ...
	if err != nil {
		w.WriteHeader(http.StatusNotFound)
		return
	}
	jsonResult, err := json.Marshal(item)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		w.Write([]byte(err.Error()))
		return
	}
	w.Header().Set("Content-Type", "application/json")
	w.Write(jsonResult)
}

http.Handle("/items", ViewItemHandler)

With binder :

func ViewItem(i *Item) response.Response {
	if i == nil {
		return &response.Error{http.StatusNotFound, "not found, sorry"}
	}
	return &response.Json{i}
}

http.Handle("/items", binder.Wrap(ViewItem, "id"))

binder is compatible with pat (no need to add ":" to your bindings, binder automatically adds it) :

m.Get("/items/:id", binder.Wrap(ViewItem, "id"))

Bindings

binder binds query string or url parameters to your controller parameters.

func MyAction(param1 string, param2 float32, param3 []string, param4 *int) response.Response {
	str := fmt.Sprintf("param1=%v, param2=%v, param3=%v, param4=%v", param1, param2, param3, param4)
	return &response.Basic{str}
}

http.Handle("/my_action", binder.Wrap(MyAction, "param1", "param2", "param3", "param4"))
GET /my_action
param1=, param2=0, param3=[], param4=<nil>

GET /my_action?param1=foo&param2=12.5&param3=foo,bar,baz&param4=42
param1=foo, param2=12.5, param3=[foo,bar,baz], param4=0xc210148940

Binder currently binds :

  • integers (signed/unsigned)
  • floats
  • strings
  • booleans (true/false, on/off, 1/0)
  • slices (comma separated lists : value,value,value)
  • pointers (nil if no value found)
  • structs
  • custom binders
  • the request

Custom binders

You can bind an "id" url parameter to a database record using a custom binder.

import(
	"github.com/SoCloz/binder"
)

var (
	ItemBinder = func(values url.Values, name string, typ reflect.Type) (reflect.Value, bool) {
		id := binder.GetValue(values, name)
		// loads the object of id "id" from the DB
		i, err := [...]
		if err != nil {
			return reflect.Zero(typ), true
		}
		return reflect.ValueOf(i), false
	}

)

func init() {
	binder.RegisterBinder(new(Item), ItemBinder)
}

And then :

func ViewItem(i *Item) response.Response {}

m.Get("/items/:id", binder.Wrap(ViewItem, "id"))

Binding the request

If your controller has a parameter of type http.Request, it will be bound to the current http request. You can wrap it using "" (or omit "*" if it is at the end of the call) :

func ViewItem(id int, r *http.Request) response.Response {}

m.Get("/items/:id", binder.Wrap(ViewItem, "id", "*"))
m.Get("/items/:id", binder.Wrap(ViewItem, "id"))

Binding structs

Struct bindings are defined using field tags :

type Options struct {
	OnlyNames string   `binder:"only_names"`
	Page      int      `binder:"page"`
	Tags      []string `binder:"tags"`
}

func ViewItem(id int, opt Options) response.Response {}

And wrapped using "*" :

m.Get("/items/:id", binder.Wrap(ViewItem, "id", "*"))

You can omit all "*" at the end of your Wrap call :

m.Get("/items/:id", binder.Wrap(ViewItem, "id"))

Responses

The following responses are possible :

  • basic
return &response.Basic{"content"}
  • json
return &response.Json{data}
  • error
return &response.Error{http.StatusNotFound, "content"}

The status code can be changed using :

r := &response.Json{data}
r.SetStatusCode(http.StatusBadRequest)

Database connections ?

binder does not handle your database connections, your model or whatever. Use your favorite tool.

Templating ?

binder does not generate your HTML code. Use your favorite templating engine and return a response.Basic response.

Roadmap

  • binder : bind http headers
  • more response types & http headers in responses

License

See LICENCE

Thanks

Binding code was largely borrowed from revel - https://github.com/robfig/revel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.