serve

package
v0.0.0-...-2c3b082 Latest Latest
Warning

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

Go to latest
Published: Dec 17, 2023 License: GPL-3.0 Imports: 24 Imported by: 0

README

Serve

This is where all the setup, start and eventually graceful shutdown is happening. There's a fair bit of code, and it's likely to grow a bit as you add more middleware and databases, but it shouldn't become a lot bigger.

Config.go

This is one large flag file. All flag names are constants, this is to avoid magic strings and getting compilation errors if a flag is expected but not setup. If you need other types of flags than the ones provided, you'll also need to add them in the two functions addFlags and setDefaults in serve.go.

If you're adding a flag of an existing type, it's just to add the FieldX constant and inside ConfigStructure.

Serve.go

Intimidating but the main entry point is Run(). What it does is:

  • Check if telemetry should be on, and if so start it (separate Go routine)
  • Connect to the database, could be multiple as things grow
  • Start the HTTP listener (separate Go routine)
  • Start listening to HUP signal for restart (separate Go routine)
  • Start a blocking listen for SIGINT and SIGTERM, and if received gracefully shut down and exit.
Functions you're likely to need to edit

Only two functions are likely to need changing here. Of course, if you add new flags you might need to tweak existing code, but the main suspects are:

addSecMiddlewares

These are the middlewares added to the secure path, a likely thing to add is a JWT parser so that you can verify a user, and potentially add user information to the handler context being passed around to all handlers and service functions.

addPublicMiddlewares

Currently only has the context middleware, you're likely to want at least a CORS middleware here as well, but it of course depends on your use case.

Router

The router is done in setupRouter, the actual magic happens in the router

Documentation

Index

Constants

View Source
const (
	FieldServiceName = "service-name"
	FieldDBType      = "db-type"
	FieldDBAddr      = "db-addr"
	FieldDBPass      = "db-pass"

	FieldAddress           = "http-address"
	FieldPort              = "http-port"
	FieldReadTimeout       = "http-read-timeout"
	FieldReadHeaderTimeout = "http-read-header-timeout"
	FieldIdleTimeout       = "http-idle-timeout"
	FieldMaxHeaderSize     = "http-max-header-size"
	FieldWriteTimeout      = "http-write-timeout"

	FieldTelemetry        = "telemtry"
	FieldTelemetryAddress = "telemetry-address"
	FieldTelemetryPort    = "telementry-port"

	FieldMiddlewareTraceIDHeader = "mid-trace-id-header"
	FieldMiddlewareURLPath       = "mid-url-path"

	FieldMiddlewareCors        = "mid-cors"
	FieldMiddlewareCorsOrigins = "mid-cors-origins"
	FieldMiddlewareCorsMethods = "mid-cors-methods"
	FieldMiddlewareCorsHeaders = "mid-cors-headers"

	FieldMiddlewarePromSize  = "mid-prom-size"
	FieldMiddlewarePromTime  = "mid-prom-timer"
	FieldMiddlewarePromCount = "mid-prom-counter"
)

Variables

View Source
var ConfigStructure = config.Configs{
	Ints: []config.IntConf{
		{Name: FieldPort, Desc: "Public facing http port to listen to", Def: server.DefaultPort},
		{Name: FieldTelemetryPort, Desc: "Telemetry http port to listen to", Def: server.DefaultTelemetryPort},
		{Name: FieldMaxHeaderSize, Desc: "Max header size of http requests", Def: server.DefaultMaxHeaderBytes},
	},
	Durations: []config.DurationConf{
		{Name: FieldIdleTimeout, Desc: "How long are idle keep-alive connections allowed?", Def: server.DefaultIdleTimeout},
		{Name: FieldReadTimeout, Desc: "How long to wait for data while reading HTTP requests?", Def: server.DefaultReadTimeout},
		{Name: FieldReadHeaderTimeout, Desc: "How long to wait for reading the http headers?", Def: server.DefaultReadHeaderTimeout},
		{Name: FieldWriteTimeout, Desc: "How long are HTTP writes allowed to take?", Def: server.DefaultWriteTimeout},
	},
	Strings: []config.StringConf{
		{Name: FieldServiceName, Desc: "Name of the service. Used for path and prometheus", Def: "myService"},
		{Name: FieldAddress, Desc: "Public facing address to bind to, empty for all", Def: ""},
		{Name: FieldTelemetryAddress, Desc: "Telemetry address to bind to, empty for all", Def: ""},
		{Name: FieldTelemetry, Desc: "What type of telemetry to use. prometheus|otel|none", Def: "prometheus"},
		{Name: FieldMiddlewareTraceIDHeader, Desc: "Set traceID header to be able to follow a individual request/session through the logs", Def: ""},
		{Name: FieldDBType, Desc: "What key value store to use. badger|redis", Def: "badger"},
		{Name: FieldDBAddr, Desc: "DB address", Def: filepath.Join(os.TempDir(), "http-skeleton-badger")},
		{Name: FieldDBPass, Desc: "DB password", Def: ""},
	},
	Bools: []config.BoolConf{
		{Name: FieldMiddlewareCors, Desc: "Activate CORS to allow cross domain requests from browsers", Def: true},
		{Name: FieldMiddlewareURLPath, Desc: "Add request path to the logs", Def: false},
		{Name: FieldMiddlewarePromSize, Desc: "Instrument response sizes, requires prometheus turned on to be active", Def: true},
		{Name: FieldMiddlewarePromTime, Desc: "Instrument response times, requires prometheus turned on to be active", Def: true},
		{Name: FieldMiddlewarePromCount, Desc: "Instrument request counter, requires prometheus turned on to be active", Def: true},
	},
	StringArrays: []config.StringArrayConf{
		{Name: FieldMiddlewareCorsOrigins, Desc: "List of allowed domains for CORS. See https://pkg.go.dev/github.com/jub0bs/fcors#FromOrigins for format. At least one to have CORS active.", Def: []string{"https://example.com"}},
		{Name: FieldMiddlewareCorsMethods, Desc: "List of allowed verbs for CORS requests. One or multiple of GET,HEAD,POST,PUT,PATCH,DELETE,CONNECT,OPTIONS,TRACE", Def: []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete}},
		{Name: FieldMiddlewareCorsHeaders, Desc: "List of allowed headers, for example Authorization", Def: []string{}},
	},
}

Functions

This section is empty.

Types

type IServe

type IServe interface {
}

type Serve

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

func (*Serve) Run

func (s *Serve) Run()

Run calls Start and waits for a shutdown signal

func (*Serve) Start

func (s *Serve) Start()

Start starts the http server(s) and sets things up. It listens for SIGHUP and restarts if received

func (*Serve) Stop

func (s *Serve) Stop()

Stop gracefully shuts down anything started.

type Shutdown

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

type ShutdownFunc

type ShutdownFunc func(ctx context.Context) error

Jump to

Keyboard shortcuts

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