HTTP Client and Server in Go
Go’s standard library provides powerful HTTP capabilities. Building web servers and clients is straightforward and efficient.
HTTP Server
Basic HTTP Server
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", helloHandler)
http.ListenAndServe(":8080", nil)
}
Multiple Routes
package main
import (
"fmt"
"net/http"
)
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Home Page")
}
func aboutHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "About Page")
}
func main() {
http.HandleFunc("/", homeHandler)
http.HandleFunc("/about", aboutHandler)
http.ListenAndServe(":8080", nil)
}
JSON Response
package main
import (
"encoding/json"
"net/http"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
func userHandler(w http.ResponseWriter, r *http.Request) {
user := User{ID: 1, Name: "Alice", Age: 30}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
func main() {
http.HandleFunc("/user", userHandler)
http.ListenAndServe(":8080", nil)
}
Request Methods
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func apiHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
fmt.Fprintf(w, "GET request")
case http.MethodPost:
var data map[string]interface{}
json.NewDecoder(r.Body).Decode(&data)
fmt.Fprintf(w, "POST request: %v", data)
case http.MethodPut:
fmt.Fprintf(w, "PUT request")
case http.MethodDelete:
fmt.Fprintf(w, "DELETE request")
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
func main() {
http.HandleFunc("/api", apiHandler)
http.ListenAndServe(":8080", nil)
}
HTTP Client
Basic HTTP Request
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://api.example.com/data")
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println(string(body))
}
POST Request
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
data := map[string]string{
"name": "Alice",
"age": "30",
}
jsonData, _ := json.Marshal(data)
resp, err := http.Post(
"https://api.example.com/users",
"application/json",
bytes.NewBuffer(jsonData),
)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
fmt.Println("Status:", resp.Status)
}
Custom Request
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "https://api.example.com/data", nil)
if err != nil {
fmt.Println("Error:", err)
return
}
// Add headers
req.Header.Add("Authorization", "Bearer token123")
req.Header.Add("User-Agent", "MyApp/1.0")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}
Middleware
Simple Middleware
package main
import (
"fmt"
"net/http"
)
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello!")
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", helloHandler)
handler := loggingMiddleware(mux)
http.ListenAndServe(":8080", handler)
}
Best Practices
โ Good: Always Close Response Body
// DO: Always close response body
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
โ Bad: Forget to Close
// DON'T: Forget to close response body
resp, _ := http.Get(url)
body, _ := ioutil.ReadAll(resp.Body)
โ Good: Check Status Code
// DO: Check response status
resp, _ := http.Get(url)
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status: %d", resp.StatusCode)
}
โ Good: Set Timeouts
// DO: Set timeouts for HTTP client
client := &http.Client{
Timeout: 10 * time.Second,
}
resp, err := client.Get(url)
Summary
Go’s HTTP support provides:
- Simple server creation with
http.ListenAndServe - Easy client requests with
http.Get,http.Post - Middleware support for request processing
- JSON encoding/decoding built-in
- Efficient handling of concurrent requests
These features make Go ideal for web development.
Comments