gouldian

package module
v2.0.6 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2024 License: Apache-2.0 Imports: 16 Imported by: 1

README

µ-Gouldian

Go combinator library for building containerized and serverless HTTP services.


The library is a thin layer of purely functional abstractions to build HTTP services. In the contrast with other HTTP routers, the library resolves a challenge of building simple and declarative api implementations in the absence of pattern matching at Golang. The library also support opaque migration of HTTP service between traditional, containers and serverless environments.

User Guide | Hello World | Other Examples | Benchmark

Inspiration

Microservices have become a design style to evolve system architecture in parallel, implement stable and consistent interfaces within distributed system. An expressive language is required to design the manifold of network interfaces. A pure functional languages fits very well to express communication behavior due they rich techniques to hide the networking complexity. Finch is the best library in Scala for microservice development. Gouldian is heavily inspired by Finch.

The library solves few practical problems of HTTP service development in Golang:

  • The library support opaque migration of HTTP service between traditional, containers and serverless environments. The api implementation remains source compatible regardless the execution environment; The library supports integration with
  • The library enforces a type safe, pattern-based approach for api definition.
  • Fast, zero allocation routing

Installing

The library requires Go 1.18 or later.

The latest version of the library is available at main branch. All development, including new features and bug fixes, take place on the main branch using forking and pull requests as described in contribution guidelines. The stable version is available via Golang modules.

  1. Use go get to retrieve the library and add it as dependency to your application.
go get -u github.com/fogfish/gouldian
  1. Import it in your code
import (
  µ "github.com/fogfish/gouldian"
)

Quick Example

Here is minimal "Hello World!" example that matches any HTTP requests to /hello endpoint. You can run this example locally see the instructions.

package main

import (
  µ "github.com/fogfish/gouldian"
  "github.com/fogfish/gouldian/server/httpd"
  "net/http"
)

func main() {
  http.ListenAndServe(":8080",
    httpd.Serve(hello()),
  )
}

func hello() µ.Routable {
  return µ.GET(
    µ.URI(µ.Path("hello")),
    func(ctx µ.Context) error {
      return µ.Status.OK(µ.WithText("Hello World!"))
    },
  )
}

Benchmark

The library uses go-http-routing-benchmark methodology for benchmarking, using structure of GitHub API as primary benchmark. The results are obtained on the reference hardware such as AWS m6i.large and a1.large instances.

m6i.large 3.5 GHz 3rd generation Intel Xeon Scalable processors:

  • It takes 10.9M routing decisions per second, taking about 110 ns/op and consuming about 0 allocs/ops.
  • It performs 7.4M requests/responses for the single endpoint with one parameter, taking about 162 ns/op and consuming 24 B/op with 2 allocs/op.

a1.large AWS Graviton Processor with 64-bit Arm Neoverse cores:

  • It takes 2M routing decisions per second, taking about 520 ns/op and consuming about 0 allocs/ops.
  • It performs 1.5M requests/responses for the single endpoint with one parameter, taking about 763 ns/op and consuming 24 B/op with 2 allocs/op.

Next steps

  • Study User Guide.

  • Check build-in collection of endpoints to deal with HTTP request: path, query param, http header, body and other

  • Endpoint always returns some Output that defines HTTP response. There are three cases of output: HTTP Success, HTTP Failure and general error. See Output type.

  • See example folder for other advanced use-case.

  • Learn about microservice deployment with AWS CDK, in case of serverless development

How To Contribute

The library is Apache 2.0 licensed and accepts contributions via GitHub pull requests:

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

The build and testing process requires Go version 1.13 or later.

Build and run in your development console.

git clone https://github.com/fogfish/gouldian
cd gouldian
go test
go test -run=^$ -bench=. -cpu 1

commit message

The commit message helps us to write a good release note, speed-up review process. The message should address two question what changed and why. The project follows the template defined by chapter Contributing to a Project of Git book.

bugs

If you experience any issues with the library, please let us know via GitHub issues. We appreciate detailed and accurate reports that help us to identity and replicate the issue.

License

See LICENSE

Documentation

Overview

Package gouldian is Go combinator library for building HTTP services. The library is a thin layer of purely functional abstractions to building simple and declarative api implementations in the absence of pattern matching for traditional and serverless applications.

Inspiration

The library is heavily inspired by Scala Finch https://github.com/finagle/finch.

Getting started

Here is minimal "Hello World!" example that matches any HTTP requests to /hello endpoint.

package main

import (
  µ "github.com/fogfish/gouldian"
  "github.com/fogfish/gouldian/server/httpd"
  "net/http"
)

func main() {
  http.ListenAndServe(":8080",
    httpd.Serve(hello()),
  )
}

func hello() µ.Endpoint {
  return µ.GET(
    µ.URI(µ.Path("hello")),
    func(ctx µ.Context) error {
      return µ.Status.OK(µ.WithText("Hello World!"))
    },
  )
}

See examples folder for advanced use-case.

Next steps

↣ Study Endpoint type and its composition, see User Guide

↣ Check build-in collection of endpoints to deal with HTTP request. See types: HTTP, APIGateway

↣ Endpoint always returns some `Output` that defines HTTP response. There are three cases of output: HTTP Success, HTTP Failure and general error. See Output, Issue types.

Index

Constants

View Source
const (
	Accept            = HeaderEnumContent("Accept")
	AcceptCharset     = HeaderOf[string]("Accept-Charset")
	AcceptEncoding    = HeaderOf[string]("Accept-Encoding")
	AcceptLanguage    = HeaderOf[string]("Accept-Language")
	CacheControl      = HeaderOf[string]("Cache-Control")
	Connection        = HeaderEnumConnection("Connection")
	ContentEncoding   = HeaderOf[string]("Content-Encoding")
	ContentLength     = HeaderOf[int]("Content-Length")
	ContentType       = HeaderEnumContent("Content-Type")
	Cookie            = HeaderOf[string]("Cookie")
	Date              = HeaderOf[time.Time]("Date")
	From              = HeaderOf[string]("From")
	Host              = HeaderOf[string]("Host")
	IfMatch           = HeaderOf[string]("If-Match")
	IfModifiedSince   = HeaderOf[time.Time]("If-Modified-Since")
	IfNoneMatch       = HeaderOf[string]("If-None-Match")
	IfRange           = HeaderOf[string]("If-Range")
	IfUnmodifiedSince = HeaderOf[time.Time]("If-Unmodified-Since")
	Origin            = HeaderOf[string]("Origin")
	Range             = HeaderOf[string]("Range")
	Referer           = HeaderOf[string]("Referer")
	TransferEncoding  = HeaderEnumTransferEncoding("Transfer-Encoding")
	UserAgent         = HeaderOf[string]("User-Agent")
	Upgrade           = HeaderOf[string]("Upgrade")
)

List of supported HTTP header constants https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields

View Source
const (
	// Any constant matches any term
	Any = "_"
)

Variables

View Source
var ErrNoMatch error = NoMatch(255)

ErrNoMatch constant

View Source
var Sequence = guid.NewClock()

Sequence for generating unique identity

Functions

func FromContext

func FromContext[S any](ctx *Context, val *S) error

Get decodes context into structure

func Optics2

func Optics2[T, A, B any](attr ...string) (Lens, Lens)

Optics2 unfold attribute(s) of type T

func Optics3

func Optics3[T, A, B, C any](attr ...string) (Lens, Lens, Lens)

Optics3 unfold attribute(s) of type T

func Optics4

func Optics4[T, A, B, C, D any](attr ...string) (Lens, Lens, Lens, Lens)

Optics4 unfold attribute(s) of type T

func Optics5

func Optics5[T, A, B, C, D, E any](attr ...string) (Lens, Lens, Lens, Lens, Lens)

Optics5 unfold attribute(s) of type T

func Optics6

func Optics6[T, A, B, C, D, E, F any](attr ...string) (Lens, Lens, Lens, Lens, Lens, Lens)

Optics6 unfold attribute(s) of type T

func Optics7

func Optics7[T, A, B, C, D, E, F, G any](attr ...string) (Lens, Lens, Lens, Lens, Lens, Lens, Lens)

Optics7 unfold attribute(s) of type T

func Optics8

func Optics8[T, A, B, C, D, E, F, G, H any](attr ...string) (Lens, Lens, Lens, Lens, Lens, Lens, Lens, Lens)

Optics8 unfold attribute(s) of type T

func Optics9

func Optics9[T, A, B, C, D, E, F, G, H, I any](attr ...string) (Lens, Lens, Lens, Lens, Lens, Lens, Lens, Lens, Lens)

Optics9 unfold attribute(s) of type T

Types

type Context

type Context struct {
	context.Context

	Request *http.Request

	JWT Token
	// contains filtered or unexported fields
}

Context of HTTP request. The context accumulates matched terms of HTTP and passes it to destination function.

func NewContext

func NewContext(ctx context.Context) *Context

NewContext create a new context for HTTP request

func (*Context) Free

func (ctx *Context) Free()

Free the context

func (*Context) Put

func (ctx *Context) Put(lens optics.Lens, str string) error

Put injects value to the context

type Endpoint

type Endpoint func(*Context) error

Endpoint is a composable function that abstract HTTP endpoint. The function takes HTTP request and returns value of some type: `Context => Output`.

↣ `Context` is a wrapper over HTTP request with additional context.

↣ `Output` is sum type that represents if it is matched on a given input or not. The library uses `error` type to represent both valid and invalid variants.

Any `Endpoint A` can be composed with `Endpoint B` into new `Endpoint C`. It supports two combinators: and-then, or-else.

↣ Use `and-then` to build product Endpoint. The product type matches Input if each composed function successfully matches it.

↣ Use `or-else` to build co-product Endpoint. The co-product is also known as sum-type matches first successful function.

Endpoint life-cycle - each incoming HTTP request is wrapped with `Input` and applied to an endpoint. A returned error-like results is checked against successful Output or NoMatch error. All these machinery is handled by the libray, you should only dare to declare Endpoint from ready made primitives.

gouldian library delivers set of built-in endpoints to deal with HTTP request processing.

func Authorization

func Authorization(f func(string, string) error) Endpoint

Authorization defines Endpoints that simplify validation of credentials/tokens supplied within the request

e := µ.GET( µ.Authorization(func(string, string) error { ... }) )
e(mock.Input(mock.Header("Authorization", "Basic foo"))) == nil
e(mock.Input(mock.Header("Authorization", "Basic bar"))) != nil

func Body

func Body(lens Lens) Endpoint

Body decodes HTTP request body and lifts it to the structure

func FMap

func FMap[A any](f func(*Context, *A) error) Endpoint

FMap applies clojure to matched HTTP request, taking the execution context as the input to closure

func Header[T MatchableHeaderValues](hdr string, val T) Endpoint

Header combinator defines primitives to match Headers of HTTP requests.

endpoint := µ.GET(
  µ.Header("X-Foo", "Bar"),
)

endpoint(
  mock.Input(
    mock.Header("X-Foo", "Bar")
  )
) == nil

func HeaderAny

func HeaderAny(hdr string) Endpoint

HeaderAny is a wildcard matcher of header. It fails if header is not defined.

e := µ.GET( µ.HeaderAny("X-Foo") )
e(mock.Input(mock.Header("X-Foo", "Bar"))) == nil
e(mock.Input(mock.Header("X-Foo", "Baz"))) == nil
e(mock.Input()) != nil

func HeaderMaybe

func HeaderMaybe(header string, lens Lens) Endpoint

HeaderMaybe matches header value to the request context. It uses lens abstraction to decode HTTP header into Golang type. The Endpoint does not cause no-match if header value cannot be decoded to the target type. See optics.Lens type for details.

type myT struct{ Val string }

x := µ.Optics1[myT, string]()
e := µ.GET(µ.HeaderMaybe("X-Foo", x))
e(mock.Input(mock.Header("X-Foo", "Bar"))) == nil

func JWT

func JWT[T Pattern](claim JWTClaim, val T) Endpoint

JWT combinator defines primitives to match JWT token in the HTTP requests.

  endpoint := µ.GET(
    µ.JWT(µ.Token.Username, "joedoe"),
  )

  endpoint(
    mock.Input(
			mock.JWT(µ.Token{"username": "joedoe"})
    )
  ) == nil

func JWTAllOf

func JWTAllOf(claim JWTClaim, vals ...string) Endpoint

JWTAllOf matches a key of JWT if it contains one of the tokens

µ.GET( µ.JWTAllOf(µ.JWT.Scope, "ro", "rw") )

func JWTMaybe

func JWTMaybe(claim JWTClaim, lens optics.Lens) Endpoint

JWTMaybe matches key of JWT to the request context. It uses lens abstraction to decode value into Golang type. The Endpoint does not cause no-match if header value cannot be decoded to the target type. See optics.Lens type for details.

type MyT struct{ Username string }

username := µ.Optics1[MyT, string]()
e := µ.GET( µ.JWTMaybe(µ.JWT.Sub).Maybe(username) )
e(mock.Input(mock.JWT(µ.JWT{"username": "joedoe"}))) == nil

func JWTOneOf

func JWTOneOf(claim JWTClaim, vals ...string) Endpoint

JWTOneOf matches a key of JWT if it contains one of the tokens

µ.GET( µ.JWTOneOf(µ.JWT.Scope, "ro", "rw") )

func Join

func Join(seq ...Endpoint) Endpoint

Join builds product endpoint from sequence

func Map

func Map[A, B any](f func(*Context, *A) (*B, error)) Endpoint

Map applies clojure to matched HTTP request, taking the execution context and matched parameters as the input to closure. The output is always returned as JSON.

func Method

func Method(verb string) Endpoint

Method is an endpoint to match HTTP verb request

func Or

func Or(seq ...Endpoint) Endpoint

Or builds co-product endpoint from sequence

func Param

func Param[T Pattern](key string, val T) Endpoint

Param combinator defines primitives to match query param in the HTTP requests.

  endpoint := µ.GET(
    µ.Param("foo", "bar"),
  )

  endpoint(
    mock.Input(
			mock.URL("/?foo=bar")
    )
  ) == nil

func ParamAny

func ParamAny(key string) Endpoint

ParamAny is a wildcard matcher of param key. It fails if key is not defined.

e := µ.GET( µ.ParamAny("foo") )
e(mock.Input(mock.URL("/?foo"))) == nil
e(mock.Input(mock.URL("/?foo=bar"))) == nil
e(mock.Input(mock.URL("/?foo=baz"))) == nil
e(mock.Input()) != nil

func ParamJSON

func ParamJSON(key string, lens Lens) Endpoint

JSON matches a param key to struct. It assumes that key holds JSON value as url encoded string

func ParamMaybe

func ParamMaybe(key string, lens Lens) Endpoint

ParamMaybe matches param value to the request context. It uses lens abstraction to decode value into Golang type. The Endpoint does not cause no-match if header value cannot be decoded to the target type. See optics.Lens type for details.

  type myT struct{ Val string }

  x := µ.Optics1[myT, string]()
  e := µ.GET( µ.ParamMaybe("foo", x) )
  e(mock.Input(mock.URL("/?foo=bar"))) == nil
	e(mock.Input(mock.URL("/?foo"))) == nil
	e(mock.Input(mock.URL("/"))) == nil

func ParamMaybeJSON

func ParamMaybeJSON(key string, lens Lens) Endpoint

MaybeJSON matches a param key to closed struct. It assumes that key holds JSON value as url encoded string. It does not fail if key is not defined.

func Params

func Params(lens Lens) Endpoint

Params lifts all Query parameters to struct

type MyRequest struct {
	Params MyType `content:"form"`
}
var params = µ.Optics1[MyRequest, MyType]()
µ.GET(µ.Params(params))

func (Endpoint) Or

func (a Endpoint) Or(b Endpoint) Endpoint

Or builds co-product Endpoint

func (Endpoint) Then

func (a Endpoint) Then(b Endpoint) Endpoint

Then builds product Endpoint

type Endpoints

type Endpoints []Endpoint

Endpoints is sequence of Endpoints

func (Endpoints) Join

func (seq Endpoints) Join(ctx *Context) (err error)

Join builds product endpoint from sequence

func (Endpoints) Or

func (seq Endpoints) Or(ctx *Context) (err error)

Or builds co-product endpoint from sequence

type HeaderEnumConnection

type HeaderEnumConnection string

Type of HTTP Header, Connection enumeration

const Connection = HeaderEnumConnection("Connection")
µ.Connection.KeepAlive

func (HeaderEnumConnection) Any

func (h HeaderEnumConnection) Any(ctx *Context) error

Matches header to any value

func (HeaderEnumConnection) Close

func (h HeaderEnumConnection) Close(ctx *Context) error

Close defines header `???: close`

func (HeaderEnumConnection) Is

func (h HeaderEnumConnection) Is(value string) Endpoint

Matches value of HTTP header

func (HeaderEnumConnection) KeepAlive

func (h HeaderEnumConnection) KeepAlive(ctx *Context) error

KeepAlive defines header `???: keep-alive`

func (HeaderEnumConnection) To

func (h HeaderEnumConnection) To(lens Lens) Endpoint

Matches value of HTTP header

type HeaderEnumContent

type HeaderEnumContent string

Type of HTTP Header, Content-Type enumeration

const ContentType = HeaderEnumContent("Content-Type")
µ.ContentType.JSON

func (HeaderEnumContent) Any

func (h HeaderEnumContent) Any(ctx *Context) error

Matches header to any value

func (HeaderEnumContent) ApplicationJSON

func (h HeaderEnumContent) ApplicationJSON(ctx *Context) error

ApplicationJSON defines header `???: application/json`

func (HeaderEnumContent) Form

func (h HeaderEnumContent) Form(ctx *Context) error

Form defined Header `???: application/x-www-form-urlencoded`

func (HeaderEnumContent) HTML

func (h HeaderEnumContent) HTML(ctx *Context) error

HTML defined Header `???: text/html`

func (HeaderEnumContent) Is

func (h HeaderEnumContent) Is(value string) Endpoint

Matches value of HTTP header

func (HeaderEnumContent) JSON

func (h HeaderEnumContent) JSON(ctx *Context) error

JSON defines header `???: application/json`

func (HeaderEnumContent) Text

func (h HeaderEnumContent) Text(ctx *Context) error

Text defined Header `???: text/plain`

func (HeaderEnumContent) TextHTML

func (h HeaderEnumContent) TextHTML(ctx *Context) error

TextHTML defined Header `???: text/html`

func (HeaderEnumContent) TextPlain

func (h HeaderEnumContent) TextPlain(ctx *Context) error

TextPlain defined Header `???: text/plain`

func (HeaderEnumContent) To

func (h HeaderEnumContent) To(lens Lens) Endpoint

Matches value of HTTP header

type HeaderEnumTransferEncoding

type HeaderEnumTransferEncoding string

Type of HTTP Header, Transfer-Encoding enumeration

const TransferEncoding = HeaderEnumTransferEncoding("Transfer-Encoding")
µ.TransferEncoding.Chunked

func (HeaderEnumTransferEncoding) Any

Matches header to any value

func (HeaderEnumTransferEncoding) Chunked

func (h HeaderEnumTransferEncoding) Chunked(ctx *Context) error

Chunked defines header `Transfer-Encoding: chunked`

func (HeaderEnumTransferEncoding) Identity

func (h HeaderEnumTransferEncoding) Identity(ctx *Context) error

Identity defines header `Transfer-Encoding: identity`

func (HeaderEnumTransferEncoding) Is

Matches value of HTTP header

func (HeaderEnumTransferEncoding) To

Matches value of HTTP header

type HeaderOf

type HeaderOf[T MatchableHeaderValues] string

Internal type

func (HeaderOf[T]) Any

func (h HeaderOf[T]) Any(ctx *Context) error

Any is a wildcard matcher of header. It fails if header is not defined.

func (HeaderOf[T]) Is

func (h HeaderOf[T]) Is(value T) Endpoint

Is matches a header to defined literal value.

func (HeaderOf[T]) To

func (h HeaderOf[T]) To(lens Lens) Endpoint

To matches header value to the request context. It uses lens abstraction to decode HTTP header into Golang type. The Endpoint causes no-match if header value cannot be decoded to the target type. See optics.Lens type for details.

type Issue

type Issue struct {
	ID     string `json:"instance"`
	Type   string `json:"type"`
	Status int    `json:"status"`
	Title  string `json:"title"`
}

Issue implements RFC 7807: Problem Details for HTTP APIs

func NewIssue

func NewIssue(status int) Issue

NewIssue creates instance of Issue

type JWTClaim

type JWTClaim func(Token) string

JWTClaim is function type to extract claims from token

type Lens

type Lens struct{ optics.Lens }

Lens type

func Optics1

func Optics1[T, A any](attr ...string) Lens

Optics1 unfold attribute(s) of type T

type MatchableHeaderValues

type MatchableHeaderValues interface {
	ReadableHeaderValues | Lens
}

type NoMatch

type NoMatch int

NoMatch is returned by Endpoint if Context is not matched.

func (NoMatch) Error

func (err NoMatch) Error() string

type Node

type Node struct {
	Path string   // substring from the route "owned" by the node
	Heir []*Node  // heir nodes
	Func Endpoint // end point associated with node

}

Node of trie

func NewRoutes

func NewRoutes(seq ...Routable) *Node

NewRoutes creates new routing table

func (*Node) Endpoint

func (root *Node) Endpoint() Endpoint

Endpoint converts trie to Endpoint

func (*Node) Println

func (root *Node) Println()

Println outputs trie to console

func (*Node) Walk

func (root *Node) Walk(f func(int, *Node))

Walk through trie, use for debug purposes only

type Output

type Output struct {
	Status  int
	Headers []struct{ Header, Value string }
	Body    string
	Failure error
}

Output

func NewOutput

func NewOutput(status int) *Output

NewOutput creates HTTP response with given HTTP Status code

func (Output) Error

func (out Output) Error() string

Output uses "error" interface

func (*Output) Free

func (out *Output) Free()

Free releases output

func (*Output) GetHeader

func (out *Output) GetHeader(header string) string

func (*Output) SetHeader

func (out *Output) SetHeader(header, value string)

func (*Output) SetIssue

func (out *Output) SetIssue(failure error, title ...string)

WithIssue appends Issue, RFC 7807: Problem Details for HTTP APIs

type Pattern

type Pattern interface{ string | Lens }

Pattern is a union type of allowed params to matcher functions

type Query

type Query map[string][]string

Query of HTTP request

func (Query) Get

func (query Query) Get(key string) (string, bool)

Get parameter by key

type ReadableHeaderValues

type ReadableHeaderValues interface {
	int | string | time.Time
}

type Result

type Result func(*Output) error

Result is a composable function that abstract results of HTTP endpoint. The function takes instance of HTTP output and mutates its value

  return µ.Status.OK(
		µ.WithHeader(headers.ContentType, headers.ApplicationJson),
		µ.WithJSON(value),
	)

type Routable

type Routable func() ([]string, Endpoint)

Routable is endpoint with routing metadata

func ANY

func ANY(path Routable, arrows ...Endpoint) Routable

ANY composes Endpoints into Routable that matches HTTP any request.

e := µ.ANY(
  µ.URI(µ.Path("foo"), µ.Path("bar")),
  ...
)
e(mock.Input(mock.Method("PUT"))) == nil
e(mock.Input(mock.Method("OTHER"))) == nil

func DELETE

func DELETE(path Routable, arrows ...Endpoint) Routable

DELETE composes Endpoints into Routable that matches HTTP DELETE request.

e := µ.DELETE(
  µ.URI(µ.Path("foo"), µ.Path("bar")),
  ...
)
e(mock.Input(mock.Method("DELETE"))) == nil
e(mock.Input(mock.Method("OTHER"))) != nil

func GET

func GET(path Routable, arrows ...Endpoint) Routable

GET composes Endpoints into Routable that matches HTTP GET request.

e := µ.GET(
  µ.URI(µ.Path("foo"), µ.Path("bar")),
  ...
)
e(mock.Input(mock.Method("GET"))) == nil
e(mock.Input(mock.Method("OTHER"))) != nil

func HTTP

func HTTP(verb string, path Routable, arrows ...Endpoint) Routable

HTTP composes Endpoints into Routable

func PATCH

func PATCH(path Routable, arrows ...Endpoint) Routable

PATCH composes Endpoints into Routable that matches HTTP PATCH request.

e := µ.PATCH(
  µ.URI(µ.Path("foo"), µ.Path("bar")),
  ...
)
e(mock.Input(mock.Method("PATCH"))) == nil
e(mock.Input(mock.Method("OTHER"))) != nil

func POST

func POST(path Routable, arrows ...Endpoint) Routable

POST composes Endpoints into Routable that matches HTTP POST request.

e := µ.POST(
  µ.URI(µ.Path("foo"), µ.Path("bar")),
  ...
)
e(mock.Input(mock.Method("POST"))) == nil
e(mock.Input(mock.Method("OTHER"))) != nil

func PUT

func PUT(path Routable, arrows ...Endpoint) Routable

PUT composes Endpoints into Routable that matches HTTP PUT request.

e := µ.PUT(
  µ.URI(µ.Path("foo"), µ.Path("bar")),
  ...
)
e(mock.Input(mock.Method("PUT"))) == nil
e(mock.Input(mock.Method("OTHER"))) != nil

func Route

func Route(
	path Routable,
	seq ...Endpoint,
) Routable

Route converts sequence ot Endpoints into Routable element

func URI

func URI(segments ...Segment) Routable

URI is an endpoint to match URL of HTTP request. The function takes a sequence of segment patterns as input. These patterns are either literals or lenses, where each term corresponds to the path segment. The function do not match if length of path is not equal to the length of pattern or segment do not match to pattern

e := µ.GET( µ.URI(µ.Path("foo")) )
e(mock.Input(mock.URL("/foo"))) == nil
e(mock.Input(mock.URL("/bar"))) != nil

type Router

type Router interface {
	Endpoint() Endpoint
}

Router is data structure that holds routing information, convertable to Endpoint

type Segment

type Segment struct {
	// contains filtered or unexported fields
}

Segment union type, make URI type safe

func Path

func Path[T Pattern](segment T) Segment

Path is an endpoint to match a single URL segment of HTTP request. The function takes a path pattern as arguments. The pattern is either literal or lens. The function do not match if segment do not match to pattern

e := µ.GET( µ.URI(µ.Path("foo")) )
e(mock.Input(mock.URL("/foo"))) == nil
e(mock.Input(mock.URL("/bar"))) != nil

func PathAll

func PathAll(segment Lens) Segment

PathAll is an endpoint to match entire remaining path of URI

func PathAny

func PathAny() Segment

PathAny is a synonym of µ.Path("_"), it matches any segments

type Token

type Token map[string]string

Token is a container for access token

func NewToken

func NewToken(raw map[string]interface{}) Token

NewToken creates access token object

func (Token) ClientID

func (t Token) ClientID() string

ClientID associated with token

func (Token) Exp

func (t Token) Exp() string

Exp -ires after

func (Token) Iss

func (t Token) Iss() string

Iss -uer of token

func (Token) Jti

func (t Token) Jti() string

Jti is unique JWT token identity

func (Token) Scope

func (t Token) Scope() string

Scope of the token

func (Token) Sub

func (t Token) Sub() string

Sub -ject of token

func (Token) Username

func (t Token) Username() string

Username associated with token

Directories

Path Synopsis
example
internal
optics
Package optics is an internal, see golem.optics for public api
Package optics is an internal, see golem.optics for public api
server

Jump to

Keyboard shortcuts

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