-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmain.go
141 lines (112 loc) · 3.31 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/gorilla/mux"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
)
type Star struct {
ID uint `json:"id"`
Name string `gorm:"unique" json:"name"`
Description string `json:"description"`
URL string `json:"url"`
}
type App struct {
DB *gorm.DB
}
func (a *App) Initialize(dbDriver string, dbURI string) {
db, err := gorm.Open(dbDriver, dbURI)
if err != nil {
panic("failed to connect database")
}
a.DB = db
// Migrate the schema.
a.DB.AutoMigrate(&Star{})
}
func (a *App) ListHandler(w http.ResponseWriter, r *http.Request) {
var stars []Star
// Select all stars and convert to JSON.
a.DB.Find(&stars)
starsJSON, _ := json.Marshal(stars)
// Write to HTTP response.
w.WriteHeader(200)
w.Write([]byte(starsJSON))
}
func (a *App) ViewHandler(w http.ResponseWriter, r *http.Request) {
var star Star
vars := mux.Vars(r)
// Select the star with the given name, and convert to JSON.
a.DB.First(&star, "name = ?", vars["name"])
starJSON, _ := json.Marshal(star)
// Write to HTTP response.
w.WriteHeader(200)
w.Write([]byte(starJSON))
}
func (a *App) CreateHandler(w http.ResponseWriter, r *http.Request) {
// Parse the POST body to populate r.PostForm.
if err := r.ParseForm(); err != nil {
panic("failed in ParseForm() call")
}
// Create a new star from the request body.
star := &Star{
Name: r.PostFormValue("name"),
Description: r.PostFormValue("description"),
URL: r.PostFormValue("url"),
}
a.DB.Create(star)
// Form the URL of the newly created star.
u, err := url.Parse(fmt.Sprintf("/stars/%s", star.Name))
if err != nil {
panic("failed to form new Star URL")
}
base, err := url.Parse(r.URL.String())
if err != nil {
panic("failed to parse request URL")
}
// Write to HTTP response.
w.Header().Set("Location", base.ResolveReference(u).String())
w.WriteHeader(201)
}
func (a *App) UpdateHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
// Parse the POST body to populate r.PostForm.
if err := r.ParseForm(); err != nil {
panic("failed in ParseForm() call")
}
// Set new star values from the request body.
star := &Star{
Name: r.PostFormValue("name"),
Description: r.PostFormValue("description"),
URL: r.PostFormValue("url"),
}
// Update the star with the given name.
a.DB.Model(&star).Where("name = ?", vars["name"]).Updates(&star)
// Write to HTTP response.
w.WriteHeader(204)
}
func (a *App) DeleteHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
// Delete the star with the given name.
a.DB.Where("name = ?", vars["name"]).Delete(Star{})
// Write to HTTP response.
w.WriteHeader(204)
}
func main() {
a := &App{}
a.Initialize("sqlite3", "test.db")
r := mux.NewRouter()
r.HandleFunc("/stars", a.ListHandler).Methods("GET")
r.HandleFunc("/stars/{name:.+}", a.ViewHandler).Methods("GET")
r.HandleFunc("/stars", a.CreateHandler).Methods("POST")
r.HandleFunc("/stars/{name:.+}", a.UpdateHandler).Methods("PUT")
r.HandleFunc("/stars/{name:.+}", a.DeleteHandler).Methods("DELETE")
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./build/"))).Methods("GET")
http.Handle("/", r)
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
defer a.DB.Close()
}