详解Go语言RESTful JSON API创建

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

这里发生了两件事。 首先,我们设置了响应类型并告诉客户端期望接受JSON。第二,我们明确的设置了响应状态码。

Go语言的net/http服务器会尝试为我们猜测输出内容类型(然而并不是每次都准确的), 但是既然我们已经确切的知道响应类型,我们总是应该自己设置它。

稍等片刻,我们的数据库在哪里?

很明显,如果我们要创建RESTful API, 我们需要一些用于存储和检索数据的地方。然而,这个是不是本文的范围之内, 因此我们将简单的创建一个非常简陋的模拟数据库(非线程安全的)。

我们创建一个repo.go文件,内容如下:


package main

import "fmt"

var currentId int

var todos Todos

// Give us some seed data
func init() {
  RepoCreateTodo(Todo{Name: "Write presentation"})
  RepoCreateTodo(Todo{Name: "Host meetup"})
}

func RepoFindTodo(id int) Todo {
  for _, t := range todos {
    if t.Id == id {
      return t
    }
  }
  // return empty Todo if not found
  return Todo{}
}

func RepoCreateTodo(t Todo) Todo {
  currentId += 1
  t.Id = currentId
  todos = append(todos, t)
  return t
}
func RepoDestroyTodo(id int) error {
  for i, t := range todos {
    if t.Id == id {
      todos = append(todos[:i], todos[i+1:]...)
      return nil
    }
  }
  return fmt.Errorf("Could not find Todo with id of %d to delete", id)
}

给Todo添加ID

我们创建了模拟数据库,我们使用并赋予id, 因此我们相应的也需要更新我们的Todo结构体。


package main
import "time"
type Todo struct {
  Id    int    `json:"id"`
  Name   string  `json:"name"`
  Completed bool   `json:"completed"`
  Due    time.Time `json:"due"`
}
type Todos []Todo

更新我们的TodoIndex

要使用数据库,我们需要在TodoIndex中检索数据。修改


func TodoIndex(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json; charset=UTF-8")
  w.WriteHeader(http.StatusOK)
  if err := json.NewEncoder(w).Encode(todos); err != nil {
    panic(err)
  }
}


POST JSON

到目前为止,我们只是输出JSON, 现在是时候进入存储一些JSON了。

在routes.go文件中添加如下路由:


Route{
  "TodoCreate",
  "POST",
  "/todos",
  TodoCreate,
},

Create路由


func TodoCreate(w http.ResponseWriter, r *http.Request) {
  var todo Todo
  body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))
  if err != nil {
    panic(err)
  }
  if err := r.Body.Close(); err != nil {
    panic(err)
  }
  if err := json.Unmarshal(body, &todo); err != nil {
    w.Header().Set("Content-Type", "application/json; charset=UTF-8")
    w.WriteHeader(422) // unprocessable entity
    if err := json.NewEncoder(w).Encode(err); err != nil {
      panic(err)
    }
  }

  t := RepoCreateTodo(todo)
  w.Header().Set("Content-Type", "application/json; charset=UTF-8")
  w.WriteHeader(http.StatusCreated)
  if err := json.NewEncoder(w).Encode(t); err != nil {
    panic(err)
  }
}