backbone

package module
v0.0.0-...-a21f649 Latest Latest
Warning

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

Go to latest
Published: Mar 22, 2023 License: Unlicense Imports: 3 Imported by: 0

README

backbone - WIP

Go doesn't provide a default opinionated project template like other languages, I think this is one of its strengths, it allows you to get on with it.

However, I have found I do tend to end up with the same kind of structure over and over again, so decided to template it for my own use and others.

Of course, layout is a subjective thing so in no way is this "the perfect go layout" or "how to build go apps", everyone has their own ideas and preferences, this represents how best fits my brains view of a go project.

Backbone is a template for a go server, this is what I use to bootstrap all my projects and adheres as closely as I can get to DDD and Hexagonal architecture.

Architecture

This uses a simple 3 layer architecture which is detailed in the ARCHITECTURE page.

WIP

This isn't yet finished, I'll be adding a few things over time:

  • Config structs and a default implementation using Viper
  • Code generation - for auto generating domain objects, the related transport, service and data layers

Goals

It's very easy to write a service quickly in go, this is great because you can test out ideas very rapidly and move quickly.

This however falls over when building enterprise grade services in teams. This rapidly developed code usually ends up hard, if not impossible to unit test, usually relies on global variable or abuse of context values and has no clear separation of application concerns.

This template aims to remedy that by:

  • Adhering to well established software engineering princples
  • Using Effective Go best practises
  • Adding clear separation of concerns by splitting the app into 3 logical layers (see ARCHITECTURE.md for more info)
  • Highly testable as we follow SOLID principles and code to interfaces
  • Replacing global variables with Dependency Injection
  • Use context purely for timeouts and request specific info like requestID

Inspiration

Some inspiration I found when coming up with this is listed below:

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Thing

type Thing struct {
	ThingID    int64     `json:"thingID" db:"thingID"`
	Name       string    `json:"name" db:"name"`
	CreatedAt  time.Time `json:"createdAt" db:"createdAt"`
	ModifiedAt time.Time `json:"modifiedAt" db:"modifiedAt"`
}

Thing defines a single thing.

type ThingArgs

type ThingArgs struct {
	ThingID int64 `param:"thingID" query:"thingID"`
}

ThingArgs are used to retrieve a single thing.

func (ThingArgs) Validate

func (t ThingArgs) Validate() validator.ErrValidation

Validate enforces ThingArgs rules.

type ThingCreate

type ThingCreate struct {
	Name string `json:"name" db:"name"`
	// CreatedAt set in the data layer before storing - could also be a db default value of current_date.
	CreatedAt time.Time `json:"-" db:"createdAt"`
}

ThingCreate is used to create a new thing.

type ThingReader

type ThingReader interface {
	Thing(ctx context.Context, args ThingArgs) (*Thing, error)
	Things(ctx context.Context) ([]*Thing, error)
}

ThingReader is used to read thing or things from a data store.

type ThingReaderWriter

type ThingReaderWriter interface {
	ThingReader
	ThingWriter
}

ThingReaderWriter combines the reader and writer interface to define a read/write datastore for working with things.

type ThingService

type ThingService interface {
	Thing(ctx context.Context, args ThingArgs) (*Thing, error)
	Things(ctx context.Context) ([]*Thing, error)
	Create(ctx context.Context, req ThingCreate) (*Thing, error)
	Update(ctx context.Context, args ThingArgs, req ThingUpdate) (*Thing, error)
	Delete(ctx context.Context, args ThingArgs) error
}

ThingService is used to enforce business rules, orchestrate data store calls and raise business events.

type ThingUpdate

type ThingUpdate struct {
	Name string `json:"name" db:"name"`
	// ModifiedAt used to set the update time in the data layer.
	ModifiedAt time.Time `json:"-" db:"modifiedAt"`
}

ThingUpdate is used to update a thing.

type ThingWriter

type ThingWriter interface {
	Create(ctx context.Context, args ThingCreate) (*Thing, error)
	Update(ctx context.Context, args ThingArgs, req ThingUpdate) (*Thing, error)
	Delete(ctx context.Context, args ThingArgs) error
}

ThingWriter can be implemented to write and modify things stored in a datastore.

Directories

Path Synopsis
cmd
internal
Package mocks requires the github.com/matryer/moq lib to be installed.
Package mocks requires the github.com/matryer/moq lib to be installed.

Jump to

Keyboard shortcuts

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