您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > Go语言

如何用 Go 快速编写出 HTTP REST API 服务?

时间:2019-12-10 09:38:23  来源:  作者:

在本教程中,明白如何用Go语言写出一个HTTP REST API服务。

如何用 Go 快速编写出 HTTP REST API 服务?

作者 | Aurelie Vache

译者 | 槐序,责编 | 郭芮

出品 | CSDN(ID:CSDNnews)

以下为译文:

学习一门新语言并不容易,但是如果有具体的例子和手把手指导教程,就很容易上手了。因此,我决定编写一系列分步指导教程。

让我们使用Go语言的强大功能来编写一个HTTP REST API 服务。

1.Go, Go, Go

首先要做的就是安装GVM(Go版本管理器),当然还有安装GO。

要安装GO,你可以按照官方网站上的安装步骤进行操作,也可以使用GVM来安装。对于Go而言,GVM是一个非常实用的版本管理工具,它允许你通过指定所需版本来更新Go的版本。

安装

Bash:

bash < <(curl -s-S-L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

zsh:

zsh < <(curl -s-S-L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)

用法

$ gvm
Usage: gvm [command]
Description:
GVM is the Go Version Manager
Commands:
version — print the gvm version number
get — gets the latest code (for debugging)
use — select a go version to use (--default to set permanently)
diff — view changes to Go root
help — display this usage text
implode — completely remove gvm
install — install go versions
uninstall — uninstall go versions
cross — install go cross compilers
linkthis — link this directory into GOPATH
list — list installed go versions
listall — list available versions
alias — manage go version aliases
pkgset — manage go packages sets
pkgenv — edit the environment for a package set

让我们比较感兴趣的GVM 命令是gvm install命令,它的用法如下:

$ gvm install [version] [options]

Go的安装:

$ gvm install go1.13.3 -B
$ gvm use go1.13.3 --default

在你的.zshrc或者.bashrc文件中,设置$GOROOT 和 $GOPATH环境变量,下面是一个例子:(原文下面的2 3 4代码行命令错误,少了空格)

 [[ -s"$HOME/.gvm/scripts/gvm" ]] && source"$HOME/.gvm/scripts/gvm"
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=${PATH}:$GOBIN

以上就是利用版本管理器来安装GO。现在进入本文章的核心,来创建我们第一个CLI(命令行程序)。

2.初始化你的App

现在我们在GitHub中创建一个仓库(为了共享和开源)。

首先,登录GitHub网站,单击仓库链接,创建一个名叫“http-go-server”的仓库:

如何用 Go 快速编写出 HTTP REST API 服务?

然后,在你本地机器上,把这个新建的仓库克隆(git clone)到你想放的地方。

“放任何我想放的地方?你确定?”

我们会用GO模块作为依赖项,所以不要忘记在GOPATH目录外git clone。但事实上,好消息是,从GO 1.13版本开始,我们不需要再担心这个问题了。Go模块现在可以在GOPATH目录下和目录外使用。

这也是我在本文选择使用GO 1.13版本的原因。

现在,为了方便找回及同步本地代码到git仓库,我们要git clone这个仓库:

$git clone https://github.com/scraly/http-go-server.git
$cd http-go-server

然后初始化go模块(依赖管理):

$ go mod init github.com/scraly/http-go-server
go: creating new go.mod: module github.com.scraly/http-go-server

我们将创建一个简单的HTTP服务,但是为了代码组织方面具有良好实践。因此我们不会将所有的代码放到main.go文件,我们会创建一个代码目录然后管理我们的代码。

创建下面的文件目录结构:

.
├── README.md
├── bin
├── doc
├── go.mod
├── internal
├── pkg
│ └── swagger
└── scripts

3.创建一个HTTP服务

现在开始编写HTTP服务代码。

Go是一个很强大的语言。其中一个强大的功能就是有许多可用的内置包,例如net/HTTP。在internal/路径下面创建一个main.go文件,如下所示:

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.Println("Listening on localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}

这个简单的例子创建了一个HTTP服务,并监听端口8080的传入请求,并在返回到根目录/。

现在构建我们的应用来测试它,然后启动应用程序二进制文件:

$ go run internal/main.go
2019/10/27 20:53:39 Listening on localhost:8080 ...

为了测试你的HTTP服务,你可以使用curl命令来测试下 localhost:8080,或者直接用浏览器输入这个URL来测试:

$ curl localhost:8080
Hello, "/"%

很好,我们创建了一个小型的HTTP服务,它可以正常运行。

现在我们可以在二进制可执行文件中构建它:

$ go build -o bin/http-go-server internal/main.go

很好,我们在几分钟内完成了,但是我们将在下文深入了解:-)。

4.使用 Makefile

我不想手动执行每个命令,所以,为了持续改进我们的应用,好的方法就是创建一个Makefile 文件,这样我们就可以直接通过命令行来构建应用,生成文件,生成swagger文档,检查许可证以及执行单元测试和静态测试。

我们可以在Makefile里面定义好一系列将由make工具执行的任务。

因此,在这个项目中,我创建了一个Makefile文件,大家可以直接下载,这样就能节约大家的时间。

Makefile:https://raw.githubusercontent.com/scraly/http-go-server/master/Makefile

出于好奇,在Makefile文件中,我们创建几个指令(targets,可以是目标文件或者执行文件或者标签)用来执行一个或者多个命令。

总结下来就是,一个指令需要或者不需要依赖文件(prerequisites)都将执行方法(recipe):target: prerequisites。

<TAB> recipe

在我创建的Makefile文件中,一个build指令构建和打包我们的应用为二进制文件,存放到目录bin/http-go-server下:

## Build all binaries 
build:
$(GO) build -o bin/http-go-server internal/main.go

5.HTTP Endpoints 定义

现在我们将优化我们的HTTP服务,并使用Swagger,它可以处理我们的HTTP endpoints定义。

什么是Swagger?

Swagger允许你提供符合OpenAPI规范的标准化APIs文档。

因为有了Swagger应用,使用Swagger标准文件输入,你可以在最后生成代码,并且可以为用户提供HTML格式的API文档。

如果你想构建一个公共API,请不要犹豫使用Swagger。

Swagger安装:请参考go-swagger安装页面(https://github.com/go-swagger/go-swagger/blob/master/docs/install.md)。

然后,为了检查该工具在你的系统中正确安装,你可以检查Swagger的版本。

$ swagger version

现在要做的第一件事是在我们的代码中创建swagger标准文档:

pkg/swagger/swagger.yml:

consumes:
- application/json
info:
description: HTTP server in Go with Swagger endpoints definition
title: http-go-server
version: 0.1.0
produces:
- application/json
schemes:
- http
swagger: "2.0"
paths:
/healthz:
get:
operationId: checkHealth
produces:
- text/plain
responses:
'200':
description: OK message
schema:
type: string
enum:
- OK
/hello/{user}:
get:
description: Returns a greeting to the user!
parameters:
- name: user
in: path
type: string
required: true
description: The name of the user to greet.
responses:
200:
description: Returns the greeting.
schema:
type: string
400:
description: Invalid characters in "user" were provided.

每次修改swagger文件后,一个好的做法是检查文件的有效性。

为此,我们可以使用swagger validate命令:

$ swagger validate pkg/swagger/swagger.yml
2019/10/27 21:14:47
The swagger spec at "pkg/swagger/swagger.yml" is valid against swagger specification 2.0

或者可以使用一个Makefile指令:

$ make swagger.validate
2019/10/27 21:15:12
The swagger spec at "pkg/swagger/swagger.yml" is valid against swagger specification 2.0

太棒了,我们的Swagger文件是有效的。

现在我们将在HTML文档中创建Swagger定义。为此,我们可以使用Docker镜像,该镜像考虑到了Swagger YAML定义并且返回一个漂亮的HTML页面。

$ make swagger.doc

如果你在浏览器中打开已经生成的doc/index.html页面,可以查看HTML endpoints定义:

如何用 Go 快速编写出 HTTP REST API 服务?如何用 Go 快速编写出 HTTP REST API 服务?如何用 Go 快速编写出 HTTP REST API 服务?

很好,是具有可读性的。

归功于Swagger规范,现在我们可以生成代码。

为此,我们进入到pkg/swagger/目录,创建一个gen.go文件,如下所示:

package swagger
//go:generate rm -rf server
//go:generate mkdir -p server
//go:generate swagger generate server --quiet --target server --name hello-api --spec swagger.yml --exclude-main

由于有Makefile,我们可以执行生成swagger go代码的文件:

$ make generate
==> generating go code
GOFLAGS=-mod=vendor go generate github.com.scraly/http-go-server/internal github.com.scraly/http-go-server/pkg/swagger
如何用 Go 快速编写出 HTTP REST API 服务?

如下所示,使用一个swagger endpoint定义输入,生成了很多代码,这对于HTTP服务器的实现是节省了时间的。

下面使用Swagger编辑main.go文件:

package main
import (
"log"
"github.com/go-openapi/loads"
"github.com/scraly/http-go-server/pkg/swagger/server/restapi"
"github.com/scraly/http-go-server/pkg/swagger/server/restapi/operations"
)
func main{
// Initialize Swagger
swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
if err != nil {
log.Fatalln(err)
}
api := operations.NewHelloAPI(swaggerSpec)
server := restapi.NewServer(api)
defer server.Shutdown
server.Port = 8080
// Start listening using having the handlers and port
// already set up.
if err := server.Serve; err != nil {
log.Fatalln(err)
}
}

现在启动服务:

$ go run internal/main.go
2019/10/28 14:27:26 Serving hello at http://[::]:8080

现在我们可以做几个测试:

$ curl localhost:8080
{"code":404,"message":"path / was not found"}%
$ curl localhost:8080/hello
{"code":404,"message":"path /hello was not found"}%
$ curl localhost:8080/hello/aurelie
"operation GetHelloUser has not yet been implemented"

完美,我们的HTTP服务正在应答,甚至告知我们GetHelloUser接口尚未实现,接下来实现它吧!

编辑main.go文件如下所示:

package main
import (
"log"
"github.com/go-openapi/loads"
"github.com/go-openapi/runtime/middleware"
"github.com/scraly/http-go-server/pkg/swagger/server/restapi"
"github.com/scraly/http-go-server/pkg/swagger/server/restapi/operations"
)
func main{
// Initialize Swagger
swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
if err != nil {
log.Fatalln(err)
}
api := operations.NewHelloAPI(swaggerSpec)
server := restapi.NewServer(api)
defer func{
if err := server.Shutdown; err != nil {
// error handle
log.Fatalln(err)
}
}
server.Port = 8080
// Implement the CheckHealth handler
api.CheckHealthHandler = operations.CheckHealthHandlerFunc(
func(user operations.CheckHealthParams) middleware.Responder {
return operations.NewCheckHealthOK.WithPayload("OK")
})
// Implement the GetHelloUser handler
api.GetHelloUserHandler = operations.GetHelloUserHandlerFunc(
func(user operations.GetHelloUserParams) middleware.Responder {
return operations.NewGetHelloUserOK.WithPayload("Hello " + user.User + "!")
})
// Start server which listening
if err := server.Serve; err != nil {
log.Fatalln(err)
}
}

再来一次,我们重启服务:

$ go run internal/main.go
2019/10/28 21:45:38 Serving hello at http://[::]:8080
$ curl localhost:8080/hello/aurelie
"Hello aurelie!"
$ curl localhost:8080/healthz
OK%

很好,我们有一个遵守OpenAPI规范的HTTP服务和两个路由:

  • GET/healthz

  • GET/hello/{name}

我们可以到此为止,因为我们的HTTP服务正常工作,但是我们将继续深入。

我们将在main.go文件(在文件末尾)中,为路由实现增加新函数。

//Health route returns OK
func Health(operations.CheckHealthParams) middleware.Responder {
return operations.NewCheckHealthOK.WithPayload("OK")
}
//GetHelloUser returns Hello + your name
func GetHelloUser(user operations.GetHelloUserParams) middleware.Responder {
return operations.NewGetHelloUserOK.WithPayload("Hello " + user.User + "!")
}

现在我们只需在主函数中调用这些新函数:

func main{
// Initialize Swagger
swaggerSpec, err := loads.Analyzed(restapi.SwaggerJSON, "")
if err != nil {
log.Fatalln(err)
}
api := operations.NewHelloAPI(swaggerSpec)
server := restapi.NewServer(api)
defer func{
if err := server.Shutdown; err != nil {
// error handle
log.Fatalln(err)
}
}
server.Port = 8080
api.CheckHealthHandler = operations.CheckHealthHandlerFunc(Health)
api.GetHelloUserHandler = operations.GetHelloUserHandlerFunc(GetHelloUser)
// Start server which listening
if err := server.Serve; err != nil {
log.Fatalln(err)
}
}

和之前一样,我们测试静态测试是否通过,以及我们应用是否构建:

$ make lint.full
==> linters (slow)
INFO [config_reader] Config search paths: [./ /Users/uidn3817/git/github.com/scraly/http-go-server/internal /Users/uidn3817/git/github.com/scraly/http-go-server /Users/uidn3817/git/github.com/scraly /Users/uidn3817/git/github.com /Users/uidn3817/git /Users/uidn3817 /Users /]
INFO [config_reader] Used config file .golangci.yml
INFO [lintersdb] Active 13 linters: [deadcode errcheck goimports golint govet ineffassign maligned misspell nakedret structcheck typecheck unconvert varcheck]
INFO [loader] Go packages loading at mode load types and syntax took 1.474090863s
INFO [loader] SSA repr building timing: packages building 15.964643ms, total 220.705097ms
INFO [runner] worker.4 took 652.824µs with stages: deadcode: 244.82µs, unconvert: 110.42µs, errcheck: 102.565µs, varcheck: 81.099µs, structcheck: 38.623µs, maligned: 34.263µs, nakedret: 22.825µs, typecheck: 5.339µs
INFO [runner] worker.6 took 1.883µs
INFO [runner] worker.8 took 2.125µs
INFO [runner] worker.5 took 1.040528ms with stages: ineffassign: 1.035173ms
INFO [runner] worker.7 took 3.211184ms with stages: goimports: 3.2029ms
INFO [runner] worker.3 took 102.06494ms with stages: misspell: 102.056568ms
INFO [runner] worker.1 took 120.104406ms with stages: golint: 120.096599ms
INFO [runner] worker.2 took 204.48169ms with stages: govet: 204.471908ms
INFO [runner] Workers idle times: #1: 84.514968ms, #3: 86.547645ms, #4: 203.167851ms, #5: 202.957443ms, #6: 203.09743ms, #7: 201.160969ms, #8: 202.973757ms
INFO [runner] processing took 18.697µs with stages: max_same_issues: 14.808µs, skip_dirs: 737ns, cgo: 498ns, nolint: 420ns, filename_unadjuster: 398ns, max_from_linter: 281ns, autogenerated_exclude: 172ns, path_prettifier: 170ns, identifier_marker: 167ns, diff: 164ns, skip_files: 161ns, replacement_builder: 158ns, exclude: 156ns, source_code: 90ns, max_per_file_from_linter: 81ns, path_shortener: 79ns, uniq_by_line: 79ns, exclude-rules: 78ns
INFO File cache stats: 0 entries of total size 0B
INFO Memory: 24 samples, avg is 248.1MB, max is 671.8MB
INFO Execution took 2.277787079s

6.测试静态代码

另外一个好的做法是使用linters 分析来做静态代码测试。为此,我们可以使用golang-ci工具(Go里的快速linter,比gometaliner好)。

还是因为有了Makefile,你只需要获取此处我列出的工具,例如golang-cli:

$ make get.tools

一个好的做法是新建一个.golangci.yml文件来定义我们想要的linter配置。下面是golang-cli配置示例:

run:
modules-download-mode: vendor
deadline: 10m
issues-exit-code: 1
tests: true
skip-files:
- ".*\.pb\.go$"
- ".*\.gen\.go$"
- "mock_.*\.go"
linters:
enable:
- govet # check standard vet rules
- golint # check standard linting rules
- staticcheck# comprehensive checks
- errcheck # find unchecked errors
- ineffassign# find ineffective assignments
- varcheck # find unused global variables and constants
- structcheck# check for unused struct parameters
- deadcode # find code that is not used
- nakedret # check for naked returns
- goimports # fix import order
- misspell # check spelling
- unconvert # remove unnecessary conversions
- maligned # check for better memory usage
disable:
- goconst # check for things that could be replaced by constants
- gocyclo # needs tweaking
- depguard # unused
- gosec # needs tweaking
- dupl # slow
- interfacer # not that useful
- gosimple # part of staticcheck
- unused # part of staticcheck
- megacheck # part of staticcheck
- lll
fast: false
output:
format: colored-line-number
print-issued-lines: true
print-linter-name: true
linters-settings:
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: false
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: false
govet:
# report about shadowed variables
#TODO# check-shadowing: true
# Obtain type information from installed (to $GOPATH/pkg) package files:
# golangci-lint will execute `go install -i` and `go test -i` for analyzed packages
# before analyzing them.
# Enable this option only if all conditions are met:
# 1. you use only "fast" linters (--fast e.g.): no program loading occurs
# 2. you use go >= 1.10
# 3. you do repeated runs (false for CI) or cache $GOPATH/pkg or `go env GOCACHE` dir in CI.
use-installed-packages: false
golint:
min-confidence: 0.8
gofmt:
simplify: true
gocyclo:
min-complexity: 10
maligned:
suggest-new: true
dupl:
threshold: 150
goconst:
min-len: 3
min-occurrences: 3
misspell:
locale: US
lll:
line-length: 140
tab-width: 1
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# call graph construction algorithm (cha, rta). In general, use cha for libraries,
# and rta for programs with main packages. Default is cha.
algo: cha
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30
prealloc:
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# True by default.
simple: true
range-loops: true# Report preallocation suggestions on range loops, true by default
for-loops: false# Report preallocation suggestions on for loops, false by default
issues:
max-per-linter: 0
max-same: 0
new: false
exclude-use-default: false

接下来我们可以检查代码是否包含lint错误:

$ make lint.full
==> linters (slow)
INFO [config_reader] Config search paths: [./ /Users/uidn3817/git/github.com/scraly/http-go-server/internal /Users/uidn3817/git/github.com/scraly/http-go-server /Users/uidn3817/git/github.com/scraly /Users/uidn3817/git/github.com /Users/uidn3817/git /Users/uidn3817 /Users /]
INFO [config_reader] Used config file .golangci.yml
INFO [lintersdb] Active 13 linters: [deadcode errcheck goimports golint govet ineffassign maligned misspell nakedret structcheck typecheck unconvert varcheck]
INFO [loader] Go packages loading at mode load types and syntax took 1.403040989s
INFO [loader] SSA repr building timing: packages building 17.446103ms, total 215.11635ms
INFO [runner] worker.1 took 319.338µs with stages: unconvert: 126.709µs, structcheck: 105.706µs, varcheck: 80.624µs
INFO [runner] worker.8 took 279.76µs with stages: errcheck: 102.203µs, nakedret: 88.6µs, deadcode: 54.547µs, maligned: 22.796µs, typecheck: 2.416µs
INFO [runner] worker.2 took 908ns
INFO [runner] worker.7 took 1.424891ms with stages: ineffassign: 1.419068ms
INFO [runner] worker.4 took 2.395856ms with stages: goimports: 2.39105ms
INFO [runner] worker.6 took 75.843872ms with stages: golint: 75.832987ms
INFO [runner] worker.5 took 77.126536ms with stages: misspell: 77.092913ms
INFO [runner] worker.3 took 124.506172ms with stages: govet: 124.498137ms
INFO [runner] Workers idle times: #1: 124.053298ms, #2: 123.973576ms, #4: 122.078696ms, #5: 47.339761ms, #6: 48.693713ms, #7: 122.946009ms, #8: 124.035904ms
INFO [runner] processing took 19.597µs with stages: max_same_issues: 16.123µs, cgo: 541ns, skip_dirs: 493ns, nolint: 398ns, max_from_linter: 280ns, path_prettifier: 179ns, filename_unadjuster: 172ns, replacement_builder: 170ns, autogenerated_exclude: 170ns, exclude: 164ns, diff: 162ns, skip_files: 161ns, identifier_marker: 150ns, source_code: 97ns, path_shortener: 97ns, max_per_file_from_linter: 82ns, exclude-rules: 80ns, uniq_by_line: 78ns
INFO File cache stats: 0 entries of total size 0B
INFO Memory: 23 samples, avg is 255.8MB, max is 672.0MB
INFO Execution took 2.119246564s

很好,一起都好。

如果你想编辑.golangci.yml文件,请查看golang-ci支持的linters。

7.检查许可证

另外一个好的实践是检查许可证。

你需要去检查许可证(你项目依赖项使用的许可证),例如,当你希望你的应用程序或者公司的代码开源时,为了避免使用被禁的许可证,就要去检查。

在Go中存在一个名为wwhrd的工具。

首先,我们创建一个名为.wwhrd.yml的文件,来定义选项:

---
blacklist:
- AGPL-3.0
- GPL-2.0
- GPL-3.0
- CDDL-1.0
whitelist:
- Apache-2.0
- MIT
- NewBSD
- FreeBSD
- LGPL-2.1
- LGPL-3.0
- ISC
- MPL-2.0
- EPL-1.0
- Unlicense
# exceptions:
# - github.com/davecgh/go-spew/spew/... # ISC License misrecognized
# - github.com/dchest/uniuri # https://creativecommons.org/publicdomain/zero/1.0/

在这个wwhrd文件特性中,你可以添加例外项,黑名单和白名单特性。

一个检查证书的指令已经写在了Makefile文件中的,因此你只需要执行它即可:

$ make license
==> license check
wwhrd check
INFO[0000] Found Approved license license=Apache-2.0 package=go.mongodb.org/mongo-driver/bson/primitive
INFO[0000] Found Approved license license=Apache-2.0 package=github.com/go-openapi/swag
INFO[0000] Found Approved license license=NewBSD package=github.com/PuerkitoBio/purell
INFO[0000] Found Approved license license=Apache-2.0 package=github.com/go-openapi/jsonreference
INFO[0000] Found Approved license license=Apache-2.0 package=go.mongodb.org/mongo-driver/bson/bsoncodec
INFO[0000] Found Approved license license=Apache-2.0 package=github.com/go-openapi/loads
…

很好,没有许可证问题了。

8.构建应用

现在,我们可以在一个可执行的二进制文件里构建应用,并测试二进制文件:

$ make build
go build -o bin/http-go-server internal/main.go
$ ./bin/http-go-server
2019/10/28 21:47:38 Serving hello at http://[::]:8080

非常棒:-)

9.总结

正如你在这篇文章第一部分看到的一样,使用net/http包和Gorilla/mux作为路由,可以在几分钟或几秒钟内创建一个HTTP服务,但是我想向你展示的是,在代码组织的最佳实践方面如何一步一步深入。为了符合OpenAPI标准使用了Swagger,还使用一些其他有用的工具。

最后,我们小型的HTTP服务成长了一些,如下代码目录结构所示:

.
├── Makefile
├── README.md
├── bin
│ └── http-go-server
├── doc
│ └── index.html
├── go.mod
├── go.sum
├── internal
│ └── main.go
├── pkg
│ └── swagger
│ ├── gen.go
│ ├── server
│ │ └── restapi
│ │ ├── configure_hello.go
│ │ ├── doc.go
│ │ ├── embedded_spec.go
│ │ ├── operations
│ │ │ ├── check_health.go
│ │ │ ├── check_health_parameters.go
│ │ │ ├── check_health_responses.go
│ │ │ ├── check_health_urlbuilder.go
│ │ │ ├── get_hello_user.go
│ │ │ ├── get_hello_user_parameters.go
│ │ │ ├── get_hello_user_responses.go
│ │ │ ├── get_hello_user_urlbuilder.go
│ │ │ └── hello_api.go
│ │ └── server.go
│ └── swagger.yml
├── scripts
└── vendor
├──…
└── modules.txt
└── .gitignore
└── .golangci.yml
└── .wwhrd.yml

所有的代码都可以在GitHub仓库找到:https://github.com/scraly/http-go-server,希望这类文章对你有所帮助。

原文:https://dzone.com/articles/how-to-write-a-http-rest-api-server-in-go-in-minut

本文为 CSDN 翻译,转载请注明来源出处。

【End】



Tags:Go语言   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
zip 是一种常见的归档格式,本文讲解 Go 如何操作 zip。首先看看 zip 文件是如何工作的。以一个小文件为例:(类 Unix 系统下)$ cat hello.textHello!执行 zip 命令进行归档:$ zip...【详细内容】
2021-12-17  Tags: Go语言  点击:(13)  评论:(0)  加入收藏
统一规范篇合理规划目录本篇主要描述了公司内部同事都必须遵守的一些开发规矩,如统一开发空间,既使用统一的开发工具来保证代码最后的格式的统一,开发中对文件和代码长度的控制...【详细内容】
2021-05-18  Tags: Go语言  点击:(232)  评论:(0)  加入收藏
闭包概述 闭包不是Go语言独有的概念,在很多编程语言中都有闭包 闭包就是解决局部变量不能被外部访问的一种解决方案 是把函数当作返回值的一种应用 代码演示总体思想:在函数...【详细内容】
2021-05-14  Tags: Go语言  点击:(223)  评论:(0)  加入收藏
一时想不开,想了解一下Go语言,于是安装了并体验了一下。下载1. 进入golang.google.cn 点击Download Go 2.选择对应的操作系统,点击后开始下载。 安装1. windows下执行傻瓜式安...【详细内容】
2021-05-12  Tags: Go语言  点击:(237)  评论:(0)  加入收藏
再次整理了一下这个日志收集系统的框,如下图 这次要实现的代码的整体逻辑为: 完整代码地址为: https://github.com/pythonsite/logagentetcd介绍高可用的分布式key-value存储,...【详细内容】
2021-01-14  Tags: Go语言  点击:(135)  评论:(0)  加入收藏
生命不止,继续 Go go go !!!之前关于golang操作数据库的博客:Go实战&ndash;go语言操作MySQL数据库(go-sql-driver/mysql)Go实战&ndash;go语言操作sqlite数据库(The way to go)...【详细内容】
2021-01-05  Tags: Go语言  点击:(196)  评论:(0)  加入收藏
欢迎访问我的GitHubhttps://github.com/zq2599/blog_demos内容:所有原创文章分类和汇总,及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;关于《gRPC学习》系列《gRPC学习》...【详细内容】
2020-12-14  Tags: Go语言  点击:(124)  评论:(0)  加入收藏
概述Go语言作为一门开源的编程语言,以简洁、快速、安全著称。尤其在高性能的分布式服务器领域得到广泛应用。技多不压身,在学习过程中记录下来,以备后续参考,希望对有同样需求的...【详细内容】
2020-11-12  Tags: Go语言  点击:(65)  评论:(0)  加入收藏
go-fly基于GO语言实现的web客服即时通讯与客服管理系统。非常适合给自己的网站增加在线客服功能,代码简单也适合学习。Github地址:https://github.com/taoshihan1991/go-fly1....【详细内容】
2020-09-25  Tags: Go语言  点击:(154)  评论:(0)  加入收藏
Illustration created for “A Journey With Go”, made from the original Go Gopher, created by Renee Fℹ️ 这篇文章基于 Go 1.13。在内存从分配到回收的生命周期中,内存...【详细内容】
2020-09-24  Tags: Go语言  点击:(65)  评论:(0)  加入收藏
▌简易百科推荐
zip 是一种常见的归档格式,本文讲解 Go 如何操作 zip。首先看看 zip 文件是如何工作的。以一个小文件为例:(类 Unix 系统下)$ cat hello.textHello!执行 zip 命令进行归档:$ zip...【详细内容】
2021-12-17  Go语言中文网    Tags:Go语言   点击:(13)  评论:(0)  加入收藏
大家好,我是 polarisxu。前段时间,Russ Cox 明确了泛型相关的事情,原计划在标准库中加入泛型相关的包,改放到 golang.org/x/exp 下。目前,Go 泛型的主要设计者 ianlancetaylor 完...【详细内容】
2021-11-30  Go语言中文网    Tags:slices 包   点击:(24)  评论:(0)  加入收藏
前言最近因为项目需要写了一段时间的 Go ,相对于 Java 来说语法简单同时又有着一些 Python 之类的语法糖,让人大呼”真香“。 但现阶段相对来说还是 Python 写的多一些,偶尔还...【详细内容】
2021-11-25  crossoverJie    Tags:Go   点击:(29)  评论:(0)  加入收藏
go-micro是基于 Go 语言用于开发的微服务的 RPC 框架,主要功能如下:服务发现,负载均衡 ,消息编码,请求/响应,Async Messaging,可插拔接口,最后这个功能牛p安装步骤安装proto...【详细内容】
2021-09-06    石老师小跟班  Tags:go-micro   点击:(197)  评论:(0)  加入收藏
GoLand 2021.2 EAP 5 现已发布。用户可以从工具箱应用程序中获得 EAP 构建,也可以从官方网站手动下载。并且从此 EAP 开始,只有拥有有效的 JetBrains 帐户才能加入该计划。手...【详细内容】
2021-06-29  IT实战联盟  今日头条  Tags:GoLand   点击:(185)  评论:(0)  加入收藏
作者:HDT3213今天给大家带来的开源项目是 Godis:一个用 Go 语言实现的 Redis 服务器。支持: 5 种数据结构(string、list、hash、set、sortedset) 自动过期(TTL) 发布订阅、地理位...【详细内容】
2021-06-18  HelloGitHub  今日头条  Tags:Go   点击:(125)  评论:(0)  加入收藏
统一规范篇合理规划目录本篇主要描述了公司内部同事都必须遵守的一些开发规矩,如统一开发空间,既使用统一的开发工具来保证代码最后的格式的统一,开发中对文件和代码长度的控制...【详细内容】
2021-05-18  1024课堂    Tags:Go语言   点击:(232)  评论:(0)  加入收藏
闭包概述 闭包不是Go语言独有的概念,在很多编程语言中都有闭包 闭包就是解决局部变量不能被外部访问的一种解决方案 是把函数当作返回值的一种应用 代码演示总体思想:在函数...【详细内容】
2021-05-14  HelloGo  今日头条  Tags:Go语言   点击:(223)  评论:(0)  加入收藏
一时想不开,想了解一下Go语言,于是安装了并体验了一下。下载1. 进入golang.google.cn 点击Download Go 2.选择对应的操作系统,点击后开始下载。 安装1. windows下执行傻瓜式安...【详细内容】
2021-05-12  程序员fearlazy  fearlazy  Tags:Go语言   点击:(237)  评论:(0)  加入收藏
1.简介channel是Go语言的一大特性,基于channel有很多值得探讨的问题,如 channel为什么是并发安全的? 同步通道和异步通道有啥区别? 通道为何会阻塞协程? 使用通道导致阻塞的协程...【详细内容】
2021-05-10  程序员麻辣烫  今日头条  Tags:Go通道   点击:(274)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条