package api import ( "context" "encoding/json" "net/http" "github.com/go-chi/chi/v5" "github.com/go-chi/render" "time" ) func MessageCtx(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var message *Message var err error if messageID := chi.URLParam(r, "messageID"); messageID != "" { message, err = dbGetMessage(messageID) } else { render.Render(w, r, ErrNotFound) return } if err != nil { render.Render(w, r, ErrNotFound) return } ctx := context.WithValue(r.Context(), messageKey{}, message) next.ServeHTTP(w, r.WithContext(ctx)) }) } func GetMessage(w http.ResponseWriter, r *http.Request) { message, ok := r.Context().Value(messageKey{}).(*Message) if !ok || message == nil { render.Render(w, r, ErrNotFound) return } if err := render.Render(w, r, NewMessageResponse(message)); err != nil { render.Render(w, r, ErrRender(err)) return } } func ListMessages(w http.ResponseWriter, r *http.Request) { dbMessages, err := dbGetAllMessages() if err != nil { render.Render(w, r, ErrRender(err)) return } if err := render.RenderList(w, r, NewMessageListResponse(dbMessages)); err != nil { render.Render(w, r, ErrRender(err)) return } } type messageKey struct{} type Message struct { ID string `json:"id"` UserID int64 `json:"user_id"` Body string `json:"body"` Timestamp time.Time `json:"timestamp"` } type MessageRequest struct { *Message User *UserPayload `json:"user"` ProtectedID string `json:"id"` } type MessageResponse struct { *Message User *UserPayload `json:"user,omitempty"` Elapsed int64 `json:"elapsed"` } func (m MessageResponse) MarshalJSON() ([]byte, error) { type OrderedMessageResponse struct { ID string `json:"id"` UserID int64 `json:"user_id"` Body string `json:"body"` Timestamp string `json:"timestamp"` User *UserPayload `json:"user,omitempty"` Elapsed int64 `json:"elapsed"` } ordered := OrderedMessageResponse{ ID: m.Message.ID, UserID: m.Message.UserID, Body: m.Message.Body, Timestamp: m.Message.Timestamp.Format(time.RFC3339), User: m.User, Elapsed: m.Elapsed, } return json.Marshal(ordered) }