# Go: How to Send JSON Data in an HTTP POST Request

> Use net/http's http.Post with a bytes.Buffer for a raw JSON string, or marshal a Go struct with encoding/json first for structured request bodies

**URL:** https://sentry.io/answers/sending-json-via-an-http-post-request-in-go/

---

## The Problem

You don't know how to send JSON data in the body of an HTTP request in Go. For example:

```json
{
  "description": "Buy cheese and bread for breakfast."
}
```

## The Solution

The simplest way to send JSON data in an HTTP request is to use the [`http.Post`](https://pkg.go.dev/net/http#Post) function from the [`http`](https://pkg.go.dev/net/http) package, which requires only a URL, a content type, and a request body.

### Sending a JSON String Via HTTP POST in Go

To send a JSON via an HTTP POST request, use [`http.Post`](https://pkg.go.dev/net/http#Post) and wrap your JSON string in a [`bytes.Buffer`](https://pkg.go.dev/bytes#Buffer).

```go
package main

import (
	"bytes"
	"log"
	"net/http"
)

func main() {
	// Define the JSON body as a string.
	body := `{"description": "Buy cheese and bread for breakfast."}`

	// Make the request.
	response, err := http.Post("https://example.com/endpoint", "application/json", bytes.NewBufferString(body))
	if err != nil {
		log.Fatalf("POST failed: %s", err)
	}

	// Do something with the response.
	log.Printf("POST returned with %d status", response.StatusCode)
}
```

**Note:** The `http.Post` function requires only a URL, a content type, and a request body. If you want more control over your request, check out [`http.Client`](https://pkg.go.dev/net/http#Client) to learn how to set custom headers, timeouts, etc.

### Generating JSON From a Struct in Go

If you'd like to generate your JSON programmatically, use Go's [`encoding/json`](https://pkg.go.dev/encoding/json) package.

The [`json.Marshal`](https://pkg.go.dev/encoding/json#Marshal) function uses user-defined `json` struct tags to format its output.

The Go Wiki offers more information about [well-known struct tags](https://go.dev/wiki/Well-known-struct-tags).

```go
package main

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

// Task contains the fields that you'd like to marshal (or serialise) as JSON.
type Task struct {
	Title       string `json:"title"`
	Description string `json:"description"`
}

func main() {
	// Define a Task instance.
	task := Task{
		Title:       "Morning task",
		Description: "Buy cheese and bread for breakfast.",
	}

	// Generate a byte slice representing the Task.
	body, err := json.Marshal(&task)
	if err != nil {
		log.Fatalf("Failed to marshal JSON: %s", err)
	}

	// Make the request.
	// Note that this time, `body` is a slice of bytes, so we use `bytes.NewBuffer` instead.
	response, err := http.Post("https://example.com/endpoint", "application/json", bytes.NewBuffer(body))
	if err != nil {
		log.Fatalf("POST failed: %s", err)
	}

	// Do something with the response.
	log.Printf("POST returned with %d status", response.StatusCode)
}
```

### Further Reading

- The [Go `http.Post` function](https://pkg.go.dev/net/http#Post) documentation
- [The Go `http.Response` type](https://pkg.go.dev/net/http#Response) documentation
- The [Go `json` package](https://pkg.go.dev/encoding/json) documentation
- [Struct tags](https://go.dev/ref/spec#Tag) in the Go spec

---

*Source: [sentry.io/answers/sending-json-via-an-http-post-request-in-go/](https://sentry.io/answers/sending-json-via-an-http-post-request-in-go/)*
