web

package
v0.0.0-...-5808e3a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 16, 2025 License: BSD-2-Clause Imports: 14 Imported by: 0

Documentation

Overview

Package web contains common utilities to help build backend Go web servers. This package is heavily opinionated and designed to work with stacks using go-chi and gorm.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrNotFound = errors.New("not found")
View Source
var ErrStreamingUnsupported = errors.New("streaming unsupported")

ErrStreamingUnsupported indicates the client connection does not support streaming

Functions

func DBErrorResponse

func DBErrorResponse(w http.ResponseWriter, err error)

DBErrorResponse returns either a 404 or 500 response based on the given error.

func MetricsMiddleware

func MetricsMiddleware(next http.Handler) http.Handler

MetricsMiddleware is an HTTP middleware that tracks chi/v5 requests with Prometheus

Example
rtr := chi.NewRouter()
rtr.Use(web.MetricsMiddleware)
rtr.Get("/", func(w http.ResponseWriter, r *http.Request) {
	w.WriteHeader(http.StatusNoContent)
})
rtr.Handle("/metrics", promhttp.Handler())

// Execute a request so we increment our metrics
r := httptest.NewRequest("GET", "http://example.com/", nil)
w := httptest.NewRecorder()
rtr.ServeHTTP(w, r)

// Fetch the latest prometheus metrics
r = httptest.NewRequest("GET", "http://example.com/metrics", nil)
w = httptest.NewRecorder()
rtr.ServeHTTP(w, r)

// Parse the response in expfmt
resp := w.Result()
var parser expfmt.TextParser
mf, err := parser.TextToMetricFamilies(resp.Body)
if err != nil {
	panic(err)
}

entry, ok := mf["go_http_request_count"]
if !ok {
	panic("go_http_request_count metric not found in prom response")
}
fmt.Printf("%s %0.0f\n", *entry.Metric[0].Label[2].Value, *entry.Metric[0].Counter.Value)
Output:

204 1

Types

type LongPollResponse

type LongPollResponse struct {
	Done chan struct{}
	// contains filtered or unexported fields
}

LongPollResponse handles the lifecycle of a long-polled HTTP response

func NewLongPollResponse

func NewLongPollResponse(context context.Context, w http.ResponseWriter) (*LongPollResponse, error)

NewLongPollResponse creates a new LongPollResponse for the given context and ResponseWriter

func (*LongPollResponse) Write

func (s *LongPollResponse) Write(data []byte) error

Write writes the raw bytes to the client connection

func (*LongPollResponse) WriteJSON

func (s *LongPollResponse) WriteJSON(data any) error

WriteJSON writes the given payload to the client connection

type Middleware

type Middleware func(http.Handler) http.Handler

func MakeURLParamMiddleware

func MakeURLParamMiddleware[T any](param string, getter func(value string) (*T, error)) (Middleware, func(r *http.Request) *T)
Example
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/alioygur/gores"
	"github.com/b1naryth1ef/sheath/web"
	"github.com/go-chi/chi/v5"
)

type User struct {
	Id       string
	Username string
}

var userMiddleware, getRequestUser = web.MakeURLParamMiddleware("user", func(value string) (*User, error) {
	return &User{Id: value, Username: "Test"}, nil
})

func main() {
	rtr := chi.NewRouter()
	rtr.With(userMiddleware).Get("/user/{user}", func(w http.ResponseWriter, r *http.Request) {
		gores.JSON(w, http.StatusOK, getRequestUser(r))
	})

	r := httptest.NewRequest("GET", "http://example.com/user/test", nil)
	w := httptest.NewRecorder()
	rtr.ServeHTTP(w, r)

	resp := w.Result()
	var result User
	err := json.NewDecoder(resp.Body).Decode(&result)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s / %s", result.Id, result.Username)
}
Output:

test / Test

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL