///
Search

08_Restful API(4)

Restful하게 Update, GetList 작성

/myapp/app_test.go

package myapp import ( "encoding/json" "fmt" "io/ioutil" "net/http" "net/http/httptest" "strconv" "strings" "testing" "github.com/stretchr/testify/assert" ) func TestIndex(t *testing.T) { assert := assert.New(t) ts := httptest.NewServer(NewHandler()) defer ts.Close() resp, err := http.Get(ts.URL) assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) data, _ := ioutil.ReadAll(resp.Body) assert.Equal("Hello World", string(data)) } func TestUsers(t *testing.T) { assert := assert.New(t) ts := httptest.NewServer(NewHandler()) defer ts.Close() resp, err := http.Get(ts.URL + "/users") assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) data, _ := ioutil.ReadAll(resp.Body) assert.Equal(string(data), "No Users") } func TestGetUserInfo(t *testing.T) { assert := assert.New(t) ts := httptest.NewServer(NewHandler()) defer ts.Close() resp, err := http.Get(ts.URL + "/users/89") assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) data, _ := ioutil.ReadAll(resp.Body) assert.Contains(string(data), "No User Id:89") resp, err = http.Get(ts.URL + "/users/56") assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) data, _ = ioutil.ReadAll(resp.Body) assert.Contains(string(data), "No User Id:56") } func TestCreateUser(t *testing.T) { assert := assert.New(t) ts := httptest.NewServer(NewHandler()) defer ts.Close() resp, err := http.Post(ts.URL+"/users", "application/json", strings.NewReader(`{"first_name":"tucker", "last_name":"kim", "email":"tucker@naver.com"}`)) assert.NoError(err) assert.Equal(http.StatusCreated, resp.StatusCode) user := new(User) err = json.NewDecoder(resp.Body).Decode(user) assert.NoError(err) assert.NotEqual(0, user.ID) id := user.ID resp, err = http.Get(ts.URL + "/users/" + strconv.Itoa(id)) assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) user2 := new(User) err = json.NewDecoder(resp.Body).Decode(user2) assert.NoError(err) assert.Equal(user.ID, user2.ID) assert.Equal(user.FirstName, user2.FirstName) } func TestDeleteUser(t *testing.T) { assert := assert.New(t) ts := httptest.NewServer(NewHandler()) defer ts.Close() req, _ := http.NewRequest("DELETE", ts.URL+"/users/1", nil) resp, err := http.DefaultClient.Do(req) assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) data, _ := ioutil.ReadAll(resp.Body) assert.Contains(string(data), "No User ID:1") resp, err = http.Post(ts.URL+"/users", "application/json", strings.NewReader(`{"first_name":"tucker", "last_name":"kim", "email":"tucker@naver.com"}`)) assert.NoError(err) assert.Equal(http.StatusCreated, resp.StatusCode) user := new(User) err = json.NewDecoder(resp.Body).Decode(user) assert.NoError(err) assert.NotEqual(0, user.ID) req, _ = http.NewRequest("DELETE", ts.URL+"/users/1", nil) resp, err = http.DefaultClient.Do(req) assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) data, _ = ioutil.ReadAll(resp.Body) assert.Contains(string(data), "Deleted User ID:1") } func TestUpdateUser(t *testing.T) {//여기서 부터 시작 assert := assert.New(t) ts := httptest.NewServer(NewHandler()) defer ts.Close() req, _ := http.NewRequest("PUT", ts.URL+"/users", strings.NewReader(`{"id":1, "first_name":"updated", "last_name":"updated", "email":"updated@naver.com"}`)) resp, err := http.DefaultClient.Do(req) assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) data, _ := ioutil.ReadAll(resp.Body) assert.Contains(string(data), "No User ID:1") // Update가 없을때 Error 던지기 resp, err = http.Post(ts.URL+"/users", "application/json", strings.NewReader(`{"first_name":"tucker", "last_name":"kim", "email":"tucker@naver.com"}`)) assert.NoError(err) assert.Equal(http.StatusCreated, resp.StatusCode) user := new(User) err = json.NewDecoder(resp.Body).Decode(user) assert.NoError(err) assert.NotEqual(0, user.ID) updateStr := fmt.Sprintf(`{"id":%d, "first_name":"jason"}`, user.ID) req, _ = http.NewRequest("PUT", ts.URL+"/users", strings.NewReader(updateStr)) resp, err = http.DefaultClient.Do(req) assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) updateUser := new(User) err = json.NewDecoder(resp.Body).Decode(updateUser) assert.NoError(err) assert.Equal(updateUser.ID, user.ID) assert.Equal("jason", updateUser.FirstName) assert.Equal(user.LastName, updateUser.LastName) assert.Equal(user.Email, updateUser.Email) } func TestUsers_WithUsersData(t *testing.T) { assert := assert.New(t) ts := httptest.NewServer(NewHandler()) defer ts.Close() resp, err := http.Post(ts.URL+"/users", "application/json", strings.NewReader(`{"first_name":"tucker", "last_name":"kim", "email":"tucker@naver.com"}`)) assert.NoError(err) assert.Equal(http.StatusCreated, resp.StatusCode) resp, err = http.Post(ts.URL+"/users", "application/json", strings.NewReader(`{"first_name":"jason", "last_name":"park", "email":"jason@naver.com"}`)) assert.NoError(err) assert.Equal(http.StatusCreated, resp.StatusCode) resp, err = http.Get(ts.URL + "/users") assert.NoError(err) assert.Equal(http.StatusOK, resp.StatusCode) users := []*User{} err = json.NewDecoder(resp.Body).Decode(&users) assert.NoError(err) assert.Equal(2, len(users)) }
Go
복사

/myapp/app.go

package myapp import ( "encoding/json" "fmt" "net/http" "strconv" "time" "github.com/gorilla/mux" ) // User struct type User struct { ID int `json:"id"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Email string `json:"email"` CreatedAt time.Time `json:"created_at"` } var userMap map[int]*User var lastID int func indexHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hello World") } func usersHandler(w http.ResponseWriter, r *http.Request) { if len(userMap) == 0 { w.WriteHeader(http.StatusOK) fmt.Fprint(w, "No Users") return } users := []*User{} for _, u := range userMap { users = append(users, u) } data, _ := json.Marshal(users) w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) fmt.Fprint(w, string(data)) } func getUserInfoHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id, err := strconv.Atoi(vars["id"]) if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprint(w, err) return } user, ok := userMap[id] if !ok { w.WriteHeader(http.StatusOK) fmt.Fprint(w, "No User Id:", id) return } w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) data, _ := json.Marshal(user) fmt.Fprint(w, string(data)) } func createUserHandler(w http.ResponseWriter, r *http.Request) { user := new(User) err := json.NewDecoder(r.Body).Decode(user) if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprint(w, err) return } // Created User lastID++ user.ID = lastID user.CreatedAt = time.Now() userMap[user.ID] = user w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) data, _ := json.Marshal(user) fmt.Fprint(w, string(data)) } func deleteUserHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) id, err := strconv.Atoi(vars["id"]) if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprint(w, err) return } _, ok := userMap[id] if !ok { w.WriteHeader(http.StatusOK) fmt.Fprint(w, "No User ID:", id) return } delete(userMap, id) w.WriteHeader(http.StatusOK) fmt.Fprint(w, "Deleted User ID:", id) } func updateUserHandler(w http.ResponseWriter, r *http.Request) { updateUser := new(User) err := json.NewDecoder(r.Body).Decode(updateUser) if err != nil { w.WriteHeader(http.StatusBadRequest) fmt.Fprint(w, err) return } user, ok := userMap[updateUser.ID] if !ok { w.WriteHeader(http.StatusOK) fmt.Fprint(w, "No User ID:", updateUser.ID) return } if updateUser.FirstName != "" { user.FirstName = updateUser.FirstName } if updateUser.LastName != "" { user.LastName = updateUser.LastName } if updateUser.Email != "" { user.Email = updateUser.Email } w.Header().Add("Content-Type", "application/json") w.WriteHeader(http.StatusOK) data, _ := json.Marshal(user) fmt.Fprint(w, string(data)) } // NewHandler make a new myapp handler func NewHandler() http.Handler { userMap = make(map[int]*User) lastID = 0 mux := mux.NewRouter() mux.HandleFunc("/", indexHandler) mux.HandleFunc("/users", usersHandler).Methods("GET") mux.HandleFunc("/users", createUserHandler).Methods("POST") mux.HandleFunc("/users", updateUserHandler).Methods("PUT") mux.HandleFunc("/users/{id:[0-9]+}", getUserInfoHandler).Methods("GET") mux.HandleFunc("/users/{id:[0-9]+}", deleteUserHandler).Methods("DELETE") return mux }
Go
복사

/main.go

package main import ( "net/http" "github.com/GloryKim/goWeb/web8/myapp" ) func main() { http.ListenAndServe(":3000", myapp.NewHandler()) }
Go
복사

추가

업데이트 하는 방법에는 크게 두가지가 있다.
Update or Create
Upadte or Error