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