From fd0fc59da63c70b42df26c3fbc9d5ecf14df6120 Mon Sep 17 00:00:00 2001 From: Vic Demuzere Date: Tue, 24 Aug 2021 14:43:05 +0200 Subject: [PATCH] Switch to structs instead of maps in api Structs are slightly faster than maps, even though speed doesn't really matter in this usecase. They're also clear documentation of the possible json keys used in the API. --- api.go | 60 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/api.go b/api.go index 06dc611..7be4417 100644 --- a/api.go +++ b/api.go @@ -12,6 +12,17 @@ type apiServer struct { store storage } +type apiResponse struct { + Success bool `json:"success"` + Error string `json:"error,omitempty"` + Secret string `json:"secret,omitempty"` + SecretId string `json:"secret_id,omitempty"` +} + +type apiRequest struct { + Secret string `json:"secret"` +} + func newAPI(s storage) *apiServer { return &apiServer{ store: s, @@ -27,39 +38,30 @@ func (a apiServer) handleCreate(res http.ResponseWriter, r *http.Request) { var secret string if strings.HasPrefix(r.Header.Get("Content-Type"), "application/json") { - tmp := map[string]string{} + tmp := apiRequest{} if err := json.NewDecoder(r.Body).Decode(&tmp); err != nil { - a.jsonResponse(res, http.StatusBadRequest, map[string]interface{}{ - "success": false, - "error": err.Error(), - }) + a.errorResponse(res, http.StatusBadRequest, err.Error()) return } - secret = tmp["secret"] + secret = tmp.Secret } else { secret = r.FormValue("secret") } if secret == "" { - a.jsonResponse(res, http.StatusBadRequest, map[string]interface{}{ - "success": false, - "error": "Secret missing", - }) + a.errorResponse(res, http.StatusBadRequest, "Secret missing") return } id, err := a.store.Create(secret) if err != nil { - a.jsonResponse(res, http.StatusInternalServerError, map[string]interface{}{ - "success": false, - "error": err.Error(), - }) + a.errorResponse(res, http.StatusInternalServerError, err.Error()) return } - a.jsonResponse(res, http.StatusCreated, map[string]interface{}{ - "success": true, - "secret_id": id, + a.jsonResponse(res, http.StatusCreated, apiResponse{ + Success: true, + SecretId: id, }) } @@ -67,10 +69,7 @@ func (a apiServer) handleRead(res http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id := vars["id"] if id == "" { - a.jsonResponse(res, http.StatusBadRequest, map[string]interface{}{ - "success": false, - "error": "ID missing", - }) + a.errorResponse(res, http.StatusBadRequest, "ID missing") return } @@ -80,20 +79,23 @@ func (a apiServer) handleRead(res http.ResponseWriter, r *http.Request) { if err == errSecretNotFound { status = http.StatusNotFound } - a.jsonResponse(res, status, map[string]interface{}{ - "success": false, - "error": err.Error(), - }) + a.errorResponse(res, status, err.Error()) return } - a.jsonResponse(res, http.StatusOK, map[string]interface{}{ - "success": true, - "secret": secret, + a.jsonResponse(res, http.StatusOK, apiResponse{ + Success: true, + Secret: secret, }) } -func (a apiServer) jsonResponse(res http.ResponseWriter, status int, response map[string]interface{}) { +func (a apiServer) errorResponse(res http.ResponseWriter, status int, msg string) { + a.jsonResponse(res, status, apiResponse{ + Error: msg, + }) +} + +func (a apiServer) jsonResponse(res http.ResponseWriter, status int, response apiResponse) { res.Header().Set("Content-Type", "application/json") res.Header().Set("Cache-Control", "no-store, max-age=0") res.WriteHeader(status)