jh

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2017 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package jh implements a shim layer between functions that return values and errors and the httprouter.Handle function signature.

This package allows us to write http handler functions that return concrete values, for example:

func (srv *server) handle(w http.ResponseWriter, r *http.Request, ps httprouter.Params) (interface{}, error) {
	v, err := db()
	if err != nil {
		return nil, Wrap(err, "db")
	}

	return map[string]string{"val": v}, nil
}

The Adapter function takes these return values and appropriately sets headers, and converts the empty interface into a json repsonse.

There are three reasons this package exists. First of all it allows functions to divorce themselves from the JSON encoding and header setting. Secondly in returning errors it reduces cases where the explicit return is forgotten in cases such as:

if err != nil {
	http.Error(w, "this is a failure", http.StatusInternalServerError)
}
// oops, this shouldn't be reached.

Lastly it allows code called by the http view to set status code where appropriate. For example consider the following database code:

func insert(id string, val string) error {
	if find(id){
		return NewError("id already exists", http.StatusConflict)
	}
	// do insert
}

func update(id, val string) error {
	if !find(id){
		return NewError("id not found", http.StatusNotFound)
	}
	if err := db.Update(id, val); err != nil {
		return errors.Wrap(err, "db update")
	}
}

The calling function can have the appropriate headers set by using the Adapter function:

func (srv *server) update(w http.ResponseWriter, r *http.Request, ps httprouter.Params) (interface{}, error) {
	// parse json update from body

	err := update(val)
	if err != nil {
		return nil, Wrap(err, "update failure")
	}

	// ...
}

Which would return the appropriate http status code according to the underlying error.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Adapter

func Adapter(jh JSONHandler) httprouter.Handle

Adapter is middleware that converts a JSONHandler route into a normal http.HandlerFunc.

It inspects the return against a collection of interfaces to determine status codes and what to encode out as json. It correctly sets status code, and content-type.

Types

type Error

type Error interface {
	error
	HasStatus
}

Error is an error interface that also tracks http status codes

func NewError

func NewError(msg string, status int) Error

NewError returns an Error with a given http status code

func Wrap

func Wrap(err error, msg string) Error

Wrap behaves as github.com/pkg/errors.Wrap, but preserves http status codes.

type HasStatus

type HasStatus interface {
	Status() int
}

HasStatus is an interface that allows a type to expose an http status code.

type JSONHandler

type JSONHandler func(http.ResponseWriter, *http.Request, httprouter.Params) (interface{}, error)

JSONHandler is the function interface used so that an Adapter can automatically parse out status codes and set headers.

The first parameter is sent out as encoded json if error is nil, otherwise an error response is sent out as json.

type Success

type Success interface {
	HasStatus
	Data() interface{}
}

Success houses an http status code and data that will be encoded as JSON from the successful return from a JSONHandler.

func NewSuccess

func NewSuccess(data interface{}, status int) Success

NewSuccess exists to give the return from a JSONHandler an alternate http status.

For example, if you need to communicate that a resource was created:

r := NewResource()
return NewSuccess(r, http.StatusCreated), nil

Jump to

Keyboard shortcuts

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