Golang Networking & HTTP Quiz

Golang
0 Passed
0% acceptance

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.

40 Questions
~80 minutes
1

Question 1

How do you create a basic HTTP server in Go?

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)
}
A
Use http.HandleFunc to register handlers and http.ListenAndServe to start the server
B
Use net.Listen
C
Use fmt.Println
D
Cannot create HTTP server
2

Question 2

How do you make an HTTP GET request in Go?

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))
A
Use http.Get() and read response body with io.ReadAll
B
Use net.Dial
C
Use os.Open
D
Cannot make HTTP requests
3

Question 3

What is JSON marshalling in Go?

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]"}
A
Converting Go structs to JSON bytes using json.Marshal
B
Converting JSON to Go structs
C
Sending HTTP requests
D
No JSON in Go
4

Question 4

How do you unmarshal JSON in Go?

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)  // Bob
A
Use json.Unmarshal with []byte and pointer to struct
B
Use json.Marshal
C
Use fmt.Scanf
D
Cannot unmarshal JSON
5

Question 5

How do you handle HTTP request parameters?

go
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)
}
A
Use r.URL.Query() for GET params, r.ParseForm() for POST data
B
Use os.Args
C
Use fmt.Scan
D
Cannot handle parameters
6

Question 6

How do you set HTTP response headers?

go
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"})
}
A
Use w.Header().Set() before writing response body
B
Use r.Header.Set()
C
Use fmt.Printf
D
Cannot set headers
7

Question 7

How do you create an HTTP client with timeout?

go
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 response
A
Create http.Client with Timeout field set
B
Use http.Get with timeout
C
Use time.Sleep
D
Cannot set timeout
8

Question 8

How do you handle different HTTP methods?

go
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)
    }
}
A
Check r.Method and handle different HTTP methods accordingly
B
Use different handlers for each method
C
Use if statements
D
Cannot handle different methods
9

Question 9

How do you implement middleware in Go HTTP?

go
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)
}
A
Create functions that take and return http.Handler, wrapping calls to next.ServeHTTP
B
Use global variables
C
Use defer in handlers
D
Cannot implement middleware
10

Question 10

How do you send JSON in HTTP response?

go
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)
}
A
Set Content-Type header and use json.NewEncoder(w).Encode()
B
Use fmt.Fprintf with JSON string
C
Use io.WriteString
D
Cannot send JSON
11

Question 11

How do you parse JSON from HTTP request?

go
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)
}
A
Use json.NewDecoder(r.Body).Decode() with pointer to struct
B
Use io.ReadAll and json.Unmarshal
C
Use r.Form.Get
D
Cannot parse JSON
12

Question 12

How do you handle HTTP errors properly?

go
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)
}
A
Use http.Error() with appropriate status codes and messages
B
Use panic
C
Use log.Fatal
D
Cannot handle errors
13

Question 13

How do you implement basic authentication?

go
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)
    })
}
A
Use r.BasicAuth() to get credentials and check them in middleware
B
Use r.Header.Get("Authorization")
C
Use cookies
D
Cannot implement auth
14

Question 14

How do you make POST requests with JSON body?

go
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()
A
Use http.NewRequest with POST method, JSON body, and set Content-Type header
B
Use http.Post
C
Use http.Get
D
Cannot make POST requests
15

Question 15

How do you handle CORS in Go HTTP server?

go
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)
    })
}
A
Set CORS headers in middleware and handle preflight OPTIONS requests
B
Use net/http automatically
C
Use html/template
D
Cannot handle CORS
16

Question 16

How do you implement routing with parameters?

go
// 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)
A
Use third-party routers like gorilla/mux with parameterized paths
B
Use http.HandleFunc with regex
C
Use strings.Split on r.URL.Path
D
Cannot have parameterized routes
17

Question 17

How do you handle file uploads in HTTP?

go
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)
}
A
Use r.ParseMultipartForm() and r.FormFile() to handle uploaded files
B
Use r.Body directly
C
Use os.Open
D
Cannot handle uploads
18

Question 18

How do you implement HTTP redirects?

go
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)
}
A
Use http.Redirect() with appropriate status codes
B
Use w.Write
C
Use fmt.Printf
D
Cannot redirect
19

Question 19

How do you handle HTTP cookies?

go
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)
}
A
Use http.SetCookie() to send cookies, r.Cookie() to read them
B
Use w.Header.Set
C
Use r.Header.Get
D
Cannot handle cookies
20

Question 20

How do you implement a REST API in Go?

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)
}
A
Use different handlers for different HTTP methods on same path, handle JSON encoding/decoding
B
Use one handler for all methods
C
Use global variables
D
Cannot implement REST API
21

Question 21

How do you handle request context and timeouts?

go
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
    }
}
A
Use context.WithTimeout with r.Context() and check ctx.Done()
B
Use time.Sleep
C
Use http.Timeout
D
Cannot handle timeouts
22

Question 22

How do you implement HTTP client with custom headers?

go
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 response
A
Use http.NewRequest and set headers on req.Header
B
Use http.Get with headers
C
Use w.Header.Set
D
Cannot set custom headers
23

Question 23

How do you handle streaming responses?

go
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)
    }
}
A
Use http.Flusher to send data in chunks as it's generated
B
Use io.Copy
C
Use bufio.Writer
D
Cannot stream responses
24

Question 24

How do you validate JSON input in HTTP handlers?

go
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)
}
A
Decode JSON first, then validate fields with custom logic or validation libraries
B
Validate before decoding
C
Use json.Valid
D
Cannot validate input
25

Question 25

How do you implement rate limiting in HTTP server?

go
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)
    })
}
A
Use middleware to track requests per client and enforce limits
B
Use http.Timeout
C
Use time.Sleep
D
Cannot implement rate limiting
26

Question 26

How do you handle HTTPS in Go HTTP server?

go
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)
}
A
Use http.ListenAndServeTLS with certificate and key files
B
Use http.ListenAndServe
C
Use net.Listen
D
Cannot handle HTTPS
27

Question 27

How do you implement graceful shutdown in HTTP server?

go
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()
}
A
Use http.Server with Shutdown() method and signal handling
B
Use os.Exit directly
C
Use panic
D
Cannot shutdown gracefully
28

Question 28

How do you handle form data in HTTP requests?

go
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)
}
A
Use r.ParseForm() for application/x-www-form-urlencoded, r.ParseMultipartForm() for multipart/form-data
B
Use json.Unmarshal
C
Use r.Body directly
D
Cannot handle form data
29

Question 29

How do you implement HTTP client connection pooling?

go
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()
A
Configure http.Transport with connection pool settings
B
Use http.Get directly
C
Use sync.Pool
D
Cannot pool connections
30

Question 30

How do you handle HTTP status codes properly?

go
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)
}
A
Use appropriate HTTP status constants and set them with w.WriteHeader()
B
Use fmt.Fprintf
C
Use log.Print
D
Cannot set status codes
31

Question 31

How do you implement a simple HTTP proxy?

go
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)
}
A
Forward requests to target server, copy headers and body, handle hop-by-hop headers
B
Use http.Get
C
Use net.Dial
D
Cannot implement proxy
32

Question 32

How do you handle large request bodies?

go
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")
}
A
Use http.MaxBytesReader to limit size, process in chunks to avoid memory issues
B
Use io.ReadAll
C
Use json.Unmarshal
D
Cannot handle large bodies
33

Question 33

How do you implement content negotiation?

go
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")
    }
}
A
Check Accept header and respond with appropriate content type
B
Use r.Method
C
Use w.Header.Get
D
Cannot negotiate content
34

Question 34

How do you handle WebSocket connections in HTTP server?

go
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
        }
    }
}
A
Use websocket upgrader to upgrade HTTP connection to WebSocket
B
Use net/http only
C
Use http.ListenAndServe
D
Cannot handle WebSockets
35

Question 35

How do you implement pagination in REST APIs?

go
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)
}
A
Parse page and per_page query parameters, calculate offset, return paginated response with metadata
B
Return all data
C
Use headers for pagination
D
Cannot implement pagination
36

Question 36

How do you handle HTTP request logging?

go
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)
}
A
Use middleware with wrapped ResponseWriter to capture status codes and timing
B
Use fmt.Printf
C
Use log.Print
D
Cannot log requests
37

Question 37

How do you implement API versioning?

go
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)
}
A
Use URL paths (/api/v1/), headers (API-Version), or content negotiation (Accept)
B
Use query parameters
C
Use cookies
D
Cannot version APIs
38

Question 38

How do you handle database connections in HTTP handlers?

go
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)
}
A
Initialize database connection pool globally, use it in handlers with proper error handling
B
Open connection in each handler
C
Use global variables without pooling
D
Cannot use database in handlers
39

Question 39

How do you implement caching in HTTP responses?

go
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)
}
A
Use middleware with response caching, wrapped ResponseWriter to capture output
B
Use http.Cache
C
Use global variables
D
Cannot cache responses
40

Question 40

What is the most important principle for HTTP APIs in Go?

A
Use appropriate HTTP status codes, handle errors properly, validate input, implement timeouts, use middleware for cross-cutting concerns, follow REST conventions, document APIs clearly
B
Use GET for everything
C
Ignore errors
D
Use panic for errors

QUIZZES IN Golang