详解Go语言RESTful JSON API创建

2020-01-28 13:00:06丽君


type Todo struct {
  Name   string  `json:"name"`
  Completed bool   `json:"completed"`
  Due    time.Time `json:"due"`
}

其实很简单,就是在结构体中添加标签属性, 这样可以完全控制结构体如何编排(marshalled)成JSON。

拆分代码

到目前为止,我们所有代码都在一个文件中。显得杂乱, 是时候拆分代码了。我们可以将代码按照功能拆分成下面多个文件。

我们准备创建下面的文件,然后将相应代码移到具体的代码文件中:

    main.go: 程序入口文件。 handlers.go: 路由相关的处理器。 routes.go: 路由。 todo.go: todo相关的代码。

package main

import (
  "encoding/json"
  "fmt"
  "net/http"

  "github.com/gorilla/mux"
)

func Index(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintln(w, "Welcome!")
}

func TodoIndex(w http.ResponseWriter, r *http.Request) {
  todos := Todos{
    Todo{Name: "Write presentation"},
    Todo{Name: "Host meetup"},
  }

  if err := json.NewEncoder(w).Encode(todos); err != nil {
    panic(err)
  }
}

func TodoShow(w http.ResponseWriter, r *http.Request) {
  vars := mux.Vars(r)
  todoId := vars["todoId"]
  fmt.Fprintln(w, "Todo show:", todoId)
}

package main

import (
  "net/http"

  "github.com/gorilla/mux"
)

type Route struct {
  Name    string
  Method   string
  Pattern   string
  HandlerFunc http.HandlerFunc
}

type Routes []Route

func NewRouter() *mux.Router {

  router := mux.NewRouter().StrictSlash(true)
  for _, route := range routes {
    router.
      Methods(route.Method).
      Path(route.Pattern).
      Name(route.Name).
      Handler(route.HandlerFunc)
  }

  return router
}

var routes = Routes{
  Route{
    "Index",
    "GET",
    "/",
    Index,
  },
  Route{
    "TodoIndex",
    "GET",
    "/todos",
    TodoIndex,
  },
  Route{
    "TodoShow",
    "GET",
    "/todos/{todoId}",
    TodoShow,
  },
}


package main

import "time"

type Todo struct {
  Name   string  `json:"name"`
  Completed bool   `json:"completed"`
  Due    time.Time `json:"due"`
}

type Todos []Todo

package main
import (
  "log"
  "net/http"
)

func main() {
  router := NewRouter()
  log.Fatal(http.ListenAndServe(":8080", router))
}

更好的Routing

我们重构的过程中,我们创建了一个更多功能的routes文件。 这个新文件利用了一个包含多个关于路由信息的结构体。 注意,这里我们可以指定请求的类型,例如GET, POST, DELETE等等。

输出Web日志

在拆分的路由文件中,我也包含有一个不可告人的动机。稍后你就会看到,拆分之后很容易使用另外的函数来修饰http处理器。

首先我们需要有对web请求打日志的能力,就像很多流行web服务器那样的。 在Go语言中,标准库里边没有web日志包或功能, 因此我们需要自己创建。