Golang / GoLang Production Patterns and Web Standards Interview Questions
What are the conventions for returning structured error responses from a Go REST API?
A consistent error response format makes APIs predictable for clients. The RFC 7807 (Problem Details for HTTP APIs) standard provides a widely adopted structure. Go implementations typically define a consistent JSON error envelope.
// RFC 7807-inspired error envelope type ProblemDetail struct { Type string `json:"type"` // URI identifying the problem type Title string `json:"title"` // short human-readable summary Status int `json:"status"` // HTTP status code Detail string `json:"detail"` // human-readable explanation Instance string `json:"instance"` // URI of the specific occurrence // Extension fields Errors map[string]string `json:"errors,omitempty"` // field-level errors TraceID string `json:"trace_id,omitempty"` } // Constructor helpers func notFound(detail, instance string) *ProblemDetail { return &ProblemDetail{ Type: "https://api.example.com/errors/not-found", Title: "Resource Not Found", Status: http.StatusNotFound, Detail: detail, Instance: instance, } } func validationError(errs map[string]string) *ProblemDetail { return &ProblemDetail{ Type: "https://api.example.com/errors/validation", Title: "Validation Failed", Status: http.StatusUnprocessableEntity, Detail: "One or more fields failed validation", Errors: errs, } } // Middleware: attach trace ID to all error responses func errorResponseMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/problem+json") next.ServeHTTP(w, r) }) } // Usage in handler user, err := svc.FindUser(r.Context(), id) if errors.Is(err, ErrNotFound) { prob := notFound( fmt.Sprintf("user with id %d does not exist", id), r.URL.Path, ) w.Header().Set("Content-Type", "application/problem+json") w.WriteHeader(prob.Status) json.NewEncoder(w).Encode(prob) return }
More Related questions...