package main import ( "encoding/json" "fmt" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/sqlite" "log" "net/http" "strings" "strconv" ) type server struct { name string db *gorm.DB } type Message struct { ID uint Name string Content string } func main() { db, err := gorm.Open("sqlite3", "sqlite.db") if err != nil { log.Fatal("Could not open database", err) } defer db.Close() db.DropTableIfExists(&Message{}) db.AutoMigrate(&Message{}) s := server{name: "Golang Hands-on", db: db} http.Handle("/", http.FileServer(http.Dir("resources"))) http.HandleFunc("/api/greet/", s.titleHandler) http.HandleFunc("/api/sum/", s.sumHandler) http.HandleFunc("/api/store/", s.storeHandler) if err != nil { log.Fatal(err) } log.Println("Listening on http://localhost:8080") err = http.ListenAndServe(":8080", nil) log.Fatal(err) } type greet struct { Title string `json:"title"` Subtitle string `json:"subtitle"` } func (s server) titleHandler(w http.ResponseWriter, r *http.Request) { var err error if strings.Contains(r.Header.Get("Accept"), "application/json") { w.Header().Set("Content-Type", "application/json; charset=utf8") e := json.NewEncoder(w) err = e.Encode(greet{Title: s.name, Subtitle: "Hallo Quintor!"}) } else { w.Header().Set("Content-Type", "text/plain; charset=utf8") _, err = fmt.Fprint(w, s.name) } if err != nil { log.Println(err) } } type sumRequest struct { Start int `json:"start"` End int `json:"end"` Numbers []int `json:"numbers"` } type sumResponse struct { Answer int `json:"answer"` Count int `json:"contributers"` } func (s server) sumHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf8") var sreq sumRequest d := json.NewDecoder(r.Body) err := d.Decode(&sreq) if err != nil { log.Println(err) http.Error(w, "Bad request", http.StatusBadRequest) return } var sresp sumResponse for _, val := range sreq.Numbers[sreq.Start:sreq.End] { sresp.Answer += val sresp.Count++ } e := json.NewEncoder(w) err = e.Encode(sresp) if err != nil { log.Println(err) } } type storeMessage struct { Name string `json:"name"` Content string `json:"message"` } type storeResponse struct { Id uint `json:"id"` } func (s server) storeHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=utf8") if r.Method == http.MethodPost { storeHandlePost(s.db, w, r) } else { storeHandleGet(s.db, w, r) } } func storeHandlePost(db *gorm.DB, w http.ResponseWriter, r *http.Request) { var sm storeMessage d := json.NewDecoder(r.Body) err := d.Decode(&sm) if err != nil { log.Println(err) http.Error(w, "Bad request", http.StatusBadRequest) return } m := Message{Name: sm.Name, Content: sm.Content} db.Create(&m) log.Println("message id", m.ID) e := json.NewEncoder(w) err = e.Encode(storeResponse{Id: m.ID}) if err != nil { log.Println(err) } } func storeHandleGet(db *gorm.DB, w http.ResponseWriter, r *http.Request) { log.Println(r.URL.Path, strings.TrimPrefix(r.URL.Path, "/api/store/")) id, err := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/api/store/")) if err != nil { http.NotFound(w, r) return } var m Message if err := db.First(&m, id).Error; err != nil { log.Println(err) http.NotFound(w, r) return } e := json.NewEncoder(w) err = e.Encode(storeMessage{m.Name, m.Content}) if err != nil { log.Println(err) } }