How to make an HTTP request in golang with best practices?

ai make http request golang
R
Rahul Yadav

Senior Email Marketing Strategist

 
June 30, 2025 3 min read

Making a HTTP request in golang is pretty straightforward and simple, following are the examples by HTTP verbs

GET

The HTTP GET method requests a representation of the specified resource. Requests using GET should only retrieve data.

package main

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

func main() {
resp, err := http.Get("https://httpbin.org/get")
if err != nil {
log.Fatal(err)
}

defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}

fmt.Println(string(body))
}

GET with Query Args

package main

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

func main() {
client := &http.Client{}
req, err := http.NewRequest(http.MethodGet, "https://httpbin.org/get", nil)
if err != nil {
log.Fatal(err)
}

// appending to existing query args
q := req.URL.Query()
q.Add("foo", "bar")

// assign encoded query string to http request
req.URL.RawQuery = q.Encode()

resp, err := client.Do(req)
if err != nil {
    fmt.Println("Errored when sending request to the server")
    return
}

defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Println(resp.Status)
fmt.Println(string(responseBody))

}

POST

The following example sends a POST request with data in JSON format.

package main

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

func main() {
values := map[string]string{"foo": "baz"}
jsonData, err := json.Marshal(values)

req, err := http.NewRequest(http.MethodPost, "https://httpbin.org/post", bytes.NewBuffer(jsonData))
if err != nil {
    log.Fatal(err)
}

// appending to existing query args
q := req.URL.Query()
q.Add("foo", "bar")

// assign encoded query string to http request
req.URL.RawQuery = q.Encode()

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
    fmt.Println("Errored when sending request to the server")
    return
}

defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
    log.Fatal(err)
}

fmt.Println(resp.Status)
fmt.Println(string(responseBody))

}

Best Practices

Re-use HTTP Client

The HTTP 1.1 protocol supports HTTP Persistent connections, or also known as HTTP Keep-Alive. This allows a client and a server to re-use the same underlying TCP connection when sending multiple HTTP Requests/Responses. So instead of establishing a connection for each HTTP Request, the client re-uses the TCP connection previously created more than once. This is particularly useful for performance reasons and when sending multiple requests to the same host.

func httpClient() *http.Client {
    client := &http.Client{Timeout: 10 * time.Second}
    return client
}

Reuse the http.Client throughout your code base.

An example of it as follows:

package main

import (
"bytes"
"io/ioutil"
"log"
"net/http"
"time"
)

func httpClient() *http.Client {
client := &http.Client{Timeout: 10 * time.Second}
return client
}

func sendRequest(client *http.Client, method string) []byte {
endpoint := "https://httpbin.org/post"
values := map[string]string{"foo": "baz"}
jsonData, err := json.Marshal(values)

req, err := http.NewRequest(method, endpoint, bytes.NewBuffer(jsonData))
if err != nil {
    log.Fatalf("Error Occurred. %+v", err)
}

response, err := client.Do(req)
if err != nil {
    log.Fatalf("Error sending request to API endpoint. %+v", err)
}

// Close the connection to reuse it
defer response.Body.Close()

body, err := ioutil.ReadAll(response.Body)
if err != nil {
    log.Fatalf("Couldn't parse response body. %+v", err)
}

return body

}

func main() {
// c should be re-used for further calls
c := httpClient()
response := sendRequest(c, http.MethodPost)
log.Println("Response Body:", string(response))
}

R
Rahul Yadav

Senior Email Marketing Strategist

 

Technical Manager and Passionate Fullstack and polyglot developer.

Related Articles

seo

6 Authentic Ways to Trace an IP Address from Email

Learn effective methods to trace IP addresses from emails for security verification, spam identification, and enhanced email management with practical step-by-step guidance.

By Abhijeet Chattarjee June 30, 2025 6 min read
Read full article
marketing

Demystifying Email Delivery: A Deep Dive into Email APIs, SMTP Servers, and Email Delivery Services

This blog post dives into the world of email APIs, SMTP servers, and email delivery services. Learn how they work together to get your emails into inboxes, not spam folders. Boost your email marketing results with this essential guide!

By Abhijeet Chattarjee June 30, 2025 7 min read
Read full article
content

21 SMTP Response Codes

The SMTP response code list can be used to help quickly determine the reason for email bounces or why you received an SMTP error when sending an email.

By Rahul Yadav June 30, 2025 6 min read
Read full article
digital

6 Tips for Defending Against Business Email Cybercriminal Attacks

Learn how to defend your firm from business email cybercriminal attacks, including how to spot and block them. Discover important tips with Mailazy now!

By Abhijeet Chattarjee June 30, 2025 6 min read
Read full article