From 989dd670309eea785e7cccb73327cf9715763073 Mon Sep 17 00:00:00 2001 From: cspark Date: Tue, 6 May 2025 01:49:13 +0100 Subject: [PATCH] Implement request body handling on abstraction --- main.go | 54 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index 1fa8345..a67b1a2 100644 --- a/main.go +++ b/main.go @@ -3,11 +3,13 @@ package main import ( "encoding/json" "fmt" + "io" "log" "net/http" "os" "os/signal" "reflect" + "strings" "syscall" "time" ) @@ -43,32 +45,58 @@ type http_status_code int; const ( BAD_REQUEST http_status_code = http.StatusBadRequest ) -func http_new_route[T any](method http_method, route string, handle_func func(request *http.Request) (T, http_status_code)) { +type empty_request_body struct {} +/* T Representing any request body struct + S Representing any response body struct */ +func http_new_route[T any, S any](method http_method, route string, handle_func func(body T, raw_request *http.Request) (S, http_status_code)) { http.HandleFunc(method.to_string() + " /" + route, func(response http.ResponseWriter, request *http.Request) { - body, status_code := handle_func(request) - result, err := json.Marshal(body) + request_body_bytes, err := io.ReadAll(request.Body) if err != nil { - log.Fatal(err) + response.WriteHeader(int(INTERNAL_SERVER_ERROR)) + log.Panicln(err) + return + } + var decode_result T + if len(request_body_bytes) != 0 { + decoder := json.NewDecoder(strings.NewReader(string(request_body_bytes))) + decoder.DisallowUnknownFields() + err = decoder.Decode(&decode_result) + if err != nil { + response.WriteHeader(int(BAD_REQUEST)) + response.Write([]byte(err.Error())) + log.Println(err) + return + } + } + + body, status_code := handle_func(decode_result, request) + encode_result, err := json.Marshal(body) + if err != nil { + response.WriteHeader(int(INTERNAL_SERVER_ERROR)) + log.Panicln(err) + return } fmt.Println(reflect.VisibleFields(reflect.TypeOf(body))) response.WriteHeader(int(status_code)) - response.Write(result) + response.Write(encode_result) }) } func main() { + type foo_request_body struct { + Arg1 int + Arg2 int + } type foo_response_body struct { Field1 string - Field2 http.Header + Field2 int } - foo_route_handler := func(request *http.Request) (foo_response_body, http_status_code) { - fmt.Println(request.Header) - - return foo_response_body{ + foo_route_handler := func(body foo_request_body, raw_request *http.Request) (foo_response_body, http_status_code) { + return foo_response_body { Field1: "hi there on foo!", - Field2: request.Header, + Field2: body.Arg1 + body.Arg2, }, OK } http_new_route(GET, "foo", foo_route_handler) @@ -77,8 +105,8 @@ func main() { Response int Message string } - bar_route_handler := func(request *http.Request) (bar_response_body, http_status_code) { - return bar_response_body{ + bar_route_handler := func(body empty_request_body, raw_request *http.Request) (bar_response_body, http_status_code) { + return bar_response_body { Response: 400, Message: "hi there on bar!", }, INTERNAL_SERVER_ERROR