Mercurial > gemma
comparison 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 |
comparison
equal
deleted
inserted
replaced
413:a9440a4826aa | 414:c1047fd04a3a |
---|---|
1 package controllers | |
2 | |
3 import ( | |
4 "database/sql" | |
5 "encoding/json" | |
6 "fmt" | |
7 "log" | |
8 "net/http" | |
9 | |
10 "github.com/jackc/pgx" | |
11 | |
12 "gemma.intevation.de/gemma/pkg/auth" | |
13 ) | |
14 | |
15 type JSONResult struct { | |
16 Code int | |
17 Result interface{} | |
18 } | |
19 | |
20 type JSONHandler struct { | |
21 Input func() interface{} | |
22 Handle func(interface{}, *http.Request, *sql.DB) (JSONResult, error) | |
23 } | |
24 | |
25 type JSONError struct { | |
26 Code int | |
27 Message string | |
28 } | |
29 | |
30 func (je JSONError) Error() string { | |
31 return fmt.Sprintf("%d: %s", je.Code, je.Message) | |
32 } | |
33 | |
34 func (j *JSONHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { | |
35 | |
36 var input interface{} | |
37 if j.Input != nil { | |
38 input = j.Input() | |
39 defer req.Body.Close() | |
40 if err := json.NewDecoder(req.Body).Decode(input); err != nil { | |
41 http.Error(rw, "error: "+err.Error(), http.StatusBadRequest) | |
42 return | |
43 } | |
44 } | |
45 | |
46 var jr JSONResult | |
47 var err error | |
48 | |
49 if token, ok := auth.GetToken(req); ok { | |
50 err = auth.ConnPool.Do(token, func(db *sql.DB) (err error) { | |
51 jr, err = j.Handle(input, req, db) | |
52 return err | |
53 }) | |
54 } else { | |
55 jr, err = j.Handle(input, req, nil) | |
56 } | |
57 | |
58 if err != nil { | |
59 switch e := err.(type) { | |
60 case pgx.PgError: | |
61 var res = struct { | |
62 Result string `json:"result"` | |
63 Code string `json:"code"` | |
64 Message string `json:"message"` | |
65 }{ | |
66 Result: "failure", | |
67 Code: e.Code, | |
68 Message: e.Message, | |
69 } | |
70 rw.Header().Set("Content-Type", "application/json") | |
71 rw.WriteHeader(http.StatusInternalServerError) | |
72 if err := json.NewEncoder(rw).Encode(&res); err != nil { | |
73 log.Printf("error: %v\n", err) | |
74 } | |
75 case JSONError: | |
76 rw.Header().Set("Content-Type", "application/json") | |
77 if e.Code == 0 { | |
78 e.Code = http.StatusInternalServerError | |
79 } | |
80 rw.WriteHeader(e.Code) | |
81 var res = struct { | |
82 Message string `json:"message"` | |
83 }{ | |
84 Message: e.Message, | |
85 } | |
86 if err := json.NewEncoder(rw).Encode(&res); err != nil { | |
87 log.Printf("error: %v\n", err) | |
88 } | |
89 default: | |
90 log.Printf("err: %v\n", err) | |
91 http.Error(rw, | |
92 "error: "+err.Error(), | |
93 http.StatusInternalServerError) | |
94 } | |
95 return | |
96 } | |
97 | |
98 if jr.Code == 0 { | |
99 jr.Code = http.StatusOK | |
100 } | |
101 | |
102 if jr.Code != http.StatusNoContent { | |
103 rw.Header().Set("Content-Type", "application/json") | |
104 } | |
105 rw.WriteHeader(jr.Code) | |
106 if jr.Code != http.StatusNoContent { | |
107 if err := json.NewEncoder(rw).Encode(jr.Result); err != nil { | |
108 log.Printf("error: %v\n", err) | |
109 } | |
110 } | |
111 } |