Create A Simple RESTful API With GoLang
用GO语言构建一个简单的RESTful API作者:Nic Raboy 2016.7.11 GO语言 `
` 正文现在大多数应用程序在前后台已经分开了。 后台是一典型的RESTful API,也是全栈开发的关键部分。这些API会通常被分成多个路由集合, 它通常也指后台。 构建一个像这样API的应用,通常比把所有的杂揉到单一的应用中,则更为简洁和可维护。 我用各种编程语言实现了RESTful API, 例如Node.js、java,但是近来我研究了很多GO语言编程。 由于它是一个快速、可靠、简洁编程语言, 我们接下来看下用GO语言构建一个基本的CRUD操作究竟用到了什么。 为了简明, 我们不准备用真实的数据库, 我们会硬编码来作为模拟数据。这让我们重点关注核心的地方,像定义后台、基本的操作。 假设GO语言已经安装和配置在你的机器上了。 从(MAX and Linux)终端,或是windows命令提示行中执行如下:
如果你命令行中不支持以上的任何一种, 只能自己找到方法手工创建目录
在这个Go文件中, 我们将增加如下代码。 用许多代码,不用担心, 接下来我们会把它拆开。
package main
imprt (
"encoding/json"
"log"
"net/http"
"github.com/gorilla/mux"
)
type Person struct {
ID string `json:"id,omitempty"`
Firstname string `json:"firstname,omitempty"`
Lastname string `json:"lastname,omitempty"`
Address *Address `json:"address,omitempty"`
}
type Address struct {
City string `json:"city,omitempty"`
State string `json:"state,omitempty"`
}
var people []Person
func GetPersonEndpoint(w http.ResponseWriter,req *http.Request) {
params := mux.Vars(req)
for _,item := range people {
if item.ID == params["id"] {
json.NewEncoder(w).Encode(item)
return
}
}
json.NewEncoder(w).Encode(&Person{})
}
func GetPeopleEndpoint(w http.ResponseWriter,req *http.Request) {
json.NewEncoder(w).Encode(people)
}
func CreatePersonEndpoint(w http.ResponseWriter,req *http.Request) {
params := mux.Vars(req)
var person Person
_ = json.NewDecoder(req.Body).Decode(&person)
person.ID = params["id"]
people = append(people,person)
json.NewEncoder(w).Encode(people)
}
func DeletePersonEndpoint(w http.ResponseWriter,req *http.Request) {
params := mux.Vars(req)
for index,item := range people {
if item.ID == params["id"] {
people = append(people[:index],people[index+1:]...)
break
}
}
json.NewEncoder(w).Encode(people)
}
func main() {
router := mux.NewRouter()
people = append(people,Person{ID: "1",Firstname: "Nic",Lastname: "Raboy",Address: &Address{City: "Dublin",State: "CA"}})
people = append(people,Person{ID: "2",Firstname: "Maria",Lastname: "Raboy"})
router.HandleFunc("/people",GetPeopleEndpoint).Methods("GET")
router.HandleFunc("/people/{id}",GetPersonEndpoint).Methods("GET")
router.HandleFunc("/people/{id}",CreatePersonEndpoint).Methods("POST")
router.HandleFunc("/people/{id}",DeletePersonEndpoint).Methods("DELETE")
log.Fatal(http.ListenAndServe(":12345",router))
}
上面的代码究竟是什么鬼? 首先注意到我们导入了各种依赖包。 我们用JSON的数据格式工作, 因此要求有JSON编码包。 我们用HTTP来请求, 但net/http包是不一定要求。 mux包是个好帮手,更容易创建后台, 而且有更多的特性可用。 因为这是一个扩展包, 像下面这样下载:
关于mux更多的信息可以参考官方文档。 随着依赖包导入, 就可以创建结构对象,装载我们的数据,我们计划存储的数据是“人”的数据:
type Person struct {
ID string `json:"id,omitempty"`
}
我们注意到, 在结构体中的属性, 同时我们也定义了一个标签,这标签说明数据怎样以JSON的形式存储。在每个标签里,有一个omitempty参数。 这意味着如果这个属性为空, 将会从JSON中排除,而不是显示一个空的字符串或值。 在Person结构体中, 有一个adress的指针。 这说明有一个嵌套的JSON对象, 它必需是一个指针,否则 omitempty会失败。 那么Adress长成什么样呢?
type Address struct {
City string `json:"city,omitempty"`
}
这里又是一个嵌套结构,但不同于前面说的。 因为不用数据库, 我们在工程中创建了一个全局变量。在应用中,这个变量是一个Person的切片,包含了所有用到的数据。 最简单的后台应用可能是GetPeopleEndpoint, 因为它会把完整的person值返回给前台。 我们将从 插入、删除和获取指定的记录开始。
func GetPersonEndpoint(w http.ResponseWriter,item := range people {
if item.ID == params["id"] {
json.NewEncoder(w).Encode(item)
return
}
}
json.NewEncoder(w).Encode(&Person{})
}
在上面的GetPersonEndpoint中,得到一个整条记录。mux库可以从传入请求的数据中取得任何参数, 然后循环全局切片,匹配请求中指定的ID。 如果匹配到, 则解码JSON后显示出来,否则返回一个空的JSON对象。 现实中,后台会和数据库交互, 也可能包含一些应用逻辑。 这或许就是你反而要用一些查询的原因。
func CreatePersonEndpoint(w http.ResponseWriter,person)
json.NewEncoder(w).Encode(people)
}
在上面中, 根据传入的JSON,解码后存在Person的对象中。 我们会依据mux找的Id分配一个新的对象,然后添加到全局的切片中。 最后, 返回全局数组包,它包含刚才新创建的内容。
func DeletePersonEndpoint(w http.ResponseWriter,people[index+1:]...)
break
}
}
json.NewEncoder(w).Encode(people)
}
在这种情况下,DeletePersonEndpoint 遍历所有的数据和之前看到的GetPersonEndpoint 有点相似。不同的是我们需要删除它,而不是打印它。当找到的Id被删除后, 我们会重新创建切片,不包含刚才的删除的数据。
func main() {
router := mux.NewRouter()
people = append(people,router))
}
上面代码中, 首先创建一个新路由和增加两个对象到切片中。 接下来创建后台,它可以调用后台的函数。 注意我们用了GET, POST和适当的DELETE 最后定义了服务端口12345, 这就接近尾声了。 想要运行并试下效果,需要一个工具,如 结论以上你看到了怎样用go语言构建一个简单的RESTful API 。 然后用了模拟数据代替数据库, 还看到怎样用GO语言切片和JSOn创建各种后台应用。 在这个例子中,像web、手机、全互联loT通过创建API,你的应用程序易维护简、可扩展,只需要不同的前台而不需要再创建新后台了。 以下是自己的测试: 测试1. 用firefox下的一个插件poster2. poster工具3. GET 所有4. GET 其中一个Id5. ADD6. 删除生词
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |