package main import ( "encoding/json" "errors" "fmt" "io" "log" "net/http" "os" "strings" "sync" "time" ) type User struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"email"` Active bool `json:"active"` CreatedAt time.Time `json:"created_at"` } type UserService struct { mu sync.RWMutex users map[int]*User } func NewUserService() *UserService { return &UserService{ users: make(map[int]*User), } } func (s *UserService) Add(user *User) error { s.mu.Lock() defer s.mu.Unlock() if user.Name == "" { return errors.New("name is required") } if !strings.Contains(user.Email, "@") { return errors.New("invalid email") } if _, exists := s.users[user.ID]; exists { return errors.New("user already exists") } s.users[user.ID] = user return nil } func (s *UserService) FindByID(id int) (*User, error) { s.mu.RLock() defer s.mu.RUnlock() user, ok := s.users[id] if !ok { return nil, fmt.Errorf("user %d not found", id) } return user, nil } func (s *UserService) FindByEmail(email string) *User { s.mu.RLock() defer s.mu.RUnlock() for _, u := range s.users { if u.Email == email { return u } } return nil } func (s *UserService) All() []*User { s.mu.RLock() defer s.mu.RUnlock() result := make([]*User, 0, len(s.users)) for _, u := range s.users { result = append(result, u) } return result } func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() log.Printf("%s %s %s", r.Method, r.URL.Path, r.RemoteAddr) next.ServeHTTP(w, r) log.Printf("%s completed in %v", r.URL.Path, time.Since(start)) }) } func handleUsers(svc *UserService) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") switch r.Method { case http.MethodGet: users := svc.All() json.NewEncoder(w).Encode(users) case http.MethodPost: var user User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } if err := svc.Add(&user); err != nil { http.Error(w, err.Error(), http.StatusConflict) return } w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(user) default: http.Error(w, "method not allowed", http.StatusMethodNotAllowed) } } } func main() { svc := NewUserService() svc.Add(&User{ ID: 1, Name: "Alice", Email: "alice@example.com", Active: true, }) mux := http.NewServeMux() mux.HandleFunc("/users", handleUsers(svc)) port := os.Getenv("PORT") if port == "" { port = "8080" } server := &http.Server{ Addr: ":" + port, Handler: loggingMiddleware(mux), ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, } log.Printf("Server starting on :%s", port) log.Fatal(server.ListenAndServe()) }