Repository: labstack/echo
File: middleware/proxy.go (Go)

Code before:
)

// TODO: Handle TLS proxy

type (
	// ProxyConfig defines the config for Proxy middleware.
	ProxyConfig struct {
		// Skipper defines a function to skip middleware.
		Skipper Skipper

		// Balancer defines a load balancing technique.
		// Required.
		Balancer ProxyBalancer

		// RetryCount defines the number of times a proxied request to an unavailable
		// ProxyTarget should be retried using the next available ProxyTarget. Defaults
		// to 0, meaning requests are never retried.
		RetryCount int

		// RetryFilter defines a function used to determine if a failed request to an
		// unavailable ProxyTarget should be retried. The RetryFilter will only be called
		// when the number of previous retries is less than RetryCount. If the function returns
		// true, the request will be retried. When not specified, DefaultProxyRetryFilter
		// will be used, which will always retry requests. A user defined ProxyRetryFilter
		// can be provided to only retry specific requests, for example only retry GET requests.
		RetryFilter ProxyRetryFilter

		// Rewrite defines URL path rewrite rules. The values captured in asterisk can be
		// retrieved by index e.g. $1, $2 and so on.
		// Examples:
		// "/old":              "/new",
		// "/api/*":            "/$1",
		// "/js/*":             "/public/javascripts/$1",
		// "/users/*/orders/*": "/user/$1/order/$2",
		Rewrite map[string]string

		// RegexRewrite defines rewrite rules using regexp.Rexexp with captures
		// Every capture group in the values can be retrieved by index e.g. $1, $2 and so on.
		// Example:
		// "^/old/[0.9]+/":     "/new",
		// "^/api/.+?/(.*)":    "/v2/$1",
		RegexRewrite map[*regexp.Regexp]string

		// Context key to store selected ProxyTarget into context.
		// Optional. Default value "target".
		ContextKey string

		// To customize the transport to remote.
		// Examples: If custom TLS certificates are required.
		Transport http.RoundTripper


Review comment (suggestion):
I propose `ErrorHandler func(err error, c echo.Context) error` instead of this.  This would open new use-cases for users - for example - customize error codes and messages that are returned.

also these function types `ProxyRetryFilter func(c echo.Context) bool` are in my personal opinion annoying as when I check what that field is - I do not see immediately that it is function with following arguments. Basically it is harder to understand code and only IDEs features like onhover tooltips help you here. For these kind, one-off fields, this is not good user experience IMO.  

Defining new types for middleware config handler/func fields does not give anything except new public type that we must support due semantic versioning.



Code after:
)

// TODO: Handle TLS proxy

type (
	// ProxyConfig defines the config for Proxy middleware.
	ProxyConfig struct {
		// Skipper defines a function to skip middleware.
		Skipper Skipper

		// Balancer defines a load balancing technique.
		// Required.
		Balancer ProxyBalancer

		// RetryCount defines the number of times a failed proxied request should be retried
		// using the next available ProxyTarget. Defaults to 0, meaning requests are never retried.
		RetryCount int

		// RetryFilter defines a function used to determine if a failed request to a
		// ProxyTarget should be retried. The RetryFilter will only be called when the number
		// of previous retries is less than RetryCount. If the function returns true, the
		// request will be retried. The provided error indicates the reason for the request
		// failure. When the ProxyTarget is unavailable, the error will be an instance of
		// echo.HTTPError with a Code of http.StatusBadGateway. In all other cases, the error
		// will indicate an internal error in the Proxy middleware. When a RetryFilter is not
		// specified, all requests that fail with http.StatusBadGateway will be retried. A custom
		// RetryFilter can be provided to only retry specific requests. Note that RetryFilter is
		// only called when the request to the target fails, or an internal error in the Proxy
		// middleware has occurred. Successful requests that return a non-200 response code cannot
		// be retried.
		RetryFilter func(c echo.Context, e error) bool

		// ErrorHandler defines a function which can be used to return custom errors from
		// the Proxy middleware. ErrorHandler is only invoked when there has been
		// either an internal error in the Proxy middleware or the ProxyTarget is
		// unavailable. Due to the way requests are proxied, ErrorHandler is not invoked
		// when a ProxyTarget returns a non-200 response. In these cases, the response
		// is already written so errors cannot be modified. ErrorHandler is only
		// invoked after all retry attempts have been exhausted.
		ErrorHandler func(c echo.Context, err error) error

		// Rewrite defines URL path rewrite rules. The values captured in asterisk can be
		// retrieved by index e.g. $1, $2 and so on.
		// Examples:
		// "/old":              "/new",
		// "/api/*":            "/$1",
		// "/js/*":             "/public/javascripts/$1",
		// "/users/*/orders/*": "/user/$1/order/$2",
		Rewrite map[string]string

		// RegexRewrite defines rewrite rules using regexp.Rexexp with captures