diff pkg/controllers/json.go @ 414:c1047fd04a3a

Moved project specific Go packages to new pkg folder.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 15 Aug 2018 17:30:50 +0200
parents controllers/json.go@889517f254f5
children b2dc9c2f69e0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/controllers/json.go	Wed Aug 15 17:30:50 2018 +0200
@@ -0,0 +1,111 @@
+package controllers
+
+import (
+	"database/sql"
+	"encoding/json"
+	"fmt"
+	"log"
+	"net/http"
+
+	"github.com/jackc/pgx"
+
+	"gemma.intevation.de/gemma/pkg/auth"
+)
+
+type JSONResult struct {
+	Code   int
+	Result interface{}
+}
+
+type JSONHandler struct {
+	Input  func() interface{}
+	Handle func(interface{}, *http.Request, *sql.DB) (JSONResult, error)
+}
+
+type JSONError struct {
+	Code    int
+	Message string
+}
+
+func (je JSONError) Error() string {
+	return fmt.Sprintf("%d: %s", je.Code, je.Message)
+}
+
+func (j *JSONHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+
+	var input interface{}
+	if j.Input != nil {
+		input = j.Input()
+		defer req.Body.Close()
+		if err := json.NewDecoder(req.Body).Decode(input); err != nil {
+			http.Error(rw, "error: "+err.Error(), http.StatusBadRequest)
+			return
+		}
+	}
+
+	var jr JSONResult
+	var err error
+
+	if token, ok := auth.GetToken(req); ok {
+		err = auth.ConnPool.Do(token, func(db *sql.DB) (err error) {
+			jr, err = j.Handle(input, req, db)
+			return err
+		})
+	} else {
+		jr, err = j.Handle(input, req, nil)
+	}
+
+	if err != nil {
+		switch e := err.(type) {
+		case pgx.PgError:
+			var res = struct {
+				Result  string `json:"result"`
+				Code    string `json:"code"`
+				Message string `json:"message"`
+			}{
+				Result:  "failure",
+				Code:    e.Code,
+				Message: e.Message,
+			}
+			rw.Header().Set("Content-Type", "application/json")
+			rw.WriteHeader(http.StatusInternalServerError)
+			if err := json.NewEncoder(rw).Encode(&res); err != nil {
+				log.Printf("error: %v\n", err)
+			}
+		case JSONError:
+			rw.Header().Set("Content-Type", "application/json")
+			if e.Code == 0 {
+				e.Code = http.StatusInternalServerError
+			}
+			rw.WriteHeader(e.Code)
+			var res = struct {
+				Message string `json:"message"`
+			}{
+				Message: e.Message,
+			}
+			if err := json.NewEncoder(rw).Encode(&res); err != nil {
+				log.Printf("error: %v\n", err)
+			}
+		default:
+			log.Printf("err: %v\n", err)
+			http.Error(rw,
+				"error: "+err.Error(),
+				http.StatusInternalServerError)
+		}
+		return
+	}
+
+	if jr.Code == 0 {
+		jr.Code = http.StatusOK
+	}
+
+	if jr.Code != http.StatusNoContent {
+		rw.Header().Set("Content-Type", "application/json")
+	}
+	rw.WriteHeader(jr.Code)
+	if jr.Code != http.StatusNoContent {
+		if err := json.NewEncoder(rw).Encode(jr.Result); err != nil {
+			log.Printf("error: %v\n", err)
+		}
+	}
+}