Skip to main content
Glama
main.go5.11 kB
package main import ( "encoding/json" "log" "net/http" "strconv" "sync" "time" ) // ============================================ // Models // ============================================ type User struct { ID int `json:"id"` Email string `json:"email"` Name string `json:"name"` CreatedAt time.Time `json:"created_at"` } type CreateUserRequest struct { Email string `json:"email"` Name string `json:"name"` } type APIResponse struct { Success bool `json:"success"` Data interface{} `json:"data,omitempty"` Error string `json:"error,omitempty"` } // ============================================ // Database (Thread-Safe In-Memory) // ============================================ type Database struct { users map[int]*User nextID int mu sync.RWMutex } func NewDatabase() *Database { return &Database{ users: make(map[int]*User), nextID: 1, } } func (db *Database) CreateUser(req CreateUserRequest) *User { db.mu.Lock() defer db.mu.Unlock() user := &User{ ID: db.nextID, Email: req.Email, Name: req.Name, CreatedAt: time.Now(), } db.users[db.nextID] = user db.nextID++ return user } func (db *Database) GetUser(id int) *User { db.mu.RLock() defer db.mu.RUnlock() return db.users[id] } func (db *Database) GetAllUsers() []*User { db.mu.RLock() defer db.mu.RUnlock() users := make([]*User, 0, len(db.users)) for _, user := range db.users { users = append(users, user) } return users } func (db *Database) DeleteUser(id int) bool { db.mu.Lock() defer db.mu.Unlock() if _, exists := db.users[id]; exists { delete(db.users, id) return true } return false } // ============================================ // Middleware // ============================================ func loggingMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() next.ServeHTTP(w, r) log.Printf("[%s] %s %s", r.Method, r.URL.Path, time.Since(start)) }) } func corsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK) return } next.ServeHTTP(w, r) }) } // ============================================ // Handlers // ============================================ var db = NewDatabase() func respondJSON(w http.ResponseWriter, status int, data interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) json.NewEncoder(w).Encode(data) } func healthHandler(w http.ResponseWriter, r *http.Request) { respondJSON(w, http.StatusOK, map[string]string{ "status": "healthy", "timestamp": time.Now().Format(time.RFC3339), }) } func getUsersHandler(w http.ResponseWriter, r *http.Request) { users := db.GetAllUsers() respondJSON(w, http.StatusOK, APIResponse{Success: true, Data: users}) } func createUserHandler(w http.ResponseWriter, r *http.Request) { var req CreateUserRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { respondJSON(w, http.StatusBadRequest, APIResponse{Error: "Invalid JSON"}) return } if req.Email == "" || req.Name == "" { respondJSON(w, http.StatusBadRequest, APIResponse{Error: "Email and name required"}) return } user := db.CreateUser(req) respondJSON(w, http.StatusCreated, APIResponse{Success: true, Data: user}) } func getUserHandler(w http.ResponseWriter, r *http.Request) { idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { respondJSON(w, http.StatusBadRequest, APIResponse{Error: "Invalid ID"}) return } user := db.GetUser(id) if user == nil { respondJSON(w, http.StatusNotFound, APIResponse{Error: "User not found"}) return } respondJSON(w, http.StatusOK, APIResponse{Success: true, Data: user}) } func deleteUserHandler(w http.ResponseWriter, r *http.Request) { idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) if err != nil { respondJSON(w, http.StatusBadRequest, APIResponse{Error: "Invalid ID"}) return } if !db.DeleteUser(id) { respondJSON(w, http.StatusNotFound, APIResponse{Error: "User not found"}) return } w.WriteHeader(http.StatusNoContent) } // ============================================ // Main // ============================================ func main() { mux := http.NewServeMux() // Routes (Go 1.22+ path patterns) mux.HandleFunc("GET /health", healthHandler) mux.HandleFunc("GET /api/users", getUsersHandler) mux.HandleFunc("POST /api/users", createUserHandler) mux.HandleFunc("GET /api/users/{id}", getUserHandler) mux.HandleFunc("DELETE /api/users/{id}", deleteUserHandler) // Apply middleware handler := loggingMiddleware(corsMiddleware(mux)) log.Println("Server running on http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", handler)) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/millsydotdev/Code-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server