AppDividend
Latest Code Tutorials

Golang Http Example | GET, POST HTTP Requests In Golang

0

Golang Http Example is today’s topic. Golang http package provides HTTP client and server implementations. Web developers make http requests all the time. In this post, we’re going to make some http requests using Golang. I am going to show you how I make http GET and POST requests using the net/http built-in package.

Golang Http

Golang http package offers convenient functions like Get, Post, Head for common http requests.

Let’s see the following example.

// hello.go

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	resp, err := http.Get("https://api.github.com/users/KrunalLathiya")
	if err != nil {
		print(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		print(err)
	}
	fmt.Print(string(body))
}

Output

➜  hello go run hello.go
{"login":"KrunalLathiya","id":14403830,"node_id":"MDQ6VXNlcjE0NDAzODMw","avatar_url":"https://avatars1.githubusercontent.com/u/14403830?v=4","gravatar_id":"","url":"https://api.github.com/users/KrunalLathiya","html_url":"https://github.com/KrunalLathiya","followers_url":"https://api.github.com/users/KrunalLathiya/followers","following_url":"https://api.github.com/users/KrunalLathiya/following{/other_user}","gists_url":"https://api.github.com/users/KrunalLathiya/gists{/gist_id}","starred_url":"https://api.github.com/users/KrunalLathiya/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/KrunalLathiya/subscriptions","organizations_url":"https://api.github.com/users/KrunalLathiya/orgs","repos_url":"https://api.github.com/users/KrunalLathiya/repos","events_url":"https://api.github.com/users/KrunalLathiya/events{/privacy}","received_events_url":"https://api.github.com/users/KrunalLathiya/received_events","type":"User","site_admin":false,"name":"Krunal","company":"Freelancer","blog":"https://appdividend.com","location":"Rajkot","email":null,"hireable":true,"bio":"Web Developer and Author","public_repos":118,"public_gists":0,"followers":502,"following":13,"created_at":"2015-09-20T19:22:19Z","updated_at":"2019-11-10T12:44:04Z"}

In this example, we’re calling http.Get, which gives us a response and error value.

We are sending a GET request to Github API, and we get the response and store it in the body variable.

If there was an error while making the GET request, the err variable will be non-nil means we can either print or log the error in the file.

We then defer an execution of the resp.Body.Close(), which will be executed at the end of the function.

When we make an http request, we get the response and the error back.

We may feel lazy and decide not to check for errors or close the response body.

If we do not close the response body, the connection may remain open and cause the resource leak.

But if the error is not nil that is in case of an error, the response can be nil.

This step is very, very important. When you have the response body (it is not nil), forgetting to close the response body can cause resource leaks in long-running programs.

We’re then reading the entirety of the response body and logging it.

The resp.Body implements an io.Reader interface allowing us to use the ioutil.ReadAll function.

In our case, we do know that our target response is small in size.

This gives us the required confidence to read the full response in memory.

However, since the response body is the io.Reader, we could read the data chunk by chunk and process it as a stream of data. But for this blog post, I have kept my code short and used the Github example.

Golang Http Post Example

For the post request example, we will make use of the httpbin.org site to help us inspect the requests.

See the following code.

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	reqBody, err := json.Marshal(map[string]string{
		"username": "Krunal Lathiya",
		"email":    "krunal@appdividend.com",
	})
	if err != nil {
		print(err)
	}
	resp, err := http.Post("https://httpbin.org/post",
		"application/json", bytes.NewBuffer(reqBody))
	if err != nil {
		print(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		print(err)
	}
	fmt.Println(string(body))
}

Output

➜  hello go run hello.go
{
  "args": {},
  "data": "{\"email\":\"krunal@appdividend.com\",\"username\":\"Krunal Lathiya\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept-Encoding": "gzip",
    "Content-Length": "62",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "Go-http-client/1.1"
  },
  "json": {
    "email": "krunal@appdividend.com",
    "username": "Krunal Lathiya"
  },
  "origin": "43.241.145.32, 43.241.145.32",
  "url": "https://httpbin.org/post"
}

➜  hello

The Post function is similar. In this example, we’re going to send the JSON payload.

You can checkout: Golang JSON Example for more information regarding handing json data in Go.

We are marshaling a map and will get the []byte if successful. We handled an error and then called http.Post.

This function takes a URL, the content type we’re using (in our case it is JSON), and an instance of io.Reader.

At our hands, we have the []byte, which doesn’t implement this interface.

So, we use the bytes.NewBuffer which gives us the bytes buffer based on our bytes slice.

This buffer is both readable and writable. It’s “readable” part satisfies the io.Reader interface and serves our purpose.

Posting Form Request & Decoding JSON in Golang

See the following code in which we post the form request and decode the json.

// hello.go

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
)

func main() {
	formData := url.Values{
		"username": {"KrunalLathiya"},
	}
	resp, err := http.PostForm("https://httpbin.org/post", formData)
	if err != nil {
		print(err)
	}
	defer resp.Body.Close()
	var data map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		print(err)
	}
	fmt.Println(data["form"])
}

Output

➜  hello go run hello.go
map[username:KrunalLathiya]
➜  hello

In the above example, the formData variable is of url.Values type, which is map[string][]string — means it’s a map type, where each key has a value of []string.

For each key, we can have the list of string values.

We can use the http.PostForm function to submit forms quickly.

Remember, we talked about taking the advantage of resp.Body being an io.Reader to read as a stream? The json.NewDecoder can take the io.Reader to read the data chunk by chunk.

Then we use the Decode function to unmarshal the JSON into Go data structure, in this case, a map.

We could have used the ioutil.ReadAll like before to first read the data into the memory and then call the json.Unmarshall on it. It would have worked pretty well for a small payload.

Conclusion

We have seen how to send GET and POST requests in Golang using http package.

Finally, Golang Http Example | GET, POST HTTP Requests In Golang tutorial is over.

Recommended Posts

Golang Log example

Golang Slice example

Golang Template example

Golang Arrays example

Golang Structs example

Leave A Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.