Christian Giacomi

My personal software development blog

Simple PUT/PATCH requests using Go

How to perform a simple PUT or PATCH request with a JSON body using Go

Posted — May 15, 2020   Category — software 

Making HTTP requests in Go is very simple, the http package contains all the tools you will need to carry out your task. The package contains three helper functions to perform basic requests, and in the case of more complex or custom requests one needs only a couple of extra lines of code.

Http Package

The http package in Go contains several convenience functions to make Get, Post and Head requests over http. But in the case of PUT and PATCH we will need to add a little more code. Lets start looking at the helper functions and then move to the more complex requests.

Convenience functions

The following are the convenience functions defined in the http package.

convenience functions

And this is how you would use either one of them. Here is a sample GET request.

resp, err := http.Get("http://example.com/")
if err != nil {
	log.Fatal(err)
}
defer resp.Body.Close()

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

log.Println(string(body))

Should you want to use any of the other ones you will just need to call the appropriate function, but the code will look the same, with the exception of POST requests which also take a body.

More complex requests

To make more complex requests, or in our case you want to make PUT of PATCH requests you will need to use the following function.

request function

As you will see below the are a few more lines of code, but the gist is still the same, with the exception of having to create a Client first which will be used to perform the request.

package main

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

func main() {
    // 1.
    payload, err := json.Marshal(map[string]interface{} {
        "title": "my simple todo",
        "completed": false,
    })
    if err != nil {
        log.Fatal(err)
    }

    // 2.
    client := &http.Client{}
    url := "https://sample42.free.beeceptor.com/put"

    // 3.
    req, err := http.NewRequest(http.MethodPut, url, bytes.NewBuffer(payload))
    req.Header.Set("Content-Type", "application/json")
    if err != nil {
        log.Fatal(err)
    }

    // 4.
    resp, err := client.Do(req)
    if err != nil {
        log.Fatal(err)
    }

    // 5.
    defer resp.Body.Close()

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

As you can see above, we start by doing: 1) defining the JSON payload that we want to send to the endpoint we are calling. 2) Instantiate the http Client. 3) Define the request and set any additional headers. 4) Perform the actual request. 5) Ensure we clean up. 6) Read the response.

We can also replace http.MethodPut with the http method we want to use.

const (
    MethodGet     = "GET"
    MethodHead    = "HEAD"
    MethodPost    = "POST"
    MethodPut     = "PUT"
    MethodPatch   = "PATCH" // RFC 5789
    MethodDelete  = "DELETE"
    MethodConnect = "CONNECT"
    MethodOptions = "OPTIONS"
    MethodTrace   = "TRACE"
)

Conclusion

As you can see it is very simple to make any type of http request in Go. If you are using GET or POST you can leverage the convenience functions, otherwise you just need to add a couple of lines of code and use the standard request function. Here is the official documentation for the http package documentation.

Here is a working repl for the code.

If this post was helpful tweet it or share it.

See Also