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.
This commit is contained in:
Vic Demuzere 2021-08-24 14:43:05 +02:00
parent 26233c635c
commit fd0fc59da6
No known key found for this signature in database
GPG Key ID: 5B9EA1616690CF94

60
api.go
View File

@ -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)