类似于curl的Golang JSON/HTTP请求

12

我正在寻找一个关于如何使用Golang执行请求的快速教程,模拟使用curl时的请求方式。我有两个API需要通信,它们本质上是相同的。一个是ElasticSearch,另一个是飞利浦Hue。我知道这两个都有Go语言库,但我想学习如何自己实现:

$ 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功能?


只是为了明确:你面临的唯一问题是一些JSON的“POST”吗?还是整个过程?(参数/标志解析,JSON编码等)。 - Simon Whitehead
1
虽然 curl 可以实现,但不建议在 GET 请求中发送请求体。尽管规范没有禁止这样做,但服务器不一定需要解析它。 - JimB
@SimonWhitehead 我理解语言语法。我正在寻找向API发送数据和从API接收数据的正确方法。(1)我想了解这是如何工作的。(2)我只需要在我的应用程序中执行几次,基于其他一些数据。因此,我有点不愿意引入两个库及其所有依赖项,以对两个不同的API进行两次调用。我知道这可能比任何人都想在这里解释的要多。如果可以指向一个资源就好了。搜索结果给我带来了构建API教程 - 这不是我所需要的。 - codecode
@JimB,你能指点我一些通常被认为是正确的模式的解释吗? - codecode
没问题 - 我只是想澄清你遇到的问题的哪个部分 :) 很高兴你得到了答案。 - Simon Whitehead
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: check err
client := &http.Client{}
resp, err := client.Do(request)
// TODO: check err

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请求处理),但是您可以从(出色的)文档中找到所需内容。

谢谢您的指点,既然您这么好心地指出我可能走错了路,那正确的方法是什么呢? - codecode
@codecode:这其实是一个小问题 - 根据约定(以及HTTP规范的歧义),并不是所有的请求方法都与请求体相关联(例如GET、DELETE),而有些则是(例如PUT、POST等)。但是,如果你的目标是在golang中模拟curl的行为,那么你走对了路,因为该工具允许你描述的行为。 - maerics

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接