routing

package
v1.25.0-118.0 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2024 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package routing provides utilities to define a number of Route instances, which can be...

  1. Used by servers to...

    1.a. Register with github.com/gorilla/mux.Router instances via the Route.Representation method.

    1.b. Deserialize HTTP path variables into a struct with the Route.Deserialize method.

  2. Used by clients to construct HTTP paths for requests by calling the Route.Path method.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Constant

func Constant[T any](values ...string) constant[T]

Constant returns a Component that represents a series of constant HTTP path components in a Route. They will be joined via strings when used to construct a path or path representation.

Example
package main

import (
	"fmt"

	"go.temporal.io/server/common/routing"
)

type QualifiedWorkflow struct {
	Namespace  string
	WorkflowID string
}

func main() {
	fmt.Println(routing.Constant[QualifiedWorkflow]("api", "v1", "namespaces").Representation())
}
Output:

api/v1/namespaces

func StringVariable

func StringVariable[T any](name string, getter func(*T) *string) stringVariable[T]

StringVariable returns a Component that represents a string variable in a Route.

Example
package main

import (
	"fmt"

	"go.temporal.io/server/common/routing"
)

type QualifiedWorkflow struct {
	Namespace  string
	WorkflowID string
}

func main() {
	fmt.Println(routing.StringVariable("namespace", func(params *QualifiedWorkflow) *string { return &params.Namespace }).Representation())
}
Output:

{namespace}

Types

type Component

type Component[T any] interface {
	// Representation is the string representation of the component for usage in a path definition, e.g. "v1" for a
	// constant slug or "{namespace}" for a variable. This should be compatible with the format specified in
	// the [github.com/gorilla/mux] package.
	Representation() string
	// Serialize returns the actual value of the slug when used in an HTTP path, e.g. "v1" for a constant slug or
	// "test-namespace" for a variable.
	Serialize(params T) string
	// Deserialize mutates the given params object with the value of the component when parsing an HTTP path, e.g.
	// setting the value of a variable to "test-namespace". If the component is a constant slug, this method should
	// be a no-op.
	Deserialize(vars map[string]string, t *T)
}

Component represents a single HTTP path component, either a constant slug or a variable parameter.

type Route

type Route[T any] struct {
	// contains filtered or unexported fields
}

Route represents a series of HTTP path components.

Example
package main

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

	"github.com/gorilla/mux"
	"go.temporal.io/server/common/routing"
)

type QualifiedWorkflow struct {
	Namespace  string
	WorkflowID string
}

func main() {
	route := routing.NewBuilder[QualifiedWorkflow]().
		Constant("api", "v1", "namespaces").
		StringVariable("namespace", func(params *QualifiedWorkflow) *string { return &params.Namespace }).
		Constant("workflows").
		StringVariable("workflowID", func(params *QualifiedWorkflow) *string { return &params.WorkflowID }).
		Build()
	router := mux.NewRouter()
	router.HandleFunc("/"+route.Representation(), func(w http.ResponseWriter, r *http.Request) {
		params := route.Deserialize(mux.Vars(r))
		_, _ = fmt.Fprintf(w, "Namespace: %s, WorkflowID: %s\n", params.Namespace, params.WorkflowID)
	})
	recorder := httptest.NewRecorder()
	u := "http://localhost/" + route.Path(QualifiedWorkflow{
		Namespace:  "TEST-NAMESPACE",
		WorkflowID: "TEST-WORKFLOW-ID",
	})
	router.ServeHTTP(recorder, httptest.NewRequest("GET", u, nil))
	fmt.Println(recorder.Code)
	fmt.Println(recorder.Body.String())
}
Output:

200
Namespace: TEST-NAMESPACE, WorkflowID: TEST-WORKFLOW-ID

func NewRoute

func NewRoute[T any](components ...Component[T]) Route[T]

NewRoute returns a new Route instance with the given components.

func (Route[T]) Deserialize

func (r Route[T]) Deserialize(vars map[string]string) T

Deserialize the given vars into a new instance of the params type, T.

Example
package main

import (
	"fmt"

	"go.temporal.io/server/common/routing"
)

type QualifiedWorkflow struct {
	Namespace  string
	WorkflowID string
}

func newWorkflowRoute() routing.Route[QualifiedWorkflow] {
	return routing.NewBuilder[QualifiedWorkflow]().
		Constant("api", "v1", "namespaces").
		StringVariable("namespace", func(params *QualifiedWorkflow) *string { return &params.Namespace }).
		Constant("workflows").
		StringVariable("workflowID", func(params *QualifiedWorkflow) *string { return &params.WorkflowID }).
		Build()
}

func main() {
	route := newWorkflowRoute()
	// Would usually be mux.Vars(r) in a real application
	vars := map[string]string{
		"namespace":  "TEST-NAMESPACE",
		"workflowID": "TEST-WORKFLOW-ID",
	}
	params := route.Deserialize(vars)
	fmt.Println(params.Namespace)
	fmt.Println(params.WorkflowID)
}
Output:

TEST-NAMESPACE
TEST-WORKFLOW-ID

func (Route[T]) Path

func (r Route[T]) Path(t T) string

Path returns the serialized path of the route with the given params. There will be no leading or trailing slashes, similar to the behavior of the Route.Representation method.

Example
package main

import (
	"fmt"

	"go.temporal.io/server/common/routing"
)

type QualifiedWorkflow struct {
	Namespace  string
	WorkflowID string
}

func newWorkflowRoute() routing.Route[QualifiedWorkflow] {
	return routing.NewBuilder[QualifiedWorkflow]().
		Constant("api", "v1", "namespaces").
		StringVariable("namespace", func(params *QualifiedWorkflow) *string { return &params.Namespace }).
		Constant("workflows").
		StringVariable("workflowID", func(params *QualifiedWorkflow) *string { return &params.WorkflowID }).
		Build()
}

func main() {
	route := newWorkflowRoute()
	params := QualifiedWorkflow{Namespace: "TEST-NAMESPACE", WorkflowID: "TEST-WORKFLOW-ID"}
	fmt.Println(route.Path(params))
}
Output:

api/v1/namespaces/TEST-NAMESPACE/workflows/TEST-WORKFLOW-ID

func (Route[T]) Representation

func (r Route[T]) Representation() string

Representation returns the github.com/gorilla/mux compatible string representation of the route for usage in a path definition. It does not add a leading or trailing slash to the representation, but it won't remove them if they're present in the components. We do this because it's easier to add a slash depending on the context than to remove it.

Example
package main

import (
	"fmt"

	"go.temporal.io/server/common/routing"
)

type QualifiedWorkflow struct {
	Namespace  string
	WorkflowID string
}

func newWorkflowRoute() routing.Route[QualifiedWorkflow] {
	return routing.NewBuilder[QualifiedWorkflow]().
		Constant("api", "v1", "namespaces").
		StringVariable("namespace", func(params *QualifiedWorkflow) *string { return &params.Namespace }).
		Constant("workflows").
		StringVariable("workflowID", func(params *QualifiedWorkflow) *string { return &params.WorkflowID }).
		Build()
}

func main() {
	route := newWorkflowRoute()
	fmt.Println(route.Representation())
}
Output:

api/v1/namespaces/{namespace}/workflows/{workflowID}

type RouteBuilder

type RouteBuilder[T any] struct {
	// contains filtered or unexported fields
}

RouteBuilder is a builder for the Route interface.

func NewBuilder

func NewBuilder[T any]() *RouteBuilder[T]

NewBuilder creates a new RouteBuilder instance, which can be used to define a new Route via a fluent API.

func (*RouteBuilder[T]) Build

func (r *RouteBuilder[T]) Build() Route[T]

Build returns a read-only Route.

func (*RouteBuilder[T]) Constant

func (r *RouteBuilder[T]) Constant(values ...string) *RouteBuilder[T]

Constant adds a Constant component to the Route.

func (*RouteBuilder[T]) StringVariable

func (r *RouteBuilder[T]) StringVariable(name string, getter func(*T) *string) *RouteBuilder[T]

StringVariable adds a StringVariable component to the Route.

func (*RouteBuilder[T]) With

func (r *RouteBuilder[T]) With(c ...Component[T]) *RouteBuilder[T]

With adds a series of Component instances to the Route.

Jump to

Keyboard shortcuts

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