Help us shape the future of Go! Take the 2026 Go Developer Survey

bedrock

package module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2024 License: MIT Imports: 3 Imported by: 7

README

bedrock

Mentioned in Awesome Go Go Reference Go Report Card Coverage build

bedrock provides a minimal, modular and composable foundation for quickly developing services and more use case specific frameworks in Go.

Core Concepts

bedrock begins with the concepts of an App and a Runtime. App is a container for a Runtime and handles more "low-level" things, such as, OS interrupts, config parsing, environment variable overrides, etc. The Runtime is then the users entry point for jumping right into their use case specific code e.g. RESTful API, gRPC service, K8s job, etc.

Building services with bedrock

bedrock conveniently comes with a couple of Runtimes already implemented for you. This can significantly aid in shortening your overall development time, as well as, provide an example for how to implement your own custom Runtime.

For example, the below shows how simple it is to initialize an HTTP based "API" leveraging the builtin HTTP Runtime.

package main

import (
    "context"
    "net/http"

    "github.com/z5labs/bedrock"
    "github.com/z5labs/bedrock/http"
)

func initRuntime(ctx context.Context) (bedrock.Runtime, error) {
    rt := brhttp.NewRuntime(
		brhttp.ListenOnPort(8080),
		brhttp.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprint(w, "Hello, world")
		}),
	)
	return rt, nil
}

func main() {
	bedrock.New(
		bedrock.WithRuntimeBuilderFunc(initRuntime),
	).Run()
}

There you go! An entire HTTP API in less than 20 lines... well kind of. This incredibly simple example can easily be extended (aka made more production-ready) by supplying extra options to both bedrock.New and brhttp.NewRuntime. For available, options please check the official Go documentation.

Building custom frameworks with bedrock

One of the guiding principals for bedrock is to composable. This principal comes from the experience gained from working with custom, tailor made frameworks which over their lifetime within an organization are unable to adapt to changing development and deployment patterns. Eventually, these frameworks are abandoned for new ones or completely rewritten to reflect the current state of the organization.

bedrock defines a small set of types and carefully chooses its opinions to balance composability and functionality, as much as it can. The result is, in fact, a framework that isn't necessarily designed for building services directly, but instead meant for building more custom, use case specific frameworks.

For example, bedrock could be used by your organizations platform engineering or framework team(s) to quickly develop internal frameworks which abstract over all of your organizations requirements e.g. OpenTelemetry, Logging, Authenticated endpoints, etc. Then, due to the high composibility of bedrock, any changes within your organization would then be very easy to adapt to within your internal framework. A more concrete example of how a custom framework could look like can be found in example/custom_framework.

Documentation

Overview

Package bedrock provides a minimal foundation for building more complex frameworks on top of.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Run added in v0.6.0

func Run[T any](ctx context.Context, builder AppBuilder[T], srcs ...config.Source) error

Run executes the application. It's responsible for reading the provided config sources, unmarshalling them into the generic config type, using the config and builder to build the users App and, lastly, running the returned App.

Example
package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/z5labs/bedrock/pkg/config"
)

type appFunc func(context.Context) error

func (f appFunc) Run(ctx context.Context) error {
	return f(ctx)
}

func main() {
	r := strings.NewReader(`hello: world`)

	// Define a custom config struct which aligns with your
	// the format of your config.Source(s).
	type MyConfig struct {
		Hello string `config:"hello"`
	}

	// Define a AppBuilder.
	builder := AppBuilderFunc[MyConfig](func(ctx context.Context, cfg MyConfig) (App, error) {
		// Inside your AppBuilder.Build is where you should be initializing
		// all dependencies of your code e.g. backend API clients, DB connections, etc.

		// Lastly, initialize something which implements the bedrock.App interface.
		app := appFunc(func(c context.Context) error {
			fmt.Println("hello,", cfg.Hello)
			return nil
		})

		return app, nil
	})

	err := Run(context.Background(), builder, config.FromYaml(r))
	if err != nil {
		fmt.Println(err)
		return
	}
}
Output:
hello, world

Types

type App

type App interface {
	Run(context.Context) error
}

App represents the entry point for user specific code.

type AppBuildError added in v0.6.0

type AppBuildError struct {
	Cause error
}

AppBuildError

func (AppBuildError) Error added in v0.6.0

func (e AppBuildError) Error() string

Error implements the [builtin.error] interface.

func (AppBuildError) Unwrap added in v0.6.0

func (e AppBuildError) Unwrap() error

Unwrap implements the implicit interface used by errors.Is and errors.As.

type AppBuilder added in v0.6.0

type AppBuilder[T any] interface {
	Build(ctx context.Context, cfg T) (App, error)
}

AppBuilder represents anything which can initialize a Runtime.

type AppBuilderFunc added in v0.6.0

type AppBuilderFunc[T any] func(context.Context, T) (App, error)

AppBuilderFunc is a functional implementation of the AppBuilder interface.

func (AppBuilderFunc[T]) Build added in v0.6.0

func (f AppBuilderFunc[T]) Build(ctx context.Context, cfg T) (App, error)

Build implements the RuntimeBuilder interface.

type AppRunError added in v0.6.0

type AppRunError struct {
	Cause error
}

AppRunError

func (AppRunError) Error added in v0.6.0

func (e AppRunError) Error() string

Error implements the [builtin.error] interface.

func (AppRunError) Unwrap added in v0.6.0

func (e AppRunError) Unwrap() error

Unwrap implements the implicit interface used by errors.Is and errors.As.

type ConfigReadError added in v0.6.0

type ConfigReadError struct {
	Cause error
}

ConfigReadError

func (ConfigReadError) Error added in v0.6.0

func (e ConfigReadError) Error() string

Error implements the [builtin.error] interface.

func (ConfigReadError) Unwrap added in v0.6.0

func (e ConfigReadError) Unwrap() error

Unwrap implements the implicit interface used by errors.Is and errors.As.

type ConfigUnmarshalError added in v0.6.0

type ConfigUnmarshalError struct {
	Cause error
}

ConfigUnmarshalError

func (ConfigUnmarshalError) Error added in v0.6.0

func (e ConfigUnmarshalError) Error() string

Error implements the [builtin.error] interface.

func (ConfigUnmarshalError) Unwrap added in v0.6.0

func (e ConfigUnmarshalError) Unwrap() error

Unwrap implements the implicit interface used by errors.Is and errors.As.

Directories

Path Synopsis
circuit module
example
simple_queue command
simple_rest command
fit module
host module
pkg
app
Package app provides helpers for common bedrock.App implementation patterns.
Package app provides helpers for common bedrock.App implementation patterns.
config
Package config provides very easy to use and extensible configuration management capabilities.
Package config provides very easy to use and extensible configuration management capabilities.
config/key
Package key provides types for strongly typed keys in key value pairs.
Package key provides types for strongly typed keys in key value pairs.
health
Package health defines K8s inspired health metrics.
Package health defines K8s inspired health metrics.
noop
Package noop provides no-op implementations to be used in tests and as defaults.
Package noop provides no-op implementations to be used in tests and as defaults.
ptr
Package ptr provides helpers for working with references of values.
Package ptr provides helpers for working with references of values.
Package queue provides multiple patterns which implements the app.Runtime interface.
Package queue provides multiple patterns which implements the app.Runtime interface.
Package rest provides a bedrock.App implementation for building RESTful applications.
Package rest provides a bedrock.App implementation for building RESTful applications.
endpoint
Package endpoint wraps generic RPC style code into a RESTful HTTP endpoint handler.
Package endpoint wraps generic RPC style code into a RESTful HTTP endpoint handler.
retry module

Jump to

Keyboard shortcuts

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