Go语言Tips

时间日期格式化

time.Now().Format("2006-01-02")

原生DefaultServeMux支持restful路由

ref: https://towardsdev.com/how-to-create-rest-api-in-golang-6448d1de294c

package main

import (
    "encoding/json"
    "net/http"
    "regexp"
    "sync"
)

var (
    listUserRe   = regexp.MustCompile(`^\/users[\/]*$`)
    getUserRe    = regexp.MustCompile(`^\/users\/(\d+)$`)
    createUserRe = regexp.MustCompile(`^\/users[\/]*$`)
)

type user struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

type datastore struct {
    m map[string]user
    *sync.RWMutex
}

type userHandler struct {
    store *datastore
}

func (h *userHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("content-type", "application/json")
    switch {
    case r.Method == http.MethodGet && listUserRe.MatchString(r.URL.Path):
        h.List(w, r)
        return
    case r.Method == http.MethodGet && getUserRe.MatchString(r.URL.Path):
        h.Get(w, r)
        return
    case r.Method == http.MethodPost && createUserRe.MatchString(r.URL.Path):
        h.Create(w, r)
        return
    default:
        notFound(w, r)
        return
    }
}

func (h *userHandler) List(w http.ResponseWriter, r *http.Request) {
    h.store.RLock()
    users := make([]user, 0, len(h.store.m))
    for _, v := range h.store.m {
        users = append(users, v)
    }
    h.store.RUnlock()
    jsonBytes, err := json.Marshal(users)
    if err != nil {
        internalServerError(w, r)
        return
    }
    w.WriteHeader(http.StatusOK)
    w.Write(jsonBytes)
}

func (h *userHandler) Get(w http.ResponseWriter, r *http.Request) {
    matches := getUserRe.FindStringSubmatch(r.URL.Path)
    if len(matches) < 2 {
        notFound(w, r)
        return
    }
    h.store.RLock()
    u, ok := h.store.m[matches[1]]
    h.store.RUnlock()
    if !ok {
        w.WriteHeader(http.StatusNotFound)
        w.Write([]byte("user not found"))
        return
    }
    jsonBytes, err := json.Marshal(u)
    if err != nil {
        internalServerError(w, r)
        return
    }
    w.WriteHeader(http.StatusOK)
    w.Write(jsonBytes)
}

func (h *userHandler) Create(w http.ResponseWriter, r *http.Request) {
    var u user
    if err := json.NewDecoder(r.Body).Decode(&u); err != nil {
        internalServerError(w, r)
        return
    }
    h.store.Lock()
    h.store.m[u.ID] = u
    h.store.Unlock()
    jsonBytes, err := json.Marshal(u)
    if err != nil {
        internalServerError(w, r)
        return
    }
    w.WriteHeader(http.StatusOK)
    w.Write(jsonBytes)
}

func internalServerError(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusInternalServerError)
    w.Write([]byte("internal server error"))
}

func notFound(w http.ResponseWriter, r *http.Request) {
    w.WriteHeader(http.StatusNotFound)
    w.Write([]byte("not found"))
}

func main() {
    mux := http.NewServeMux()
    userH := &userHandler{
        store: &datastore{
            m: map[string]user{
                "1": user{ID: "1", Name: "bob"},
            },
            RWMutex: &sync.RWMutex{},
        },
    }
    mux.Handle("/users", userH)
    mux.Handle("/users/", userH)

    http.ListenAndServe("localhost:8080", mux)
}
posted @ 2020-01-16 23:40  让速不让路  阅读(95)  评论(0编辑  收藏  举报