poc

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

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

Go to latest
Published: Mar 17, 2022 License: MIT Imports: 2 Imported by: 0

README

Toy proof-of-concept repo using "command" pattern

make run-dev

What is the "command" pattern?

The command pattern encapsulates all information necessary to perform a request before it is executed. This makes it easy to chain commands together, add middleware, etc.

The project root

The types of "commands" for this project are simply interfaces stored in the root directory under commands.go. Commands manipulate service objects, defined service.go.

Domain entities are saved in a file called model.go. The structs in this file do not contain any struct tags as that would violate their purpose: to serve as stable domain values. There are very few imports in this package and really only to define aggregate data types (e.g. guregu/null package).

Error types are stored in error.goand wrap underlying errors, conforming to Go's error convention (see https://pkg.go.dev/errors).

Dependency isolation

Sub-packages only import from the root package and 3rd-party packages (Never from other sub-packages... utilities are an exception). Dependencies should be specified as interfaces and defined as close as possible to the struct that uses it. If code is thoughtfully organized by imports and function, this layout effectively enforces dependency inversion.

Note that per Dave Cheney's advice on fewer, larger packages, sub-folders are not nested very deeply (Ideally only a single layer). And hold more, larger files than in other languages.

Pipelining commands

Inside the pipeline package, there are custom pipeline types. Holding lists of the command, a pipeline will implement the command interface, and terminate execution early when an error is encountered.

Handlers

Handlers do three things: They transform bytes into service objects, get results from a command and transform those results back into bytes.

Routers

Routers hand the request body to byte handlers for processing and return response bodies, translating errors into http error codes.

Dependency Setup

Executables are stored in packages under the cmd folder but they hold very little logic. The heavy lifting of dependency setup and pipeline definition is done in the boot package.

This project follows the idiomatic go convention to define a struct literal rather than a constructor when there is no constructor logic.

Utilities

Utility packages have meaningful names (config, logger, etc... never generic names like base, common or util). They are allowed to define global, singleton objects. A utility's sub-packages are allowed to register itself with its parent at import.

Code generation

Mocks, enum stringer methods, test harnesses and test assertion helpers are all generated using the go:generate comments. The test setup duplicates the logic in the boot package using mock dependencies. Since we've defined our dependencies as interfaces, we can use mock-generation libraries like golang/mock to generate that code.

Mocks, harnesses and assertions are saved in the test directory.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Board

type Board struct {
	Piles [13][]PositionedCard
	Score int32
}

Board is the current state of the board.

type Card

type Card struct {
	Suit  Suit
	Index Index
}

Card is a face card.

type Error

type Error struct {
	Actual   error
	Category ErrorCategory
}

Error wraps an existing error and assigns it a category.

func (Error) Error

func (e Error) Error() string

func (Error) Unwrap

func (e Error) Unwrap() error

type ErrorCategory

type ErrorCategory uint8

An ErrorCategory must be at least detailed enough to only correspond to a single http status code, but may be broken down further (one-to-many).

const (
	SemanticError ErrorCategory
	MalformedError
	UnavailableError
	UnimplementedError
	NotFoundError
	UnknownError
)

supported error categories

func (ErrorCategory) String

func (i ErrorCategory) String() string

type Index

type Index uint8

Index is the value part of the card.

const (
	Ace Index
	Two
	Three
	Four
	Five
	Six
	Seven
	Eight
	Nine
	Ten
	Jack
	Queen
	King
	Juggler
	Fool
)

Standard deck indices.

func (Index) String

func (i Index) String() string

type ListGames

type ListGames struct {
	Cursor struct {
		Offset int32
		Limit  int32
	}
	Games []SavedGameSummary
}

ListGames lists running games.

type ListGamesCaller

type ListGamesCaller interface {
	CallListGames(context.Context, ListGames) (ListGames, error)
}

ListGamesCaller is a list game command.

type Move

type Move struct {
	OldPileNum      int
	OldPileIndex    int
	OldPilePosition Position
	NewPileNum      int
	NewPileIndex    int
	NewPilePosition Position
}

Move is a transformation of the board.

type PerformMove

type PerformMove struct {
	Next            []Move
	SavedGameDetail SavedGameDetail
}

PerformMove executes a move on a game.

type PerformMoveCaller

type PerformMoveCaller interface {
	CallPerformMove(context.Context, PerformMove) (PerformMove, error)
}

PerformMoveCaller is a perform move command.

type Position

type Position uint64

Position is a way of positioning a card.

const (
	FaceUp Position = 1 << iota
)

Possible ways of positioning a card.

type PositionedCard

type PositionedCard struct {
	Position Position
	Card     Card
}

PositionedCard is a card that has a position

type SavedGameDetail

type SavedGameDetail struct {
	GameID            int64
	Board             Board
	History           [][]Move
	PossibleNextMoves [][]Move
	Variant           Variant
}

SavedGameDetail is a saved game with detail of the game state.

type SavedGameSummary

type SavedGameSummary struct {
	GameID int64
	Score  int32
}

SavedGameSummary is a saved game with summary of the game state.

type StartGame

type StartGame struct {
	Variant         Variant
	SavedGameDetail SavedGameDetail
}

StartGame starts a game.

type StartGameCaller

type StartGameCaller interface {
	CallStartGame(context.Context, StartGame) (StartGame, error)
}

StartGameCaller is a start game command.

type Suit

type Suit uint8

Suit is a the pip part of the card.

const (
	Hearts Suit
	Clubs
	Diamonds
	Spades
	Joker
)

Standard deck suits.

func (Suit) String

func (i Suit) String() string

type Variant

type Variant struct {
	MaxTimesThroughDeck int32
}

Variant is a rules variant.

Directories

Path Synopsis
cmd
api
env
db
encoding
test
mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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