基于Go语言快速构建RESTful API服务
2017-05-26 04:33
459 查看
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.
部分内容删减调整,原文请查看: Making a RESTful JSON API in Go,2014Nov
Author:CORY LANOU:a full stack technologist who has specialized in start-ups for the last 17 years. I'm currently working at InfluxDB on their core data team. I also help lead and organizer several community technology meetups and do Go training.
示例:
访问测试:
Todo.go
Routes.go
Router.go
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" } ]
授权验证:涉及到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访问服务器上受保护的资源。
header:定义算法(alg:ALGORITHM)和TOKEN TYPE(typ)
Data:
eTags:关于缓存、性能和用户标识和追踪。
https://my.oschina.net/zijingshanke/blog/907955
部分内容删减调整,原文请查看: Making a RESTful JSON API in Go,2014Nov
Author:CORY LANOU:a full stack technologist who has specialized in start-ups for the last 17 years. I'm currently working at InfluxDB on their core data team. I also help lead and organizer several community technology meetups and do Go training.
What is a JSON API?
JSON API 是数据交互规范,用以定义客户端如何获取与修改资源,以及服务器如何响应对应请求。JSON API设计用来最小化请求的数量,以及客户端与服务器间传输的数据量。通过遵循共同的约定,可以提高开发效率,利用更普遍的工具,基于 JSON API 的客户端还能够充分利用缓存,以提升性能。(更多:http://jsonapi.org.cn/format/)。示例:
{ "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)) }
增加路径分发功能
路径又称"终点"(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"
抽象数据模型
创建一个数据模型“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
重构:Handlers & Router
Handlers.gopackage 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 }
启动入口是不是清爽很多!
Main.goMain.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" } ]
增强功能:持久化
func TodoCreate(w http.ResponseWriter, r *http.Request) { var todo Todo //add Todo instance }
增强功能:日志
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
Things We Didn’t Do
版本控制 API版本迭代 & 跨版本资源访问。常用做法是将版本号放在URL,较为简洁,例如:https://localhost:8080/v1/ 另一种做法是将版本号放在HTTP头信息中。授权验证:涉及到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:ALGORITHM)和TOKEN TYPE(typ)
{ "alg": "HS256", "typ": "JWT" }
Data:
{ "sub": "1234567890", "name": "John Doe", "admin": true }
eTags:关于缓存、性能和用户标识和追踪。
https://my.oschina.net/zijingshanke/blog/907955
相关文章推荐
- go语言快速入门:项目构建实践(21)
- NetBeans Visual Web Pack 5.5以可视方式快速构建基于标准的 Web 应用程序。
- 基于SQL Server 2008 Service Broker构建企业级消息系统|企业级管理软件快速开发平台
- go语言快速读取配置文件并声明环境变量
- 基于 Web 的 Go 语言 IDE - Wide 1.1.0 发布!
- 基于Salt Master/Minions快速构建Salt SSH环境
- 介绍几个基于动态语言的快速Web开发框架
- 基于Bluemix快速构建部署一款Java小程序——微博影响力分析器
- 如何快速构建基于Spring4.0的Rest API
- 如何快速构建基于Spring4.0的Rest API(攻略)
- 基于 Web 的 Go 语言 IDE - Wide 1.1.0 发布!
- Direct3D轮回:快速构建基于win32工程的Direct3D游戏框架
- YinCart 基于Yii框架开源商城!可快速构建自己的网店!
- 使用 Go 语言和 HTML5 WebSocket 构建一个 Web 聊天室
- 快速构建基于代码级性能测试方法的一种思路和简单实现
- 用Python脚本语言建立一个基于应用程序的GUI快速启动
- 基于Eclipse的Google Go语言开发工具Goclipse
- 使用Yeoman快速构建基于angular的web应用
- 在ubuntu下构建go语言开发环境的方法
- 基于 Web 的 Go 语言 IDE - Wide 1.1.0 发布!