diff --git a/README.md b/README.md index 4780762..2ee925e 100644 --- a/README.md +++ b/README.md @@ -9,32 +9,42 @@ A [JSON API](http://jsonapi.org) specification micro-service builder created on ## Setup +The easiest way to get started is like so: + ```go import github.com/derekdowling/jsh-api -// if you want a custom logger -jshapi.Logger = yourLogger - -// create the base api -api := jshapi.New("") - -// implement jshapi/store.CRUD interface +// implement jshapi/store.CRUD interface and add resource specific middleware via Goji userStorage := &UserStorage{} resource := jshapi.NewCRUDResource("user", userStorage) +resource.UseC(yourUserMiddleware) -// resource specific middleware via Goji -resource.Use(yourUserMiddleware) - -// add resources to the API +// setup a logger, your shiny new API, and give it a resource +logger := log.New(os.Stderr, ": ", log.LstdFlags) +api := jshapi.Default("", true, logger) api.Add(resource) -// add top level API middleware -api.Use(yourTopLevelAPIMiddleware) - // launch your api http.ListenAndServe("localhost:8000", api) ``` +For a completely custom setup: + +```go +import github.com/derekdowling/jsh-api + +// manually setup your API +api := jshapi.New("") + +// add a custom send handler +jshapi.SendHandler = customHandler + +// add top level Goji Middleware +api.UseC(yourTopLevelAPIMiddleware) + +http.ListenAndServe("localhost:8000", api) +``` + ## Feature Overview ### Fast CRUD Implementation diff --git a/api.go b/api.go index fb980d7..34444a9 100644 --- a/api.go +++ b/api.go @@ -2,12 +2,15 @@ package jshapi import ( "fmt" + "log" + "os" "path" "strings" "goji.io" "goji.io/pat" + "github.com/derekdowling/go-stdlogger" "github.com/derekdowling/goji2-logger" ) @@ -20,7 +23,14 @@ type API struct { } /* -New initializes a new top level API Resource Handler without. */ +SendHandler allows the customization of how API responses are sent and logged. This +is used by all jshapi.Resource objects. +*/ +var SendHandler = DefaultSender(log.New(os.Stderr, "jshapi: ", log.LstdFlags)) + +/* +New initializes a new top level API Resource without doing any additional setup. +*/ func New(prefix string) *API { // ensure that our top level prefix is "/" prefixed @@ -42,20 +52,23 @@ started without needing to add a lot of extra functionality. The most basic implementation is: - // optionally, set your own logger that can do custom things - jshapi.Logger = yourLogger + // create a logger, the std log package works, as do most other loggers + // std.Logger interface defined here: + // https://github.com/derekdowling/go-stdlogger/blob/master/logger.go + logger := log.New(os.Stderr, "jshapi: ", log.LstdFlags) // create the API. Specify a http://yourapi// if required - api := jshapi.Default("", false) + api := jshapi.Default("", false, logger) api.Add(yourResource) */ -func Default(prefix string, debug bool) *API { +func Default(prefix string, debug bool, logger std.Logger) *API { api := New(prefix) + SendHandler = DefaultSender(logger) // register logger middleware - gojilogger := gojilogger.New(Logger, debug) + gojilogger := gojilogger.New(logger, debug) api.UseC(gojilogger.Middleware) return api diff --git a/logger.go b/logger.go deleted file mode 100644 index 17483c6..0000000 --- a/logger.go +++ /dev/null @@ -1,12 +0,0 @@ -package jshapi - -import ( - "log" - "os" - - "github.com/derekdowling/go-stdlogger" -) - -// Logger can be overridden with your own logger to utilize any custom features -// it might have. Interface defined here: https://github.com/derekdowling/go-stdlogger/blob/master/logger.go -var Logger std.Logger = log.New(os.Stderr, "jshapi: ", log.LstdFlags) diff --git a/sender.go b/sender.go index d3f8c3d..3c1e743 100644 --- a/sender.go +++ b/sender.go @@ -4,6 +4,7 @@ import ( "net/http" "github.com/derekdowling/go-json-spec-handler" + "github.com/derekdowling/go-stdlogger" "golang.org/x/net/context" ) @@ -13,25 +14,20 @@ send and log API responses. */ type Sender func(context.Context, http.ResponseWriter, *http.Request, jsh.Sendable) -/* -SendHandler is what JSHAPI uses to send all API responses. This can be overidden to -provide custom send or logging functionality. -*/ -var SendHandler Sender = DefaultSender - /* DefaultSender is the default sender that will log 5XX errors that it encounters in the process of sending a response. */ -func DefaultSender(ctx context.Context, w http.ResponseWriter, r *http.Request, sendable jsh.Sendable) { - - sendableError, isType := sendable.(jsh.ErrorType) - if isType && sendableError.StatusCode() >= 500 { - Logger.Printf("Returning ISE: %s\n", sendableError.Error()) - } +func DefaultSender(logger std.Logger) Sender { + return func(ctx context.Context, w http.ResponseWriter, r *http.Request, sendable jsh.Sendable) { + sendableError, isType := sendable.(jsh.ErrorType) + if isType && sendableError.StatusCode() >= 500 { + logger.Printf("Returning ISE: %s\n", sendableError.Error()) + } - sendError := jsh.Send(w, r, sendable) - if sendError != nil && sendError.Status >= 500 { - Logger.Printf("Error sending response: %s\n", sendError.Error()) + sendError := jsh.Send(w, r, sendable) + if sendError != nil && sendError.Status >= 500 { + logger.Printf("Error sending response: %s\n", sendError.Error()) + } } }