Golang中像curl一样的JSON/HTTP请求

huangapple go评论88阅读模式
英文:

Golang JSON/HTTP request like curl

问题

我正在寻找一个关于如何使用Golang执行类似于curl的请求的快速教程。我有两个API需要通信,它们的工作方式基本相同。一个是ElasticSearch,另一个是Phillips Hue。我知道这两个都有Go语言的库。但我不是在找这些库,我想学习如何使用Golang来实现以下功能:

$ curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d '{
"query" : {
    "term" : { "user" : "kimchy" }
} }'

在Golang中,我找到的所有资料似乎都是硬编码成:

http://url:port/api/_function?something=value?anotherthing=value...

但我已经在软件中有JSON对象了。有没有办法用JSON字符串或结构体等类似的方式来模拟CURL的-d功能呢?

英文:

I am looking for a quick tutorial on how to perform requests with Golang that emulate those one would use with curl. I have two APIs that I want to communicate with that both essentially work the same way. One is ElasticSearch, the other is Phillips Hue. I know that both of these have libraries in Go. That's not what I'm after, I'm trying to learn how to do this:

$ curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d '{
"query" : {
    "term" : { "user" : "kimchy" }
} }'

With Golang. Everything I can find people seem to be hard coding to

http://url:port/api/_function?something=value?anotherthing=value...

But I already have JSON objects floating around in the software. Is there a way that I can emulate the -d feature of CURL with a JSON string or struct or something similar?

答案1

得分: 28

正如评论者@JimB指出的,根据HTTP/1.1规范,使用GET请求时可以包含请求体,但并不要求服务器实际解析请求体,所以如果遇到奇怪的行为也不要感到惊讶。

话虽如此,以下是使用golang HTTP客户端执行带有请求体的GET请求的方法:

reader := strings.NewReader(`{"body":123}`)
request, err := http.NewRequest("GET", "http://localhost:3030/foo", reader)
// TODO: 检查错误
client := &http.Client{}
resp, err := client.Do(request)
// TODO: 检查错误

Web服务器将看到如下请求:

GET /foo HTTP/1.1
Host: localhost:3030
User-Agent: Go 1.1 package http
Content-Length: 12
Accept-Encoding: gzip

{"body":123}

要构建类似于"curl"的命令行工具,你需要使用一些go包(例如用于解析命令行参数处理HTTP请求的包),但是你可以从(优秀的)文档中找到所需的内容。

英文:

As commenter @JimB pointed out, doing a GET request with a body is not disallowed by the HTTP/1.1 specification; however, it is also not required that servers actually parse the body, so do not be surprised if you encounter strange behavior.

That said, here is how you would perform a GET request with a body using a golang HTTP client:

reader := strings.NewReader(`{"body":123}`)
request, err := http.NewRequest("GET", "http://localhost:3030/foo", reader)
// TODO: check err
client := &http.Client{}
resp, err := client.Do(request)
// TODO: check err

The web server will see a request like this:

GET /foo HTTP/1.1
Host: localhost:3030
User-Agent: Go 1.1 package http
Content-Length: 12
Accept-Encoding: gzip

{"body":123}

To build a command-line tool like "curl" you will need to use a number of go packages (e.g. for flag parsing and HTTP request handling) but presumably you can find what you need from the (excellent) docs.

huangapple
  • 本文由 发表于 2015年4月1日 05:46:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/29379156.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定