Interview Q&A · 13 questions · 8 answered publicly

Go Web Frameworks Interview Questions

Ordered by how often they're asked. Sign in free to see every answer, rate your confidence and run timed mock interviews.

  1. Most asked What is the http.Handler interface, and why is it central to Go web development?

    Summary

    http.Handler has one method, ServeHTTP(http.ResponseWriter, *http.Request). Routers, middleware, frameworks and servers all speak this interface, so pieces compose freely.

    Longer Answer

    http.HandlerFunc adapts a plain function to the interface. Middleware are functions func(http.Handler) http.Handler. Because Chi, Gin and Echo engines are themselves http.Handlers, they run under http.Server, test with httptest, and can host standard middleware.

    Code Example

    func logging(next http.Handler) http.Handler {
    	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    		log.Println(r.Method, r.URL.Path)
    		next.ServeHTTP(w, r)
    	})
    }
    

    Key Points

    • One method: ServeHTTP.
    • HandlerFunc adapts functions.
    • Middleware wrap handlers.
    • Frameworks are Handlers too (except Fiber).

    Deep dive: Go Web Frameworks: Start with net/http

    Permalink

  2. Most asked Compare Gin, Echo, Chi and Fiber.

    Summary

    Chi is a net/http-compatible router; Gin is the most popular framework with its own Context and tag-based binding; Echo is similar but handlers return errors handled centrally; Fiber is Express-like and built on fasthttp, so it isn't net/http compatible.

    Longer Answer

    Choose by needs and team: standard-library style and no lock-in (Chi), ecosystem and familiarity (Gin), centralised error handling (Echo), Express ergonomics or extreme throughput with simple handlers (Fiber). Router speed rarely matters compared with database time. Keep business logic framework-free either way.

    Key Points

    • Chi: router, standard handlers.
    • Gin: popular, binding/validation.
    • Echo: handlers return errors.
    • Fiber: fasthttp, not net/http.

    Deep dive: Go Web Frameworks: Choosing a Go Framework

    Permalink

  3. Most asked How do you test HTTP handlers in Go?

    Summary

    Use net/http/httptest: build a request with httptest.NewRequest, a recorder with httptest.NewRecorder, call router.ServeHTTP(rec, req), and assert on status, headers and body, usually in table-driven tests with t.Run.

    Longer Answer

    Inject dependencies via interfaces so tests use fakes. Run with go test -race ./.... Keep a few integration tests against a real database (e.g. in a container). Fiber apps use app.Test(req) instead.

    Key Points

    • httptest recorder, no server needed.
    • Table-driven subtests.
    • Interfaces + fakes; -race in CI.

    Deep dive: Go Web Frameworks: Testing Go APIs

    Permalink

  4. Most asked How should a Go service use database/sql correctly?

    Summary

    Open one *sql.DB (a concurrency-safe pool) at startup and share it, configure pool limits, always use placeholders, pass contexts to every query, close rows, check rows.Err(), and translate sql.ErrNoRows to a domain 'not found' error.

    Longer Answer

    Use transactions (BeginTx, defer tx.Rollback(), Commit) for multi-step changes, and conditional updates or row locks to prevent check-then-act races. Libraries such as sqlx, sqlc or GORM sit on top; hide them behind a repository interface.

    Key Points

    • One pool, shared.
    • Placeholders and contexts.
    • Close rows; handle ErrNoRows.
    • Transactions for multi-step changes.

    Deep dive: Go Web Frameworks: Database Access

    Permalink

  5. Most asked How do you implement graceful shutdown for a Go HTTP server?

    Summary

    Listen for SIGINT/SIGTERM (signal.NotifyContext), then call server.Shutdown(ctx) with a timeout: it stops accepting new connections and waits for in-flight requests to finish before returning.

    Longer Answer

    Also close other resources (database pools, message consumers) after the server drains, and fail readiness checks at the start of shutdown so load balancers stop sending traffic.

    Code Example

    ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
    defer stop()
    go srv.ListenAndServe()
    <-ctx.Done()
    shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    srv.Shutdown(shutdownCtx)
    

    Key Points

    • signal.NotifyContext for SIGTERM.
    • server.Shutdown(ctx) drains requests.
    • Close resources after; fail readiness first.

    Deep dive: Go Web Frameworks: Production Ready

    Permalink

  6. Most asked Do you need a web framework in Go? What does Go 1.22's ServeMux provide?

    Summary

    Often not. Since Go 1.22, http.ServeMux matches methods and path wildcards ("GET /books/{id}", read with r.PathValue), returns 405 for wrong methods, and prefers more specific patterns.

    Longer Answer

    Frameworks still add route groups, request binding and validation, centralised error handling and helper APIs. Small services and libraries often stay on the standard library for zero dependencies and long-term stability; larger APIs may prefer Chi, Gin or Echo for ergonomics.

    Key Points

    • Method + wildcard routing since 1.22.
    • 405 handling built in.
    • Frameworks add groups, binding, validation, errors.

    Deep dive: Go Web Frameworks: Start with net/http

    Permalink

  7. Most asked How do you pass request-scoped values (like the current user) through middleware in Go?

    Summary

    Store them in the request's context with context.WithValue, using an unexported key type to avoid collisions, pass r.WithContext(ctx) to the next handler, and read them with a typed helper.

    Longer Answer

    Frameworks offer equivalents (c.Set/c.Get in Gin, c.Set in Echo, c.Locals in Fiber), but context.Context is what you should pass into services and repositories so cancellation and deadlines flow through too. Don't use context values for optional function parameters.

    Code Example

    type ctxKey int
    const userKey ctxKey = 0
    
    func UserFrom(ctx context.Context) (string, bool) {
    	u, ok := ctx.Value(userKey).(string)
    	return u, ok
    }
    

    Key Points

    • context.WithValue + private key type.
    • Typed accessor helper.
    • Pass ctx into services for cancellation.

    Deep dive: Go Web Frameworks: Middleware

    Permalink

  8. Most asked How do you design consistent error responses in a Go API?

    Summary

    Define one API error type (status, machine-readable code, message, optional field errors), one function that writes it, and map domain errors to it in one place; unexpected errors become a generic 500 while the real cause is logged.

    Longer Answer

    Use errors.Is/As to map sentinel and typed domain errors (ErrNotFound → 404, ErrConflict → 409). Echo's central HTTPErrorHandler is built for this; in other frameworks, write a helper or middleware. RFC 9457 (Problem Details) is a standard format to consider.

    Key Points

    • One error type and writer.
    • Map domain errors centrally.
    • Never leak internals.

    Deep dive: Go Web Frameworks: Validation and Errors

    Permalink

  9. How does request validation work in Gin?
  10. Which http.Server timeouts should you set, and why?
  11. Why must you copy values from a Fiber context that outlive the request?
  12. Compare GORM, sqlx and sqlc.
  13. What is log/slog and why use it?

Was this page helpful?