Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

urls

A package for type safe URL routes.

API docs

Go Reference

Usage

-- routes.go --
import "github.com/kron4eg/urls"

var (
	Index      = urls.Route("/")
	Posts      = urls.Route("/posts")
	PostDetail = urls.TypedRoute[PostDetailParams]{
		Pattern: urls.Route("/posts/{id}"),
		Build: func(r urls.Route, p PostDetailParams) urls.Route {
			return r.Bind(urls.PathParams{"id": strconv.Itoa(p.ID)})
		},
	}
)

// PostDetailParams are the typed parameters for the PostDetail route.
type PostDetailParams struct {
	ID int
}

-- server.go --
func newMux() *http.ServerMux {
	mux := http.NewServeMux()
	mux.HandleFunc(Index.String(), http.HandlerFunc(IndexHandler))
	mux.HandleFunc(Posts.String(), http.HandlerFunc(PostsHandler))
	mux.HandleFunc(PostDetail.Pattern.String(), http.HandlerFunc(PostDetailHandler))
}

-- handlers.go --
func IndexHandler(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, Posts.URL(), http.StatusFound)
}

func PostsHandler(w http.ResponseWriter, r *http.Request) {
	// look Ma, no string literals in revers URLs
	typesafePost42URL := PostDetail.With(PostDetailParams{ID: 42}).URL()
	http.Redirect(w, r, typesafePost42URL, http.StatusFound)
}

func PostDetailHandler(w http.ResponseWriter, r *http.Request) {
	postID := r.PathValue("id")
	post := getPost(postID)
	render(w, "post.html", post)
}

Route.URL — query string building

route := urls.Route("/search")
fmt.Println(route.URL(url.Values{"q": {"hello world"}, "page": {"2"}}))
// "/search?page=2&q=hello+world"

// Multiple Values can be merged:
fmt.Println(route.URL(
    url.Values{"q": {"hello"}},
    url.Values{"page": {"2"}},
))
// "/search?page=2&q=hello"

TypedRoute — typed parameter binding

type Params struct {
    Org  string
    Repo string
}

repoRoute := urls.TypedRoute[Params]{
    Pattern: urls.Route("/orgs/{org}/repos/{repo}"),
    Build: func(r urls.Route, p Params) urls.Route {
        return r.Bind(urls.PathParams{"org": p.Org, "repo": p.Repo})
    },
}

fmt.Println(repoRoute.With(Params{Org: "golang", Repo: "go"}))
// "/orgs/golang/repos/go"

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages