ProductPromotion
Logo

Go.Lang

made by https://0x3d.site

GitHub - z5labs/bedrock: A framework for building other frameworks
A framework for building other frameworks. Contribute to z5labs/bedrock development by creating an account on GitHub.
Visit Site

GitHub - z5labs/bedrock: A framework for building other frameworks

GitHub - z5labs/bedrock: A framework for building other frameworks

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

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

App is a simple abstraction over the execution of your specific application type e.g. HTTP server, gRPC server, etc.

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

AppBuilder puts the responsibility of App initialization in your hands!

The generic parameter provided to your AppBuilder is, in fact, your custom configuration type, which means no messing with config parsing and unmarshalling yourself!

package config

type Source interface {
	Apply(Store) error
}

The config.Source is arguably the most powerful abstraction defined in any of the bedrock packages. It abstracts over the entire mechanic of sourcing your application configuration. This simple interface can then be implemented in various ways to support loading configuration from different files (e.g. YAML, JSON, TOML) to remote configuration stores (e.g. etcd).

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

The final piece and most crucial piece bedrock provides is the Run function which handles the orchestration of config parsing, app building and, lastly, app execution by relying on the other core abstractions noted above.

Building services with bedrock

bedrock conveniently comes with a couple of Apps 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 App.

For example, the below shows how simple it is to implement a RESTful API leveraging the rest.App.

package main

import (
    "context"
	"encoding/json"
	"net/http"
	"strings"

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

type echoService struct{}

type EchoRequest struct {
	Msg string `json:"msg"`
}

func (EchoRequest) ContentType() string {
	return "application/json"
}

func (req *EchoRequest) UnmarshalBinary(b []byte) error {
	return json.Unmarshal(b, req)
}

type EchoResponse struct {
	Msg string `json:"msg"`
}

func (EchoResponse) ContentType() string {
	return "application/json"
}

func (resp EchoResponse) MarshalBinary() ([]byte, error) {
	return json.Marshal(resp)
}

func (echoService) Handle(ctx context.Context, req *EchoRequest) (*EchoResponse, error) {
	return &EchoResponse{Msg: req.Msg}, nil
}

type Config struct {
	Title string `config:"title"`
	Version string `config:"version"`

	Http struct {
		Port uint `config:"port"`
	} `config:"http"`
}

// here we're defining our AppBuilder as a simple function
// remember bedrock.Run handles config unmarshalling for us
// so we get to work with our custom config type, Config, directly.
func buildRestApp(ctx context.Context, cfg Config) (bedrock.App, error) {
	app := rest.NewApp(
		rest.ListenOn(cfg.Http.Port),
		rest.Title(cfg.Title),
		rest.Version(cfg.Version),
		rest.Endpoint(
			http.MethodPost,
			"/",
			endpoint.NewOperation(
				echoService{},
			),
		),
	)
	return app, nil
}

// would recommend this being a separate file you could use
// go:embed on or use a config.Source that could fetch it
// from a remote store.
var config = `{
	"title": "My Example API",
	"version": "v0.0.0",
	"http": {
		"port": 8080
	}
}`

func main() {
	builder := bedrock.AppBuilderFunc[Config](buildRestApp)

	// Note: Should actually handle error in your code
	_ = bedrock.Run(
		context.Background(),
		builder,
		config.FromJson(strings.NewReader(config)),
	)
}

There you go, an entire RESTful API in less than 100 lines!

This incredibly simple example can theb easily be extended (aka made more production-ready) by leveraging a middleware approach to the App returned by your AppBuilder. Conventiently, bedrock already has a couple common middlewares defined for your use in package app. Two notable middleware implementations are:

Building custom frameworks with bedrock

One of the guiding principals for bedrock is to be 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.

Articles
to learn more about the golang concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here ๐Ÿ”ฅ.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here ๐Ÿ”ฅ.

Queries
or most google FAQ's about GoLang.

mail [email protected] to add more queries here ๐Ÿ”.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory