Skip to content

jmptrader/go-rest

 
 

Repository files navigation

go-rest

Package rest is a RESTful web-service framework. It make function to http.Handler automatically.

Build StatusBuild StatusCoverage StatusBitdeli Badge

Why another rest framework?

I want to make a clear, flexible framework, which easy to write and test. Here is some principle when I design go-rest:

  • Don't repeat yourself.

    The framework will grab as many as it can to set up service. No need to specify "postdata" type or "output" type which has defined in handler.

  • Handle HTTP directly if you want.

    Handler support http.Handler or http.HandleFunc directly, so you can add old style handler, like http.FileServer directly.

  • Handle HTTP request right.

    Use Accept to check mime. If Accept doesn't exist, use service default mime.

  • Work with other framework.

    Package go-rest will work with GAE or net/http or any other framework working with http.Handler.

  • Speed.

    Golang is fast, framework should be fast too.

  • Easy to do unit test.

    No need to worry about marshal and unmarshal when do unit test, handler function is normal function, test it directly.

Install

$ go get github.com/googollee/go-rest

Document

http://godoc.org/github.com/googollee/go-rest

A over all example

package main 

import (
	"fmt"
	"github.com/googollee/go-rest"
	"net/http"
	"strings"
)

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

	// add log midware
	r.Use(rest.NewLog(nil))

	// add router. router must before mime parser because parser need handler's parameter inserted by router.
	r.Use(rest.NewRouter())

	// support mime of text/html and application/json
	html, err := rest.NewHTML("./templates")
	if err != nil {
		fmt.Println("html template error:", err)
		return
	}
	r.Use(rest.NewMimeParser(html, rest.NewJSON()))

	// simple handler
	r.Get("/", func() (map[string]interface{}, string) {
		return map[string]interface{}{"name": "rest"}, "hello"
	})

	// rest handler, name from post body
	r.Get("/hello.js", func(name string) map[string]interface{} {
		return map[string]interface{}{
			"action": "hello",
			"name":   name,
		}
	})

	// handle url parameter.
	r.Get("/hello/:name", func(params rest.Params) (map[string]interface{}, string) {
		return params, "hello"
	})

	// handle url parameter and post body, and return error if invalid.
	r.Post("/json/:id", func(params rest.Params, i int) (map[string]interface{}, error) {
		if params["id"] == nil {
			return nil, rest.Error(http.StatusBadRequest, "id is empty")
		}
		id, ok := params["id"].(string)
		if !ok {
			return nil, rest.Error(http.StatusBadRequest, "id is not string")
		}
		if id == "" {
			return nil, rest.Error(http.StatusBadRequest, "id is empty")
		}
		return map[string]interface{}{
			"id":      id,
			"request": i,
		}, nil
	})

	// handle static file
	r.NotFound(prefix("/static/"), http.FileServer(http.Dir(".")))

	// launch http server
	http.ListenAndServe("127.0.0.1:8080", r)
}

// custom midware
func prefix(prefix string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if !strings.HasPrefix(r.URL.Path, prefix) {
			http.NotFound(w, r)
			return
		}
	}
}

About

Package rest is a RESTful web-service framework. It make service struct to http.Handler automatically.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Go 59.6%
  • HTML 40.4%