github.com/agilebits/godog@v0.7.9/examples/db/api.go (about) 1 package main 2 3 import ( 4 "database/sql" 5 "encoding/json" 6 "fmt" 7 "net/http" 8 9 _ "github.com/go-sql-driver/mysql" 10 ) 11 12 type server struct { 13 db *sql.DB 14 } 15 16 type user struct { 17 ID int64 `json:"-"` 18 Username string `json:"username"` 19 Email string `json:"-"` 20 } 21 22 func (s *server) users(w http.ResponseWriter, r *http.Request) { 23 if r.Method != "GET" { 24 fail(w, "Method not allowed", http.StatusMethodNotAllowed) 25 return 26 } 27 28 var users []*user 29 rows, err := s.db.Query("SELECT id, email, username FROM users") 30 defer rows.Close() 31 switch err { 32 case nil: 33 for rows.Next() { 34 user := &user{} 35 if err := rows.Scan(&user.ID, &user.Email, &user.Username); err != nil { 36 fail(w, fmt.Sprintf("failed to scan an user: %s", err), http.StatusInternalServerError) 37 return 38 } 39 users = append(users, user) 40 } 41 if len(users) == 0 { 42 users = make([]*user, 0) // an empty array in this case 43 } 44 default: 45 fail(w, fmt.Sprintf("failed to fetch users: %s", err), http.StatusInternalServerError) 46 return 47 } 48 49 data := struct { 50 Users []*user `json:"users"` 51 }{Users: users} 52 53 ok(w, data) 54 } 55 56 func main() { 57 db, err := sql.Open("mysql", "root@/godog") 58 if err != nil { 59 panic(err) 60 } 61 s := &server{db: db} 62 http.HandleFunc("/users", s.users) 63 http.ListenAndServe(":8080", nil) 64 } 65 66 // fail writes a json response with error msg and status header 67 func fail(w http.ResponseWriter, msg string, status int) { 68 w.Header().Set("Content-Type", "application/json") 69 70 data := struct { 71 Error string `json:"error"` 72 }{Error: msg} 73 74 resp, _ := json.Marshal(data) 75 w.WriteHeader(status) 76 77 fmt.Fprintf(w, string(resp)) 78 } 79 80 // ok writes data to response with 200 status 81 func ok(w http.ResponseWriter, data interface{}) { 82 w.Header().Set("Content-Type", "application/json") 83 84 if s, ok := data.(string); ok { 85 fmt.Fprintf(w, s) 86 return 87 } 88 89 resp, err := json.Marshal(data) 90 if err != nil { 91 w.WriteHeader(http.StatusInternalServerError) 92 fail(w, "oops something evil has happened", 500) 93 return 94 } 95 96 fmt.Fprintf(w, string(resp)) 97 }