web

package module
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package web provides muxing router, middleware, for handling HTTP requests.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Decode

func Decode[T any](r *http.Request, val *T) error

Decode reads the body of an HTTP request looking for a JSON document. The body is decoded into the provided value. If the provided value is a struct then it is checked for validation tags. If the value implements a validate function, it is executed.

Example
package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/adamwoolhether/httper/web"
)

func main() {
	type Input struct {
		Name string `json:"name" validate:"required"`
	}

	body := strings.NewReader(`{"name":"alice"}`)
	r := httptest.NewRequest(http.MethodPost, "/", body)

	var input Input
	if err := web.Decode(r, &input); err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(input.Name)
}
Output:
alice

func DecodeAllowUnknownFields

func DecodeAllowUnknownFields[T any](r *http.Request, val *T) error

DecodeAllowUnknownFields is the same as Decode, but won't reject unknown fields.

Example
package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"strings"

	"github.com/adamwoolhether/httper/web"
)

func main() {
	type Input struct {
		Name string `json:"name" validate:"required"`
	}

	body := strings.NewReader(`{"name":"alice","extra":"ignored"}`)
	r := httptest.NewRequest(http.MethodPost, "/", body)

	var input Input
	if err := web.DecodeAllowUnknownFields(r, &input); err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(input.Name)
}
Output:
alice

func Param

func Param(r *http.Request, key string) (string, error)

Param extracts a path parameter by key and returns its string value.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	r := httptest.NewRequest(http.MethodGet, "/users/alice", nil)
	r.SetPathValue("name", "alice")

	name, err := web.Param(r, "name")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(name)
}
Output:
alice

func ParamInt

func ParamInt(r *http.Request, key string) (int, error)

ParamInt extracts a path parameter by key and parses it as an int.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	r := httptest.NewRequest(http.MethodGet, "/items/42", nil)
	r.SetPathValue("id", "42")

	id, err := web.ParamInt(r, "id")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(id)
}
Output:
42

func ParamInt64

func ParamInt64(r *http.Request, key string) (int64, error)

ParamInt64 extracts a path parameter by key and parses it as an int64.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	r := httptest.NewRequest(http.MethodGet, "/orders/9000000000", nil)
	r.SetPathValue("id", "9000000000")

	id, err := web.ParamInt64(r, "id")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(id)
}
Output:
9000000000

func QueryBool

func QueryBool(r *http.Request, key string) (bool, error)

QueryBool extracts a query parameter by key and parses it as a bool.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	r := httptest.NewRequest(http.MethodGet, "/items?active=true", nil)

	active, err := web.QueryBool(r, "active")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(active)
}
Output:
true

func QueryInt

func QueryInt(r *http.Request, key string) (int, error)

QueryInt extracts a query parameter by key and parses it as an int.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	r := httptest.NewRequest(http.MethodGet, "/items?page=3", nil)

	page, err := web.QueryInt(r, "page")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(page)
}
Output:
3

func QueryInt64

func QueryInt64(r *http.Request, key string) (int64, error)

QueryInt64 extracts a query parameter by key and parses it as an int64.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	r := httptest.NewRequest(http.MethodGet, "/items?cursor=8000000000", nil)

	cursor, err := web.QueryInt64(r, "cursor")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(cursor)
}
Output:
8000000000

func QueryString

func QueryString(r *http.Request, key string) (string, error)

QueryString extracts a query parameter by key and returns its string value.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	r := httptest.NewRequest(http.MethodGet, "/search?q=golang", nil)

	q, err := web.QueryString(r, "q")
	if err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(q)
}
Output:
golang

func Redirect

func Redirect(w http.ResponseWriter, r *http.Request, url string, code int) error

Redirect issues an HTTP redirect to the given URL. The status code must be in the 3xx range or an error is returned.

Example
package main

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

	"github.com/adamwoolhether/httper/web"
)

func main() {
	w := httptest.NewRecorder()
	r := httptest.NewRequest(http.MethodGet, "/old", nil)

	if err := web.Redirect(w, r, "/new", http.StatusMovedPermanently); err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(w.Code)
	fmt.Println(w.Header().Get("Location"))
}
Output:
301
/new

func RespondError

func RespondError(ctx context.Context, w http.ResponseWriter, err *errs.Error) error

RespondError writes a structured JSON error response using the status code and message from the given *errs.Error.

Example
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/adamwoolhether/httper/web"
	"github.com/adamwoolhether/httper/web/errs"
)

func main() {
	w := httptest.NewRecorder()

	appErr := errs.New(http.StatusNotFound, fmt.Errorf("user not found"))
	if err := web.RespondError(context.Background(), w, appErr); err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(w.Code)
	fmt.Println(w.Body.String())
}
Output:
404
{"code":404,"message":"user not found"}

func RespondJSON

func RespondJSON(ctx context.Context, w http.ResponseWriter, statusCode int, data any) error

RespondJSON to an HTTP request, setting the status code and body if any.

Example
package main

import (
	"context"
	"fmt"
	"net/http"
	"net/http/httptest"

	"github.com/adamwoolhether/httper/web"
)

func main() {
	w := httptest.NewRecorder()

	data := map[string]string{"status": "ok"}
	if err := web.RespondJSON(context.Background(), w, http.StatusOK, data); err != nil {
		fmt.Println("error:", err)
		return
	}

	fmt.Println(w.Code)
	fmt.Println(w.Body.String())
}
Output:
200
{"status":"ok"}

func Validate

func Validate(val any) error

Validate that the provided model against its declared tags.

Example
package main

import (
	"fmt"

	"github.com/adamwoolhether/httper/web"
)

func main() {
	type Input struct {
		Name  string `json:"name" validate:"required"`
		Email string `json:"email" validate:"required,email"`
	}

	input := Input{
		Name:  "alice",
		Email: "alice@example.com",
	}

	err := web.Validate(&input)
	fmt.Println(err)
}
Output:
<nil>
Example (Errors)
package main

import (
	"fmt"

	"github.com/adamwoolhether/httper/web"
	"github.com/adamwoolhether/httper/web/errs"
)

func main() {
	type Input struct {
		Name string `json:"name" validate:"required"`
	}

	err := web.Validate(&Input{})

	fe := errs.GetFieldErrors(err)
	for _, f := range fe {
		fmt.Printf("%s: %s\n", f.Field, f.Err)
	}
}
Output:
name: This field is required

Types

This section is empty.

Directories

Path Synopsis
Package errs enables error handling and definition at the http/app level.
Package errs enables error handling and definition at the http/app level.
Package middleware provides common HTTP middleware for the web application.
Package middleware provides common HTTP middleware for the web application.
Package mux provides helpers for middleware and route handling.
Package mux provides helpers for middleware and route handling.
Package server manages the HTTP server lifecycle with graceful shutdown.
Package server manages the HTTP server lifecycle with graceful shutdown.

Jump to

Keyboard shortcuts

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