Skip to content

Commit

Permalink
Add standardization to HTTP response
Browse files Browse the repository at this point in the history
  • Loading branch information
zeeshanbhati committed Oct 2, 2024
1 parent 7894fd2 commit 30fe4d1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 41 deletions.
41 changes: 5 additions & 36 deletions internal/server/httpServer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package server

import (
"context"
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"server/internal/middleware"
Expand All @@ -28,17 +26,6 @@ type HandlerMux struct {
rateLimiter func(http.ResponseWriter, *http.Request, http.Handler)
}

type HTTPResponse struct {
Data interface{} `json:"data"`
}

type HTTPErrorResponse struct {
Error interface{} `json:"error"`
}

func errorResponse(response string) string {
return fmt.Sprintf("{\"error\": %q}", response)
}

func (cim *HandlerMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Convert the path to lowercase before passing to the underlying mux.
Expand Down Expand Up @@ -91,43 +78,25 @@ func (s *HTTPServer) Shutdown() error {
}

func (s *HTTPServer) HealthCheck(w http.ResponseWriter, request *http.Request) {
util.JSONResponse(w, http.StatusOK, map[string]string{"message": "Server is running"})
util.HttpResponseJSON(w, http.StatusOK, map[string]string{"message": "Server is running"})
}

func (s *HTTPServer) CliHandler(w http.ResponseWriter, r *http.Request) {
diceCmd, err := util.ParseHTTPRequest(r)
if err != nil {
http.Error(w, "Error parsing HTTP request", http.StatusBadRequest)
util.HttpResponseException(w,http.StatusBadRequest,"Error parsing HTTP request");
return
}

resp, err := s.DiceClient.ExecuteCommand(diceCmd)
if err != nil {
http.Error(w, errorResponse(err.Error()), http.StatusBadRequest)
return
}

if _, ok := resp.(string); !ok {
log.Println("Error marshaling response", "error", err)
http.Error(w, errorResponse("Internal Server Error"), http.StatusInternalServerError)
util.HttpResponseException(w,http.StatusBadRequest,err);
return
}

httpResponse := HTTPResponse{Data: resp.(string)}
responseJSON, err := json.Marshal(httpResponse)
if err != nil {
log.Println("Error marshaling response", "error", err)
http.Error(w, errorResponse("Internal Server Error"), http.StatusInternalServerError)
return
}

_, err = w.Write(responseJSON)
if err != nil {
http.Error(w, errorResponse("Internal Server Error"), http.StatusInternalServerError)
return
}
util.HttpResponseJSON(w, http.StatusOK, resp)
}

func (s *HTTPServer) SearchHandler(w http.ResponseWriter, request *http.Request) {
util.JSONResponse(w, http.StatusOK, map[string]string{"message": "Search results"})
util.HttpResponseJSON(w,http.StatusOK,map[string]string{"message": "Search results"});
}
60 changes: 55 additions & 5 deletions pkg/util/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"io"
"net/http"
"os"
"runtime/debug"
"server/internal/cmds"
"strings"
)
Expand All @@ -31,6 +33,19 @@ const (
JSONIngest string = "JSON.INGEST"
)

type HttpResponse struct {
Data interface{} `json:"data"`
Error *ErrorDetails `json:"error"`
HasError bool `json:"hasError"`
HasData bool `json:"hasData"`
StackTrace *string `json:"stackTrace,omitempty"`
}

type ErrorDetails struct {
Message *string `json:"message"`
StackTrace *string `json:"stackTrace,omitempty"`
}

func ParseHTTPRequest(r *http.Request) (*cmds.CommandRequest, error) {
command := strings.TrimPrefix(r.URL.Path, "/cli/")
if command == "" {
Expand Down Expand Up @@ -154,10 +169,45 @@ func ParseHTTPRequest(r *http.Request) (*cmds.CommandRequest, error) {
}, nil
}

func JSONResponse(w http.ResponseWriter, status int, data interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
func generateHttpResponse(w http.ResponseWriter, statusCode int, data interface{}, err *string) {
response := HttpResponse{
HasData: data != nil,
HasError: err != nil,
Data: data,
}

if err != nil {
errorDetails := &ErrorDetails{
Message: err,
}
if os.Getenv("ENV") == "development" {
stackTrace := string(debug.Stack())
errorDetails.StackTrace = &stackTrace
}
response.Error = errorDetails
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(statusCode)

if encodeErr := json.NewEncoder(w).Encode(response); encodeErr != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
}

func HttpResponseJSON(w http.ResponseWriter,statusCode int, data interface{}) {
generateHttpResponse(w, http.StatusOK, data, nil)
}

func HttpResponseException(w http.ResponseWriter, statusCode int, err interface{}) {
var errorStr string
switch e := err.(type) {
case error:
errorStr = e.Error()
case string:
errorStr = e
default:
errorStr = "Unknown error type"
}
generateHttpResponse(w, statusCode, nil, &errorStr)
}

0 comments on commit 30fe4d1

Please sign in to comment.