Golang Networking & HTTP Quiz
40 comprehensive questions on Golang's networking and HTTP capabilities, covering basic HTTP servers, HTTP clients, request/response lifecycle, JSON marshalling/unmarshalling, and REST API patterns — with 20 code examples demonstrating practical networking operations.
Question 1
How do you create a basic HTTP server in Go?
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)
}Question 2
How do you make an HTTP GET request in Go?
resp, err := http.Get("https://api.example.com/users")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(body))Question 3
What is JSON marshalling in Go?
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
user := User{Name: "Alice", Email: "[email protected]"}
// Marshal to JSON
jsonData, err := json.Marshal(user)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(jsonData)) // {"name":"Alice","email":"[email protected]"}Question 4
How do you unmarshal JSON in Go?
jsonStr := `{"name":"Bob","email":"[email protected]"}`
var user User
err := json.Unmarshal([]byte(jsonStr), &user)
if err != nil {
log.Fatal(err)
}
fmt.Println(user.Name) // BobQuestion 5
How do you handle HTTP request parameters?
func userHandler(w http.ResponseWriter, r *http.Request) {
// Query parameters
id := r.URL.Query().Get("id")
// Form data (POST)
r.ParseForm()
name := r.Form.Get("name")
// Path parameters (with gorilla/mux or similar)
// vars := mux.Vars(r)
// id := vars["id"]
fmt.Fprintf(w, "User %s with id %s", name, id)
}Question 6
How do you set HTTP response headers?
func apiHandler(w http.ResponseWriter, r *http.Request) {
// Set content type
w.Header().Set("Content-Type", "application/json")
// Set custom headers
w.Header().Set("X-API-Version", "1.0")
// Set status code
w.WriteHeader(http.StatusOK)
// Write response
json.NewEncoder(w).Encode(map[string]string{"status": "ok"})
}Question 7
How do you create an HTTP client with timeout?
client := &http.Client{
Timeout: 10 * time.Second,
}
resp, err := client.Get("https://api.example.com/data")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Use responseQuestion 8
How do you handle different HTTP methods?
func handleUser(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
// Get user
getUser(w, r)
case http.MethodPost:
// Create user
createUser(w, r)
case http.MethodPut:
// Update user
updateUser(w, r)
case http.MethodDelete:
// Delete user
deleteUser(w, r)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}Question 9
How do you implement middleware in Go HTTP?
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
next.ServeHTTP(w, r)
log.Printf("%s %s %v", r.Method, r.URL.Path, time.Since(start))
})
}
func main() {
handler := loggingMiddleware(http.DefaultServeMux)
http.ListenAndServe(":8080", handler)
}Question 10
How do you send JSON in HTTP response?
type Response struct {
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
func apiHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
response := Response{
Message: "Success",
Data: map[string]string{"key": "value"},
}
json.NewEncoder(w).Encode(response)
}Question 11
How do you parse JSON from HTTP request?
type CreateUserRequest struct {
Name string `json:"name"`
Email string `json:"email"`
}
func createUserHandler(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Bad request", http.StatusBadRequest)
return
}
// Use req.Name, req.Email
fmt.Fprintf(w, "Created user %s", req.Name)
}Question 12
How do you handle HTTP errors properly?
func getUserHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if id == "" {
http.Error(w, "Missing id parameter", http.StatusBadRequest)
return
}
user, err := getUserByID(id)
if err != nil {
if errors.Is(err, ErrNotFound) {
http.Error(w, "User not found", http.StatusNotFound)
} else {
http.Error(w, "Internal server error", http.StatusInternalServerError)
}
return
}
json.NewEncoder(w).Encode(user)
}Question 13
How do you implement basic authentication?
func basicAuthMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
if !ok || username != "admin" || password != "secret" {
w.Header().Set("WWW-Authenticate", `Basic realm="example"`)
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}Question 14
How do you make POST requests with JSON body?
type Payload struct {
Name string `json:"name"`
}
payload := Payload{Name: "test"}
jsonData, _ := json.Marshal(payload)
req, err := http.NewRequest("POST", "https://api.example.com/users", bytes.NewBuffer(jsonData))
if err != nil {
log.Fatal(err)
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()Question 15
How do you handle CORS in Go HTTP server?
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}Question 16
How do you implement routing with parameters?
// Using gorilla/mux
r := mux.NewRouter()
r.HandleFunc("/users/{id}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
fmt.Fprintf(w, "User ID: %s", id)
}).Methods("GET")
r.HandleFunc("/users/{id}/posts/{postId}", func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userId := vars["id"]
postId := vars["postId"]
fmt.Fprintf(w, "User %s, Post %s", userId, postId)
})
http.ListenAndServe(":8080", r)Question 17
How do you handle file uploads in HTTP?
func uploadHandler(w http.ResponseWriter, r *http.Request) {
// Parse multipart form
err := r.ParseMultipartForm(32 << 20) // 32 MB max
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
file, header, err := r.FormFile("file")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
// Create destination file
dst, err := os.Create(header.Filename)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer dst.Close()
// Copy file data
io.Copy(dst, file)
fmt.Fprintf(w, "File %s uploaded successfully", header.Filename)
}Question 18
How do you implement HTTP redirects?
func redirectHandler(w http.ResponseWriter, r *http.Request) {
// Temporary redirect
http.Redirect(w, r, "/new-location", http.StatusFound)
// Or manual redirect
// w.Header().Set("Location", "/new-location")
// w.WriteHeader(http.StatusFound)
}
func permanentRedirectHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/permanent-location", http.StatusMovedPermanently)
}Question 19
How do you handle HTTP cookies?
func setCookieHandler(w http.ResponseWriter, r *http.Request) {
cookie := &http.Cookie{
Name: "session",
Value: "abc123",
Path: "/",
MaxAge: 3600, // 1 hour
HttpOnly: true,
Secure: true,
}
http.SetCookie(w, cookie)
fmt.Fprintf(w, "Cookie set")
}
func getCookieHandler(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("session")
if err != nil {
http.Error(w, "Cookie not found", http.StatusBadRequest)
return
}
fmt.Fprintf(w, "Cookie value: %s", cookie.Value)
}Question 20
How do you implement a REST API in Go?
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
var users = make(map[int]User)
var nextID = 1
func getUsersHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
}
func createUserHandler(w http.ResponseWriter, r *http.Request) {
var user User
json.NewDecoder(r.Body).Decode(&user)
user.ID = nextID
nextID++
users[user.ID] = user
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(user)
}
func main() {
http.HandleFunc("/users", getUsersHandler) // GET
http.HandleFunc("/users", createUserHandler) // POST (same path, different method)
http.ListenAndServe(":8080", nil)
}Question 21
How do you handle request context and timeouts?
func timeoutHandler(w http.ResponseWriter, r *http.Request) {
// Create context with timeout
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second)
defer cancel()
// Replace request context
r = r.WithContext(ctx)
// Simulate slow operation
select {
case <-time.After(10 * time.Second):
fmt.Fprintf(w, "Completed")
case <-ctx.Done():
http.Error(w, "Request timeout", http.StatusRequestTimeout)
return
}
}Question 22
How do you implement HTTP client with custom headers?
req, err := http.NewRequest("GET", "https://api.example.com/data", nil)
if err != nil {
log.Fatal(err)
}
// Set headers
req.Header.Set("Authorization", "Bearer token123")
req.Header.Set("User-Agent", "MyApp/1.0")
req.Header.Set("Accept", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// Handle responseQuestion 23
How do you handle streaming responses?
func streamHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Header().Set("Transfer-Encoding", "chunked")
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming not supported", http.StatusInternalServerError)
return
}
for i := 0; i < 10; i++ {
fmt.Fprintf(w, "Chunk %d\n", i)
flusher.Flush() // Send chunk immediately
time.Sleep(time.Second)
}
}Question 24
How do you validate JSON input in HTTP handlers?
type CreateUserRequest struct {
Name string `json:"name" validate:"required,min=2,max=50"`
Email string `json:"email" validate:"required,email"`
Age int `json:"age" validate:"min=18,max=120"`
}
func createUserHandler(w http.ResponseWriter, r *http.Request) {
var req CreateUserRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
// Basic validation
if req.Name == "" {
http.Error(w, "Name is required", http.StatusBadRequest)
return
}
if !strings.Contains(req.Email, "@") {
http.Error(w, "Invalid email", http.StatusBadRequest)
return
}
// Use validated data
createUser(req)
w.WriteHeader(http.StatusCreated)
}Question 25
How do you implement rate limiting in HTTP server?
var requestCount = make(map[string]int)
var requestTime = make(map[string]time.Time)
var mu sync.Mutex
func rateLimitMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
defer mu.Unlock()
clientIP := r.RemoteAddr
now := time.Now()
// Reset count if window passed
if now.Sub(requestTime[clientIP]) > time.Minute {
requestCount[clientIP] = 0
requestTime[clientIP] = now
}
if requestCount[clientIP] >= 10 { // 10 requests per minute
http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
return
}
requestCount[clientIP]++
next.ServeHTTP(w, r)
})
}Question 26
How do you handle HTTPS in Go HTTP server?
func main() {
// For self-signed certs (development)
http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
// Or redirect HTTP to HTTPS
go func() {
http.ListenAndServe(":80", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "https://"+r.Host+r.URL.Path, http.StatusMovedPermanently)
}))
}()
http.ListenAndServeTLS(":443", "server.crt", "server.key", nil)
}Question 27
How do you implement graceful shutdown in HTTP server?
func main() {
srv := &http.Server{
Addr: ":8080",
Handler: http.DefaultServeMux,
}
// Channel to listen for interrupt signal
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
log.Println("Shutting down server...")
// Create context with timeout
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
// Graceful shutdown
srv.Shutdown(ctx)
os.Exit(0)
}()
log.Println("Server starting on :8080")
srv.ListenAndServe()
}Question 28
How do you handle form data in HTTP requests?
func formHandler(w http.ResponseWriter, r *http.Request) {
// Parse form data
if err := r.ParseForm(); err != nil {
http.Error(w, "Failed to parse form", http.StatusBadRequest)
return
}
// Get form values
name := r.Form.Get("name")
email := r.Form.Get("email")
// Get multiple values
hobbies := r.Form["hobby"] // []string
// Handle file uploads if multipart
if err := r.ParseMultipartForm(32 << 20); err == nil {
file, _, err := r.FormFile("avatar")
if err == nil {
defer file.Close()
// Handle uploaded file
}
}
fmt.Fprintf(w, "Name: %s, Email: %s", name, email)
}Question 29
How do you implement HTTP client connection pooling?
transport := &http.Transport{
MaxIdleConns: 100,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 90 * time.Second,
}
client := &http.Client{
Transport: transport,
Timeout: 30 * time.Second,
}
// Use client for requests
resp, err := client.Get("https://api.example.com")
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()Question 30
How do you handle HTTP status codes properly?
func apiHandler(w http.ResponseWriter, r *http.Request) {
data, err := fetchData(r.URL.Query().Get("id"))
if err != nil {
if errors.Is(err, ErrNotFound) {
http.Error(w, "Not found", http.StatusNotFound)
return
}
if errors.Is(err, ErrUnauthorized) {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK) // Explicit 200
json.NewEncoder(w).Encode(data)
}Question 31
How do you implement a simple HTTP proxy?
func proxyHandler(w http.ResponseWriter, r *http.Request) {
// Remove hop-by-hop headers
r.Header.Del("Proxy-Authenticate")
r.Header.Del("Proxy-Authorization")
r.Header.Del("TE")
r.Header.Del("Trailers")
r.Header.Del("Transfer-Encoding")
r.Header.Del("Upgrade")
// Create new request to target
targetURL := "https://api.example.com" + r.URL.Path
proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Copy headers
for key, values := range r.Header {
for _, value := range values {
proxyReq.Header.Add(key, value)
}
}
// Make request
client := &http.Client{}
resp, err := client.Do(proxyReq)
if err != nil {
http.Error(w, err.Error(), http.StatusBadGateway)
return
}
defer resp.Body.Close()
// Copy response
for key, values := range resp.Header {
for _, value := range values {
w.Header().Add(key, value)
}
}
w.WriteHeader(resp.StatusCode)
io.Copy(w, resp.Body)
}Question 32
How do you handle large request bodies?
func uploadHandler(w http.ResponseWriter, r *http.Request) {
// Limit request body size
r.Body = http.MaxBytesReader(w, r.Body, 10<<20) // 10MB limit
// For multipart forms
if err := r.ParseMultipartForm(32 << 20); err != nil {
http.Error(w, "Request too large", http.StatusRequestEntityTooLarge)
return
}
// Handle file
file, header, err := r.FormFile("upload")
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
defer file.Close()
// Process file in chunks to avoid loading in memory
buffer := make([]byte, 4096)
for {
n, err := file.Read(buffer)
if n > 0 {
// Process chunk
processChunk(buffer[:n])
}
if err == io.EOF {
break
}
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
fmt.Fprintf(w, "File uploaded successfully")
}Question 33
How do you implement content negotiation?
func apiHandler(w http.ResponseWriter, r *http.Request) {
accept := r.Header.Get("Accept")
if strings.Contains(accept, "application/json") {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"format": "json"})
} else if strings.Contains(accept, "application/xml") {
w.Header().Set("Content-Type", "application/xml")
fmt.Fprintf(w, "<response><format>xml</format></response>")
} else {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, "Default response")
}
}Question 34
How do you handle WebSocket connections in HTTP server?
import "github.com/gorilla/websocket"
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // Allow all origins for demo
},
}
func wsHandler(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Failed to upgrade:", err)
return
}
defer conn.Close()
for {
messageType, message, err := conn.ReadMessage()
if err != nil {
log.Println("Read error:", err)
break
}
log.Printf("Received: %s", message)
// Echo message back
err = conn.WriteMessage(messageType, message)
if err != nil {
log.Println("Write error:", err)
break
}
}
}Question 35
How do you implement pagination in REST APIs?
type PaginatedResponse struct {
Data []User `json:"data"`
Page int `json:"page"`
PerPage int `json:"per_page"`
Total int `json:"total"`
TotalPages int `json:"total_pages"`
}
func getUsersHandler(w http.ResponseWriter, r *http.Request) {
// Parse query parameters
pageStr := r.URL.Query().Get("page")
perPageStr := r.URL.Query().Get("per_page")
page := 1
perPage := 10
if p, err := strconv.Atoi(pageStr); err == nil && p > 0 {
page = p
}
if pp, err := strconv.Atoi(perPageStr); err == nil && pp > 0 && pp <= 100 {
perPage = pp
}
// Calculate offset
offset := (page - 1) * perPage
// Fetch data with limit and offset
users, total := getUsersWithPagination(offset, perPage)
totalPages := (total + perPage - 1) / perPage // Ceiling division
response := PaginatedResponse{
Data: users,
Page: page,
PerPage: perPage,
Total: total,
TotalPages: totalPages,
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}Question 36
How do you handle HTTP request logging?
func loggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
// Create response writer wrapper to capture status code
wrapped := &responseWriter{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(wrapped, r)
duration := time.Since(start)
log.Printf("%s %s %d %v %s",
r.Method,
r.URL.Path,
wrapped.statusCode,
duration,
r.RemoteAddr)
})
}
type responseWriter struct {
http.ResponseWriter
statusCode int
}
func (rw *responseWriter) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}Question 37
How do you implement API versioning?
func main() {
// URL-based versioning
http.HandleFunc("/api/v1/users", v1UsersHandler)
http.HandleFunc("/api/v2/users", v2UsersHandler)
// Header-based versioning
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
version := r.Header.Get("API-Version")
if version == "v2" {
v2UsersHandler(w, r)
} else {
v1UsersHandler(w, r) // default
}
})
// Accept header versioning
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
accept := r.Header.Get("Accept")
if strings.Contains(accept, "application/vnd.myapp.v2+json") {
w.Header().Set("Content-Type", "application/vnd.myapp.v2+json")
v2UsersHandler(w, r)
} else {
w.Header().Set("Content-Type", "application/vnd.myapp.v1+json")
v1UsersHandler(w, r)
}
})
http.ListenAndServe(":8080", nil)
}Question 38
How do you handle database connections in HTTP handlers?
var db *sql.DB
func init() {
var err error
db, err = sql.Open("postgres", "conn_string")
if err != nil {
log.Fatal(err)
}
// Configure connection pool
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)
}
func userHandler(w http.ResponseWriter, r *http.Request) {
// Use database
rows, err := db.Query("SELECT id, name FROM users WHERE active = $1", true)
if err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
defer rows.Close()
var users []User
for rows.Next() {
var user User
if err := rows.Scan(&user.ID, &user.Name); err != nil {
http.Error(w, "Database error", http.StatusInternalServerError)
return
}
users = append(users, user)
}
json.NewEncoder(w).Encode(users)
}Question 39
How do you implement caching in HTTP responses?
func cacheMiddleware(next http.Handler) http.Handler {
cache := make(map[string]*cacheEntry)
var mu sync.RWMutex
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
key := r.Method + r.URL.Path
mu.RLock()
entry, exists := cache[key]
mu.RUnlock()
if exists && time.Now().Before(entry.expires) {
// Return cached response
for k, v := range entry.headers {
w.Header()[k] = v
}
w.WriteHeader(entry.statusCode)
w.Write(entry.body)
return
}
// Capture response
wrapped := &cacheResponseWriter{ResponseWriter: w}
next.ServeHTTP(wrapped, r)
// Cache response
mu.Lock()
cache[key] = &cacheEntry{
statusCode: wrapped.statusCode,
headers: make(map[string][]string),
body: wrapped.body.Bytes(),
expires: time.Now().Add(5 * time.Minute),
}
for k, v := range wrapped.Header() {
cache[key].headers[k] = v
}
mu.Unlock()
})
}
type cacheEntry struct {
statusCode int
headers map[string][]string
body []byte
expires time.Time
}
type cacheResponseWriter struct {
http.ResponseWriter
statusCode int
body *bytes.Buffer
}
func (w *cacheResponseWriter) WriteHeader(code int) {
w.statusCode = code
w.ResponseWriter.WriteHeader(code)
}
func (w *cacheResponseWriter) Write(data []byte) (int, error) {
if w.body == nil {
w.body = &bytes.Buffer{}
}
w.body.Write(data)
return w.ResponseWriter.Write(data)
}Question 40
What is the most important principle for HTTP APIs in Go?
