major refactoring of the api
This commit is contained in:
1 parent
d4f7dc57fc
commit
f0628e4682
38 files changed
+821
-367
No files matched your search
@@ -0,0 +1,52 @@
|
||||
package simpleapi
|
||||
|
||||
import (
|
||||
"github.com/gorilla/mux"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path"
|
||||
)
|
||||
|
||||
func JSONHendler(handler http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, request *http.Request) {
|
||||
w.Header().Add("Content-Type", mime.TypeByExtension(".json"))
|
||||
handler(w, request)
|
||||
}
|
||||
}
|
||||
|
||||
type Endpoint struct {
|
||||
Pattern string
|
||||
Description string
|
||||
Method string
|
||||
HandlerFunc http.HandlerFunc
|
||||
}
|
||||
|
||||
type SimpleApi struct {
|
||||
apiEndpoints []*Endpoint
|
||||
router *mux.Router
|
||||
prefix string
|
||||
}
|
||||
|
||||
func New(prefix string, apiEndpoints ...*Endpoint) *SimpleApi {
|
||||
api := &SimpleApi{apiEndpoints, nil, prefix}
|
||||
api.initRouter()
|
||||
return api
|
||||
}
|
||||
|
||||
func (api *SimpleApi) initRouter() {
|
||||
api.router = mux.NewRouter()
|
||||
for _, apiEndpoint := range api.apiEndpoints {
|
||||
api.router.Path(path.Join(api.prefix, apiEndpoint.Pattern)).
|
||||
Methods(apiEndpoint.Method).
|
||||
HandlerFunc(JSONHendler(apiEndpoint.HandlerFunc))
|
||||
}
|
||||
}
|
||||
|
||||
func (api *SimpleApi) Set404Handler(handler http.HandlerFunc) {
|
||||
api.router.NotFoundHandler = http.HandlerFunc(handler)
|
||||
|
||||
}
|
||||
|
||||
func (api *SimpleApi) ServeHTTP(w http.ResponseWriter, request *http.Request) {
|
||||
api.router.ServeHTTP(w, request)
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package simpleapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type requestData struct {
|
||||
Path string
|
||||
Method string
|
||||
Response *http.Response
|
||||
}
|
||||
|
||||
func createRequestData(r *http.Request) *requestData {
|
||||
return &requestData{r.URL.Path, r.Method, nil}
|
||||
|
||||
}
|
||||
|
||||
func GetHandlerFunc() http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.Encode(createRequestData(r))
|
||||
}
|
||||
}
|
||||
|
||||
func GetMockApiEndpoint(pattern, method string) *Endpoint {
|
||||
return &Endpoint{Pattern: pattern, Method: method, HandlerFunc: GetHandlerFunc()}
|
||||
}
|
||||
|
||||
func GET(ts *httptest.Server, path string) (*requestData, error) {
|
||||
res, err := http.Get(ts.URL + path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.Body.Close()
|
||||
ret := new(requestData)
|
||||
if err := json.Unmarshal(body, ret); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret.Response = res
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func POST(ts *httptest.Server, path, data string) (*requestData, error) {
|
||||
res, err := http.Post(ts.URL+path, "", bytes.NewBufferString(data))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res.Body.Close()
|
||||
ret := new(requestData)
|
||||
return ret, json.Unmarshal(body, ret)
|
||||
}
|
||||
|
||||
func TestServeGet(t *testing.T) {
|
||||
api := New("/", GetMockApiEndpoint("/", "GET"))
|
||||
ts := httptest.NewServer(api)
|
||||
defer ts.Close()
|
||||
|
||||
if rd, err := GET(ts, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if rd.Path != "/" {
|
||||
t.Error(rd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServeGetSpecificPath(t *testing.T) {
|
||||
api := New("/", GetMockApiEndpoint("/some/path", "GET"))
|
||||
ts := httptest.NewServer(api)
|
||||
defer ts.Close()
|
||||
|
||||
if rd, err := GET(ts, "/some/path"); err != nil {
|
||||
t.Error(err)
|
||||
} else if rd.Path != "/some/path" {
|
||||
t.Error(rd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServePOSTSpecificPath(t *testing.T) {
|
||||
api := New("/", GetMockApiEndpoint("/some/path", "POST"))
|
||||
ts := httptest.NewServer(api)
|
||||
defer ts.Close()
|
||||
|
||||
if rd, err := POST(ts, "/some/path", ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if rd.Path != "/some/path" || rd.Method != "POST" {
|
||||
t.Error(rd)
|
||||
}
|
||||
}
|
||||
|
||||
func Test404(t *testing.T) {
|
||||
api := New("/")
|
||||
api.Set404Handler(GetHandlerFunc())
|
||||
ts := httptest.NewServer(api)
|
||||
defer ts.Close()
|
||||
|
||||
if rd, err := GET(ts, "/some/path"); err != nil {
|
||||
t.Error(err)
|
||||
} else if rd.Path != "/some/path" || rd.Method != "GET" {
|
||||
t.Error(rd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaders(t *testing.T) {
|
||||
api := New("/", GetMockApiEndpoint("/", "GET"))
|
||||
ts := httptest.NewServer(api)
|
||||
defer ts.Close()
|
||||
|
||||
if rd, err := GET(ts, ""); err != nil {
|
||||
t.Error(err)
|
||||
} else if rd.Response.Header.Get("Content-Type") != "application/json" {
|
||||
t.Error(rd)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServePrefix(t *testing.T) {
|
||||
api := New("/api", GetMockApiEndpoint("/foo/bar", "GET"))
|
||||
ts := httptest.NewServer(api)
|
||||
defer ts.Close()
|
||||
|
||||
if rd, err := GET(ts, "/api/foo/bar"); err != nil {
|
||||
t.Error(err)
|
||||
} else if rd.Path != "/api/foo/bar" {
|
||||
t.Error(rd)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user