http.Post Golang example

Tags: go, webdev, beginners, restapis
Published: 2021-12-25 16:12:28

Hello, 

Today, I am going to write small tutorial about basic usage of [http.Post](https://pkg.go.dev/net/http) method in Golang. Please ignore if there is any mistakes, thank you.

```golang
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.")
}

```

Thank you.