DEV Community

Ramu Mangalarapu
Ramu Mangalarapu

Posted on

http.Post Golang example

Hello,

Today, I am going to write small tutorial about basic usage of http.Post method in Golang. Please ignore if there is any mistakes, thank you.

package main

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

// Post holds the post data that we send or receive from the API server.
type Post struct {
    ID     string `json:"id,omitempty"`
    Title  string `json:"title"`
    Body   string `json:"Body"`
    UserID string `json:"user_id"`
}

func main() {
    // Before we create resource or post on the API server, we need to see the documentation of the REST API we want to use.
    // Like what is the URL, version, what are the required fields in the resource object.
    // Most of the companies create API docs,  it will have examples in different programming languages along with cURL commands.
    // Companies also create SDKs in different programming languages.
    // Difference between SDK and API: https://addevice.medium.com/difference-between-an-api-and-an-sdk-anyone-can-understand-3a95bf7fc691
    // For example Okta to deal with mangement of users, they are having SDK at:https://github.com/okta/okta-sdk-golang

    // Let's build response body for the server we want to post or create resource
    p := new(Post)
    p.Title = "Title"
    p.Body = "This is body"
    p.UserID = "userID"

    // Now we need erializes Post 'p' to JSON
    b, err := json.Marshal(p)
    if err != nil {
        log.Fatalf("Failed to Serialize to JSON from native Go struct type: %v", err)
    }

    // here http.Post method expects body as 'io.Redear' which should implement Read() method.
    // So, bytes package will take care of that.
    body := bytes.NewBuffer(b)

    // REST APIs means, always think in terms of 'resources'.
    // This is good resource: https://www.practical-go-lessons.com/chap-35-build-an-http-client
    // This post method uses default http client, so timeout is NOT mentioned.
    // Doc of this POST API can be found here: https://jsonplaceholder.typicode.com/guide/.
    postURL := "https://jsonplaceholder.typicode.com/posts"
    resp, err := http.Post(postURL, "application/json; charset=utf-8", body)
    if err != nil {
        log.Fatalf("Failed to create resource at: %s and the error is: %v\n", postURL, err)
    }

    // Always close the response body
    defer resp.Body.Close()

    // Let us just print the response headers info from the server
    log.Printf("Status received from server is: %s", resp.Status)
    log.Printf("StatusCode received from server is: %d", resp.StatusCode)
    log.Printf("Content Type received from Server is: %s", resp.Header["Content-Type"][0])

    // Like I mentioned in my last article,
    // we can read the server response to our native Golang type
    // as the map data structure is close to JSON, we could use it
    // in fact we could use this for most of the wire formats.
    data := make(map[string]interface{})
    if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
        log.Fatalf("Failed to read response body: %v", err)
    }

    // Let's print the map data by iterating over it.
    // Usually in real usecases we use this response to pass to ther functions.
    for key, value := range data {
        fmt.Printf("%s: %v\n", key, value)
    }
    log.Println("We have successfully created resource and read the response from API server.")
}

Enter fullscreen mode Exit fullscreen mode

Thank you.

Discussion (1)

Collapse
clavinjune profile image
Clavin June

Great post!

Actually, you can use this snippet below instead of using ioutil.ReadAll and json.Unmarshal

var data map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
    log.Fatalf("Failed to read response body: %v", err)
}
Enter fullscreen mode Exit fullscreen mode