Go 是面向现代云服务架构的语言,服务之间通讯在HTTP应用层仅友好支持 RESTful 的服务 。因此,掌握 HTTP Resource API 的设计方法与工具、golang 客户端与服务器编程要点是必须 get 的技能。 本文介绍 API Blueprint 的使用,以及 golang 相关编程,以 API 为核心,支持测试驱动的编程(TDD)
需要支持 soap 服务或 oracle DB2 等数据库,请使用 java 等。
容器使得进程(应用)一次构建到处运行。人们开始思考一个系统一个进程这种开发、运营模式在云时代的合理性。在已有 SOA(Service-oriented architecture) 架构的基础上,提出了“微服务架构”的概念。
Martin Fowler 在2014年用博客明确了微服务的概念,Microservices - a definition of this new architectural term 【中文翻译】
简单来说,微服务架构风格[1]是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。
HTTP Resource API
用现在的技术表达,即是一个应用由若干(容器)服务,通过进程间通讯(IPC)组成一个应用。
1、分布式计算与 IPC 进化历史
基于 SOAP / XML-RPC 构建的 Web Service 协议家族:
2、RESTful 协议
2000 年 Roy Thomas Fielding 的博士提出面向分布式多媒体软件的 REST (Representational State Transfer) 风格架构,RESTful 服务迅速成为互联网服务的事实标准。
SOAP RPC pk. REST RPC
HTTP message with SOAP for searching on google
GET search/beta2 HTTP/1.1
Host:api.google.com
Content-Type:application/soap+xml
SOAPAction: urn:GoogleSearchAction
<soap:Envelope xmlns:soap="http://schemas.xmllsoap.org/soap/envelope/">
<soup:Body>
<gs:doGoogleSearch xmlns:gs="urn:GoogleSearch">
<q>RESTq>
…
gs:doGoogleSearch>
soup:Body>
soap:Envelope>
HTTP message with REST for searching on google
GET services/rest?api_key=xxx&q=REST HTTP/1.1
Host:api.google.com
程序员的选择?
2.3、HTTP Resource API
HTTP Resource = URL?
HTTP Resource API,使用 GET、POST、PUT、DELETE 等现有 HTTP 指令存取远端资源的 API, 原则上使用 JSON 传输对象
阅读: Gregor Roth REST, 面向资源架构(2009)
原文: RESTful HTTP in practice
要点:
跟多关于 RESTful 知识, RESTful Web Services Tutorial
API 案例: http://lbs.amap.com/api/webservice/guide/api/georegeo
这样的设计好不好? - 请不要妄议,历史因素是每个企业必须面对的问题。
如何表达这样的设计,并知道软件生产与测试是本节要求掌握的知识。
建模元素:
简单的应用我们可以参考前面的文章设计
更简单,可参考 [RESTful API 设计指南]
(http://www.ruanyifeng.com/blog/2014/05/restful_api.html)
[GET] v1/users - 获取所有用户
[POST] v1/users - 新建用户
[GET] v1/users/{id} - 查询用户明细信息
[PATCH] v1/users/{id} - 修改用户明细信息
[DELETE] v1/users/{id} - 删除用户
[GET] v1/users/{id}/owned-meetings - 获取用户创建的会议
[GET] v1/users/{id}/joined-meetings - 获取用户参与的会议
[GET] v1/meeting
...
单数与复数
上述 API 仅考虑了资源的 CRUD,并没有考虑资源的业务处理。 思考一个,如果我们要验证一个用户或者激活一个用户,它的 Api 应该是什么模样呢?
[GET] v1/user/login{?name,password}
[GET] v1/user/active{?activecode}
[GET] v1/users/login{?name,password}
如果选用复数,则 login
与 用户的 id
将难以区分。使用 单数名词/业务动作{?参数列表}
的设计模式,更加易于理解和处理。
API design First 是微服务架构首先遵循的理念!
上述设计文档不能随着系统同步进化,因此,我们需要一体化工具支持 API 的设计、验证、代码生成(客户端、服务器端)、文档自动化、以及测试自动化。
1、Api Blueprint?
什么是 API Blueprint?
一句话:用 markdown 写 API
*扩展阅读:API 设计: RAML、Swagger、Blueprint三者的比较
竞争产品: apizza
基于云原生应用开发的创新
云服务技术作为新生事物,出现了无数创新型企业,这些企业的丰富并完善了云应用开发的生态环境。中国企业依托国内软件生产的需求,在模仿中获得了成长。以下列表只是一些罗列,对应的国内应用请自己收集:
2、Api Blueprint 快速入门
push
到仓库FORMAT: 1A
HOST: http://agenda12.apiblueprint.org/
# Agenda
Agenda is a simple API allowing consumers to schedule meeting on-line
# Group User
Resource operations related to a user in the API.
## User-Key [/v1/user/getkey{?username,password}]
+ Parameters
- username : `root` (string, required) - User Name
- password : `pass` (required)
### Get User Key [GET]
get a security key for operations later
+ Response 200 (application/json)
{
"key":"1e3576bt"
"permissions":["user","admin"]
}
# Group Users
Resources related to a users in the API.
## Users Collection [/v1/users{?key}]
+ Parameters
- key : `1e3576bt` (string, required)
### List all Users [GET]
+ Response 200 (application/json)
[
{
"id":1
"username":"zhang3"
"password":"zhang"
"email":"[email protected]"
},{
"id":2
"username":"li4"
"password":"li"
"email":"[email protected]"
}
]
### Create a New User [POST]
+ Request (application/json)
{
"username":"zhang3"
"password":"zhang"
"email":"[email protected]"
}
+ Response 201 (application/json)
+ Headers
Location: /users/1
+ Body
{
"id": 1
"username":"zhang3"
"password":"zhang"
"email":"[email protected]"
}
### Get User by ID [GET /v1/users/{id}]
+ Parameters
- id : `1` (int, required) - User Name
+ Response 200 (application/json)
{
"id" : 1
"username":"zhang3"
"password":"zhang"
"email":"[email protected]"
}
# Group Meetings
本文档 URL: https://agenda12.docs.apiary.io/#
https://private-c2bed8-agenda12.apiary-mock.com/v1/user/getkey?username=root&password=pass
你会得到正确的响应。这是一个 令人激动 的功能,我们已经可以通过该 API ,客户端和服务器并行开发开始了!
3、API Blueprint 文档说明书
进入 https://apiblueprint.org/
进入 tutorial
页面:
Language Specification
是完成接口定义,必须自学的!Examples
官方所用案例,你需要模仿它完成你的 API 设计!Go REST 客户端主要涉及三个库 net/http
,io/ioutil
和 encode/json
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
res, err := http.Get("http://private-c2bed8-agenda12.apiary-mock.com/v1/user/getkey?username=root&password=pass")
if err != nil {
panic(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
retJSON := struct {
MyKey string `json:"key"`
Permissions []string
}{"w", []string{"w", "w"}}
w, err := json.Marshal(retJSON)
if err != nil {
panic(err)
}
fmt.Println(string(w), retJSON)
fmt.Println(string(body))
if err := json.Unmarshal(body, &retJSON); err != nil {
panic(err)
}
fmt.Println(retJSON)
}
案例给出用 go http 客户端访问 mock 服务的小程序。
要点
json:"-"
// 禁止转换属性json:"myName"
//属性名称映射json:",omitempty"
//空值处理,逗号!json:"myName,omitempty"
//RESTful 有更多动作、需要特殊的头、或需要处理重定向?
似乎 REST 服务端开发, urfave/negroni
,gorilla/mux
,unrolled.render
的组合几乎能完全满足 REST 的任何开发需求。
你必须考虑 RESTful 服务的用户:
1、友好传统网站
2、使用 nodejs 框架
浏览器跨域请求
对于传统浏览器必须支持 jsonp
callback
参数什么是 jsonp ?
callbackName("json string")
的 Responce.Body 通过 eval(jsonp)
得到对应的对象 3、非浏览器客户端访问