rpc

package
v0.0.0-...-a283ab3 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2024 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package rpc implements a barebones RPC framework based on HTTP and JSON.

Clients invoke RPC methods by making an HTTP POST request to a well known path, and may provide parameters via a single JSON-encoded value in the request body. RPC responses include an appropriate HTTP status code, and may include a response body containing a single JSON-encoded value.

No HTTP method other than POST is accepted for RPC requests, even those that do not require parameters. The maximum size of RPC request bodies may be limited to conserve server resources. Requests with parameters must include a Content-Type header with the value "application/json".

This framework is not considered acceptable for Internet-facing production use. For example, the Content-Type enforcement described above is the only mitigation against cross-site request forgery attacks.

Example
package main

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

	"github.com/ahamlinman/hypcast/internal/api/rpc"
)

func main() {
	setEnabled := func(enabled bool) { /* do something useful */ }

	mux := http.NewServeMux()
	mux.Handle("/rpc/setstatus",
		rpc.HTTPHandler(func(_ *http.Request, params struct{ Enabled *bool }) (code int, body any) {
			if params.Enabled == nil {
				return http.StatusBadRequest, errors.New(`missing "Enabled" parameter`)
			}
			setEnabled(*params.Enabled)
			return http.StatusNoContent, nil
		}))

	req := httptest.NewRequest(
		http.MethodPost, "/rpc/setstatus", strings.NewReader(`{"Enabled": true}`),
	)
	req.Header.Add("Content-Type", "application/json")

	resp := httptest.NewRecorder()
	mux.ServeHTTP(resp, req)
	fmt.Println(resp.Result().StatusCode)
}
Output:

204

Index

Examples

Constants

This section is empty.

Variables

View Source
var MaxRequestBodySize int64 = 1024

MaxRequestBodySize is the maximum size of the HTTP body in an RPC request. Requests whose body exceeds this size will fail without being handled.

TODO: This should not be global.

Functions

func HTTPHandler

func HTTPHandler[T any](handler HandlerFunc[T]) http.Handler

HTTPHandler conveniently boxes an RPC handler function into an http.Handler, without requiring an explicit type argument for a HandlerFunc[T] conversion.

Types

type HandlerFunc

type HandlerFunc[T any] func(r *http.Request, params T) (code int, body any)

HandlerFunc is a type for functions that handle RPC calls initiated by HTTP clients, accepting parameters decoded from JSON and returning an HTTP status code and optional JSON-encodable result body.

When the client provides a JSON parameters value in the request body, the RPC framework decodes it using standard json.Unmarshal rules. When the body returned by the handler is a Go error, the framework encodes it as a JSON object with an "Error" key containing the stringified error message. Otherwise, when the body is non-nil, the framework encodes it to JSON following standard json.Marshal rules.

func (HandlerFunc[T]) ServeHTTP

func (handler HandlerFunc[T]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler for an RPC handler function.

Jump to

Keyboard shortcuts

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