standalone

package
v0.0.0-...-80a5fd7 Latest Latest
Warning

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

Go to latest
Published: Jun 4, 2024 License: MIT Imports: 27 Imported by: 0

Documentation

Overview

Package standalone provides a stand-alone HTTP handler that provides a complete gRPC web UI that includes both the web page and relevant server-side handlers. The web page includes HTML, CSS, and JS sources, which can be customized only regarding the "target" in the page header (which is intended to show the server to which RPC requests are directed). The actual list of methods exposed via the form is also customizable.

This is the same web content that the `grpcui` command-line program exposes. It starts up a web server that includes only this stand-alone handler. If you need more control over the page in which the UI form gets embedded or over the CSS/styling of the page, instead use the various functions in the "github.com/zeroflucs-given/grpcui" package to assemble your own web UI.

Note that this package bundles the JS dependencies of the web form. It provides jQuery 3.3.1 and jQuery-UI 1.12.1.

An example of using the package with a server supporting reflection:

cc, err := grpc.DialContext(ctx, "dns:///my-grpc-server:8080", grpc.WithBlock())
if err != nil {
	return err
}
h, err := standalone.HandlerViaReflection(ctx, cc, "dns:///my-grpc-server:8080")
if err != nil {
	return err
}
http.ListenAndServe(":8080", h)

An example of using the package with a supplied file descriptor set (protoset):

//go:embed:proto/contract.fds
var fileDescriptorSet []byte

cc, err := grpc.DialContext(ctx, "dns:///my-grpc-server:8080", grpc.WithBlock())
if err != nil {
	return err
}
h, err := standalone.HandlerViaFileDescriptorSet(cc, "dns:///my-grpc-server:8080", &fileDescriptorSet)
if err != nil {
	return err
}
http.ListenAndServe(":8080", h)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Handler

func Handler(ch grpcdynamic.Channel, target string, methods []*desc.MethodDescriptor, files []*desc.FileDescriptor, opts ...HandlerOption) http.Handler

Handler returns an HTTP handler that provides a fully-functional gRPC web UI, including the main index (with the HTML form), all needed CSS and JS assets, and the handlers that provide schema metadata and perform RPC invocations. The HTML index, CSS, and JS files can be customized and augmented with opts.

All RPC invocations are sent to the given channel. The given target is shown in the header of the web UI, to show the user where their requests are being sent. The given methods enumerate all supported RPC methods, and the given files enumerate all known protobuf (for enumerating all supported message types, to support the use of google.protobuf.Any messages).

The returned handler expects to serve resources from "/". If it will instead be handling a sub-path (e.g. handling "/rpc-ui/") then use http.StripPrefix.

func HandlerViaFileDescriptorSet

func HandlerViaFileDescriptorSet(cc grpc.ClientConnInterface, target string, fileDescriptorSet []byte, opts ...HandlerOption) (http.Handler, error)

HandlerViaFileDescriptorSet imports the file descriptor set (protoset), and constructs a handler to serve the UI.

The handler has the same properties as the one returned by Handler.

func HandlerViaReflection

func HandlerViaReflection(ctx context.Context, cc grpc.ClientConnInterface, target string, opts ...HandlerOption) (http.Handler, error)

HandlerViaReflection tries to query the provided connection for all services and methods supported by the server, and constructs a handler to serve the UI.

The handler has the same properties as the one returned by Handler.

Types

type Example

type Example struct {
	Name        string         `json:"name"`
	Description string         `json:"description"`
	Service     string         `json:"service"`
	Method      string         `json:"method"`
	Request     ExampleRequest `json:"request"`
}

Example model of an example gRPC request

type ExampleMetadataPair

type ExampleMetadataPair struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

ExampleMetadataPair (name, value) pair

type ExampleRequest

type ExampleRequest struct {
	TimeoutSeconds float64               `json:"timeout_secs"`
	Metadata       []ExampleMetadataPair `json:"metadata"`
	Data           interface{}           `json:"data"`
}

ExampleRequest gRPC request

func (*ExampleRequest) MarshalJSON

func (r *ExampleRequest) MarshalJSON() ([]byte, error)

type HandlerOption

type HandlerOption interface {
	// contains filtered or unexported methods
}

HandlerOption instances allow for configuration of the standalone Handler.

func AddCSS

func AddCSS(filename string, css []byte) HandlerOption

AddCSS adds a CSS file to Handler, serving the supplied contents at the URI "/s/<filename>" with a Content-Type of "text/css; charset=UTF-8". It will also be added to the AddlResources field of the WebFormContainerTemplateData so that it is rendered into the HEAD of the HTML page.

It is safe to pass in multiple AddCSS Opts to Handler. Each will be rendered in the order they are passed.

func AddCSSFile

func AddCSSFile(filename string, open func() (io.ReadCloser, error)) HandlerOption

AddCSSFile is like AddCSS except that the contents are provided in the form of a function that is used to "open" the file to read. This means that the contents of the file need not be eagerly loaded into memory. Each time a request is received for this file, the function is called.

func AddJS

func AddJS(filename string, js []byte) HandlerOption

AddJS adds a JS file to Handler, serving the supplied contents at the URI "/s/<filename>" with a Content-Type of "text/javascript; charset=UTF-8". It will also be added to the AddlResources field of the WebFormContainerTemplateData so that it is rendered into the HEAD of the HTML page.

It is safe to pass in multiple AddJS Opts to Handler. Each will be rendered in the order they are passed.

func AddJSFile

func AddJSFile(filename string, open func() (io.ReadCloser, error)) HandlerOption

AddJSFile is like AddJS except that the contents are provided in the form of a function that is used to "open" the file to read. This means that the contents of the file need not be eagerly loaded into memory. Each time a request is received for this file, the function is called.

func EmitDefaults

func EmitDefaults(emit bool) HandlerOption

EmitDefaults tells gRPCurl whether or not default values should be emitted

func PreserveHeaders

func PreserveHeaders(headerNames []string) HandlerOption

PreserveHeaders instructs the Handler to preserve the named HTTP headers if they are included in the invocation request, and send them as request metadata when invoking the RPC. If the web form includes conflicting metadata, the web form input will be ignored and the matching header value in the HTTP request will be sent instead.

func ServeAsset

func ServeAsset(filename string, contents []byte) HandlerOption

ServeAsset will add an additional file to Handler, serving the supplied contents at the URI "/s/<filename>" with a Content-Type that is computed based on the given filename's extension.

These assets could be images or other files referenced by a custom index template. Unlike files added via AddJS or AddCSS, they will NOT be provided to the template in the AddlResources field of the WebFormContainerTemplateData.

func ServeAssetDirectory

func ServeAssetDirectory(dirname string, open func(filename string) (io.ReadCloser, error)) HandlerOption

ServeAssetDirectory is similar to ServeAssetFile except the give name is the root of a subtree, which can be used to serve a directory of assets. When a request is received, the remaining relative path is provided to the open function, to indicate which path in the subtree to open. For example, if the given name is "foo/bar" and a request is made for "foo/bar/baz/buzz", then the open function will be called with "baz/buzz" as the argument.

If a given path does not exist or is a directory, not a file, the open function should return an error that can be classified via os.IsNotExist, so that the server can return a "404 Not Found" status. Any other error will result in the server sending a "500 Internal Server Error" status.

func ServeAssetFile

func ServeAssetFile(filename string, open func() (io.ReadCloser, error)) HandlerOption

ServeAssetFile is like ServeAsset except that the contents are provided in the form of a function that is used to "open" the file to read. This means that the contents of the file need not be eagerly loaded into memory. Each time a request is received for this file, the function is called.

func WithCSS

func WithCSS(css []byte) HandlerOption

WithCSS entirely replaces the WebFormCSS bytes used by default in Handler.

func WithClientDebug

func WithClientDebug(debug bool) HandlerOption

WithClientDebug enables console logging in the client JS. This prints extra information as the UI processes user input.

func WithDebug deprecated

func WithDebug(debug bool) HandlerOption

WithDebug enables console logging in the client JS. This prints extra information as the UI processes user input.

Deprecated: Use WithClientDebug instead.

func WithDefaultMetadata

func WithDefaultMetadata(headers []string) HandlerOption

WithDefaultMetadata sets the default metadata in the web form to the given values. Each string should be in the form "name: value".

func WithExampleData

func WithExampleData(data []byte) (HandlerOption, error)

WithExampleData will add examples to the UI. The given data must be valid JSON that can be unmarshalled as a []Example. If not, this function will return an error.

func WithExamples

func WithExamples(examples ...Example) (HandlerOption, error)

WithExamples will add examples to the UI. This function returns an error if it is unable to convert the given examples to JSON, which could happen if an example request message is not a valid request and contains invalid data or types (such as a channel or function).

func WithIndexTemplate

func WithIndexTemplate(tmpl *template.Template) HandlerOption

WithIndexTemplate replace the default HTML template used in Handler with the one given. The template will be provided an instance of WebFormContainerTemplateData as the data to render.

func WithInvokeVerbosity

func WithInvokeVerbosity(verbosity int) HandlerOption

WithInvokeVerbosity indicates the level of log output from the gRPC UI server handler that performs RPC invocations.

func WithMetadata

func WithMetadata(headers []string) HandlerOption

WithMetadata adds extra request metadata that will be included when an RPC in invoked. Each string should be in the form "name: value". If the web form includes conflicting metadata, the web form input will be ignored and the metadata supplied to this option will be sent instead.

type WebFormContainerTemplateData

type WebFormContainerTemplateData struct {
	// Target is the name of the machine we are making requests to (for display purposes).
	Target string

	// WebFormContents is the generated form HTML from your ServiceDescriptors.
	WebFormContents template.HTML

	// AddlResources are additional CSS and JS files, in the form of <link> and <script>
	// tags, that we want to append to the HEAD of the index template.
	AddlResources []template.HTML
}

WebFormContainerTemplateData is the param type for templates that embed the webform HTML. If you use WithIndexTemplate to provide an alternate HTML template for Handler, the template should expect a value of this type.

Jump to

Keyboard shortcuts

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