在最近加入Central Tech之后,我得到了我的第一个项目:在Go中实现新产品创建和查询API。 我借此机会最终进入了Go语言,这是我在听到许多其他人的赞誉之后一直想要做的事情。 我还决定开始详细介绍我在此过程中学到的东西,以供个人参考并确保我理解足够的概念以书面形式对其进行解释。
因此,本文和我的网站有望成为我可以参考的资源,并希望对其他人有所帮助。
基本
本文假定您已安装并在计算机上工作。 如果没有,请参阅Go语言的官方入门指南 。
在编写要执行的实际功能之前,我们首先需要定义程序并导入必要的包。 创建一个名为main.go
的新文件,并添加以下行。
package main
import (
"log"
"net/http"
)
让我们看一下上面代码的每个组件。
配套
软件包是Go的源代码,被组织到系统目录中。 它们允许跨不同应用程序的代码可重用性。 为了区分可执行程序与要供其他程序使用的库,Go指示我们在所有可执行文件的主文件的标头中都包含package main
。 编译时,该package main
告诉Go编译器该包应作为可执行程序而不是作为库进行编译。
进口货
关键字import
用于将包导入到我们的程序或另一个包中。 导入软件包时,Go编译器将查找两个环境变量指定的位置:
-
$GOROOT
,其中存储了Go随附的标准库中的软件包 -
$GOPATH
用于获取第三方或自制软件包。
注意:“按设计进行”不允许声明未使用的导入,并且如果发现任何错误,将在编译期间坚持提出申诉
在我们的例子中,这两个软件包都来自标准库:
-
log
允许我们记录错误和其他问题。 -
net/http
为我们提供了用于构建实际API的HTTP客户端和服务器实现
声明软件包后,我们可以开始定义和提供我们的API。 在不使用第三方库和路由器的情况下,这有两个主要的“方法”。
如果将处理程序实现为函数, http.HandleFunc
使用http.HandleFunc
。 否则,如果我们使用ServeHTTP
方法将处理程序实现为类型, ServeHTTP
使用http.Handle
。
对于简单的实现,第一个选项更容易阅读和理解。 但是使用struct类型可以在其中存储有用的信息,例如标准库中的文件服务器 。 该结构包含文件服务的根目录。 有关更多详细说明,请参见此Stack Overflow帖子 。
由于我们的程序非常简单明了,因此我们将坚持第一种方法。
注意:HTTP处理程序是为响应对Web应用程序的请求而运行的进程。 有关更多信息,请参见其Wikipedia页面。
建立一个Web服务器
现在,我们来定义API服务器的实际行为,以及将作为响应发送的内容。 在我们的导入和包声明下面添加以下行:
func apiResponse (w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Header().Set( "Content-Type" , "application/json" )
w.Write([] byte ( `{"message":"hello world!"}` ))
}
func main () {
http.HandleFunc( "/" ,apiResponse)
log.Fatal(http.ListenAndServe( ":8080" , nil ))
}
同样,让我们遍历每个函数。
apiResponse
函数apiResponse负责编写响应代码和JSON。 该函数本身w
两个参数:类型为http.ResponseWriter
w
组装HTTP服务器的响应,而r
读取并解析请求。 现在来看一下函数的每一行:
w.WriteHeader(http.StatusOK)
写入HTTP 响应代码 200,指示已成功获取请求的资源(在本例中为JSON响应)并在消息正文中进行了传输。
w.Header().Set("Content-Type", "application/json")
指示所请求资源的返回类型。
w.Write([]byte('{"message":"hello world!"}'))
最终将我们的响应写入消息正文中。
主要
main()
函数在Go中有一个特殊用途:它充当可执行程序的入口。 它不带任何参数也不返回任何东西。 与其他语言不同,我们不需要显式调用main
,因为Go在运行时会自动调用该函数。
在我们的主要功能中, HandleFunc
调用通过HandleFunc
函数告诉HTTP包处理对Web根目录(“ /”)的所有请求。 然后,它调用http.ListenAndServe
,指定它应在任何接口上的端口8080
上侦听。
如果现在运行命令, go run .
并在我们的Web浏览器上导航到localhost:8080
,我们应该看到类似这样的内容。
我们还可以使用“ GET”方法将相同的URL输入到我们的REST客户端(即Postman , Insomnia , Paw )中,以获得相同的结果。
![](https://i-blog.csdnimg.cn/blog_migrate/1164929ecbdf12b6683499019c25f18b.png)
使它变得RESTful
现在我们的服务器可以返回响应,我们可以根据请求的方法将其配置为执行不同的操作。
为此,我们可以这样修改apiResponse
函数:
func apiResponse (w http.ResponseWriter, r *http.Request) {
// Set the return Content-Type as JSON like before
w.Header().Set( "Content-Type" , "application/json" )
// Change the response depending on the method being requested
switch r.Method {
case "GET" :
w.WriteHeader(http.StatusOK)
w.Write([] byte ( `{"message": "GET method requested"}` ))
case "POST" :
w.WriteHeader(http.StatusCreated)
w.Write([] byte ( `{"message": "POST method requested"}` ))
default :
w.WriteHeader(http.StatusNotFound)
w.Write([] byte ( `{"message": "Can't find method requested"}` ))
}
}
现在,如果我们使用ctrl-c
关闭服务器的先前版本并再次启动它,我们将根据REST客户端请求的方法获得不同的响应。
我们最终的main.go
应该类似于:
package main
import (
"log"
"net/http"
)
func apiResponse (w http.ResponseWriter, r *http.Request) {
// Set the return Content-Type as JSON like before
w.Header().Set( "Content-Type" , "application/json" )
// Change the response depending on the method being requested
switch r.Method {
case "GET" :
w.WriteHeader(http.StatusOK)
w.Write([] byte ( `{"message": "GET method requested"}` ))
case "POST" :
w.WriteHeader(http.StatusCreated)
w.Write([] byte ( `{"message": "POST method requested"}` ))
default :
w.WriteHeader(http.StatusNotFound)a
w.Write([] byte ( `{"message": "Can't find method requested"}` ))
}
}
func main () {
http.HandleFunc( "/" ,apiResponse)
log.Fatal(http.ListenAndServe( ":8080" , nil ))
}
闭幕
这涵盖了使用Go构建REST API服务器的基础。 在以后的文章中,我计划更详细地研究net/http
库,并计划使用第三方路由器库(例如gorillia / mux和go-chi / chi)进行更复杂的路由。
如果您有任何疑问,请随时通过Twitter或通过电子邮件与我联系。
From: https://hackernoon.com/building-a-simple-rest-api-with-go-9x4n36ph