package router import ( "bytes" "context" "encoding/json" "io" "net/http" ) type Context struct { Ctx context.Context Request *http.Request Writer http.ResponseWriter PathMap map[string]string StatusCode int } func NewContext(writer http.ResponseWriter, request *http.Request) *Context { ctx := context.Background() rctx := &Context{ Writer: writer, Request: request, Ctx: ctx, PathMap: make(map[string]string), } return rctx } // Request func (rctx *Context) GetSubpath(key string) (string, bool) { value, exists := rctx.PathMap[key] return value, exists } func (rctx *Context) GetQuery(key string) string { return rctx.Request.URL.Query().Get(key) } func (rctx *Context) GetHeader(key string) string { return rctx.Request.Header.Get(key) } func (rctx *Context) GetHeaders() http.Header { return rctx.Request.Header } func (rctx *Context) GetContext() context.Context { return rctx.Request.Context() } // Binding const emptyJSON = "{}" func (ctx *Context) BindJSON(obj any) error { buffer := bytes.NewBuffer(nil) _, err := io.Copy(buffer, ctx.Request.Body) if err != nil { return err } reqBody := buffer.Bytes() if len(reqBody) == 0 { reqBody = []byte(emptyJSON) } err = json.Unmarshal(reqBody, obj) if err != nil { return err } return err } func (ctx *Context) BindQuery(obj any) error { qMap := make(map[string]string) for key, val := range ctx.Request.URL.Query() { if len(val) == 1 { qMap[key] = val[0] } } return bindObj(obj, qMap, "param") } // Response func (rctx *Context) SetHeader(key, value string) { rctx.Writer.Header().Set(key, value) } func (rctx *Context) SetStatus(httpStatus int) { rctx.StatusCode = httpStatus rctx.Writer.WriteHeader(httpStatus) } func (rctx *Context) SendJSON(statusCode int, payload any) { rctx.Writer.Header().Set("Content-Type", "application/json") rctx.Writer.WriteHeader(statusCode) json.NewEncoder(rctx.Writer).Encode(payload) } func (rctx *Context) SendText(statusCode int, payload string) { rctx.Writer.Header().Set("Content-Type", "text/plain") rctx.Writer.WriteHeader(statusCode) rctx.Writer.Write([]byte(payload)) } func (rctx *Context) SendBytes(statusCode int, payload []byte) { rctx.Writer.WriteHeader(statusCode) rctx.Writer.Write(payload) }