基于Go语言快速构建RESTful API服务

2019-10-22 作者:金沙澳门官网网址   |   浏览(150)

基于Go语言快速构建RESTful API服务。In this post, we will not only cover how to use Go to create a RESTful JSON API, but we will also talk about good RESTful design.

What is a JSON API?

JSON API 是数量交互规范,用以定义顾客端怎样得到与改进能源,以至服务器如何响应对应必要。JSON API设计用来最小化诉求的数目,以致客商端与劳务器间传输的数据量。通过固守共同的约定,能够加强支付成效,利用越来越宽泛的工具,基于 JSON API 的客户端还是能够够充裕利用缓存,以提高品质。

示例:

{
  "links": {
    "posts.author": {
      "href": "http://example.com/people/{posts.author}",
      "type": "people"
    },
    "posts.comments": {
      "href": "http://example.com/comments/{posts.comments}",
      "type": "comments"
    }
  },
  "posts": [{
    "id": "1",
    "title": "Rails is Omakase",
    "links": {
      "author": "9",
      "comments": [ "5", "12", "17", "20" ]
    }
  }]
}

起步一个RESTful服务

$ go run main.go

$ curl http://localhost:8080
Hello,"/"

package main

import (
    "fmt"
    "html"
    "log"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
    })

    log.Fatal(http.ListenAndServe(":8080", nil))

}

参照他事他说加以考察文献

  1. 阮生机勃勃峰:RESTful API 设计指南
  2. CORY LANOU:Making a RESTful JSON API in Go,2014Nov
  3. 基于Go语言快速构建RESTful API服务。InfoQ:使用ETags减弱Web应用带宽和负载
  4. 基于Go语言快速构建RESTful API服务。Stackoverflow:jwt vs oauth authentication
  5. OAuth 2 VS JSON Web Tokens:How to secure an API,20160605
  6. 阮一峰:理解OAuth 2.0,201405

拉长成效:日志

2017/05/23 15:57:23 http: multiple response.WriteHeader calls
2017/05/23 15:57:23 GET /todos  TodoIndex   6.945807ms
2017/05/23 16:18:40 http: multiple response.WriteHeader calls
2017/05/23 16:18:40 GET /todos  TodoIndex   2.127435ms

基于Go语言快速构建RESTful API服务。抓实际效果用:持久化

func TodoCreate(w http.ResponseWriter, r *http.Request) {
    var todo Todo
    //add Todo instance
}

重构:Handlers & Router

Handlers.go

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)
}

Router.go

package main

import (
    "net/http"
    "github.com/gorilla/mux"
)

func NewRouter() *mux.Router {
    router := mux.NewRouter().StrictSlash(true)
    for _, route := range routes {
        var handler http.Handler
        handler = route.HandlerFunc
        handler = Logger(handler, route.Name)

        router.
            Methods(route.Method).
            Path(route.Pattern).
            Name(route.Name).
            Handler(handler)

    }
    return router
}

Things We Didn’t Do

1、版本调节
API版本迭代 & 跨版本财富访问。常用做法是将版本号放在UEnclaveL,较为轻巧,比方:https://localhost:8080/v1/
另风流洒脱种做法是将版本号放在HTTP头新闻中。

2、授权验证:涉及到OAuth和JWT。
(1)OAuth 2.0,OAuth2 is an authentication framework,RFC 6749
OAuth2是意气风发种授权框架,提供了日新月异套详细的、可供执行的教导性建设方案。OAuth 2.0概念了多样授权方式。授权码情势(authorization code)、简化情势(implicit)、密码格局(resource owner password credentials)、客商端情势(client credentials)。

(2)JSON web tokens,JWT is an authentication protocol,RFC 7519
JWT是大器晚成种安全磋商。基本思路正是顾客提供客户名和密码给认证服务器,服务器验证顾客提交新闻音信的合法性;假诺证实成功,会产生并赶回多少个Token(令牌),客商能够应用那么些token访谈服务器上受保证的财富。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

header:定义算法(alg:ALGOTiguanITHM)和TOKEN TYPE(typ)

{
  "alg": "HS256",
  "typ": "JWT"
}

Data:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

3、 eTags:关于缓存、质量和顾客标志和追踪。

日增路线分发作用

路子又称"终点"(endpoint),表示API的具体网站。在RESTful架构中,各个网站代表意气风发种能源(resource)。
其三方组件(Gorilla Mux package): “github.com/gorilla/mux”

package main

import (
    "fmt"
    "log"
    "net/http"
    "github.com/gorilla/mux"
)

func main() {
    router := mux.NewRouter().StrictSlash(true)
    router.HandleFunc("/", Index)
    router.HandleFunc("/todos", TodoIndex)
    router.HandleFunc("/todos/{todoId}", TodoShow)

    log.Fatal(http.ListenAndServe(":8080", router))
}

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

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

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

做客测验:

$ curl http://localhost:8080/todo
404 page not found
$ curl http://localhost:8080/todos
Todo Index! ,"/todos"
$ curl http://localhost:8080/todos/{123}
TodoShow: ,"123"

开发银行入口是否舒畅超多!

Main.go

Main.go
package main

import (
    "log"
    "net/http"
)

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

web access:http://localhost:8080/todos

Todo Index! ,"/todos"
[
{
"id":0,
"name":"Write sth ....",
"completed":false,
"due":"0001-01-01T00:00:00
},
{
"id":1,
"name":"Host meetup ....",
"completed":false,
"due":"0001-01-01T00:00:00Z"
}
]

空洞数据模型

开创叁个数据模型“Todo”、“Routes”。在另外语言中,使用类(class)达成。
在Go语言中,未有class,必需采纳结构(struct)。

Todo.go

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

Routes.go

package main

import (
    "net/http"
    "github.com/gorilla/mux"
)

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

type Routes []Route

本文由金沙澳门官网网址发布于金沙澳门官网网址,转载请注明出处:基于Go语言快速构建RESTful API服务

关键词: