12

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?

5
  • Just to be clear: the only issue you're facing is the POST of some JSON? Or the whole thing? (argument/flag parsing, json encoding.. etc). Commented Mar 31, 2015 at 22:02
  • 1
    though curl will do it, sending body in a GET request is not recommended. While the spec does not disallow it, server's are not required to parse it Commented Mar 31, 2015 at 22:12
  • @SimonWhitehead I understand language syntax. I'm looking for the right way to send data to, and receive data from, an API. (1) I want to understand how this works. (2) I only need to do it a couple of times in my application, based on some other data. So I am a little reluctant to bring in two libraries, and all their dependencies, to make two calls to two different APIs. I know this is probably more than anyone wants to explain here. If I could just be pointed at a resource. Searches are getting me tutorials on building APIs - which I don't need. Commented Mar 31, 2015 at 23:41
  • @JimB Could you point me to some place where the generally accepted as correct pattern is explained? Commented Mar 31, 2015 at 23:44
  • @codecode No problem - I just wanted to clarify which part of the problem you were struggling with :) Glad you got your answer. Commented Apr 1, 2015 at 0:05

1 Answer 1

28

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for this... now that you've been so kind as to point out that perhaps I'm going about this wrong, what's the right way?
@codecode: it's a small thing really - by convention (and due to ambiguity of the HTTP specs) not all request methods are associated with a body (e.g. GET, DELETE) whereas some are (e.g. PUT, POST, etc). But if your goal is to emulate curl in golang then you are on the right track since that tool allows the behavior you describe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.