wess

package module
v1.0.9 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2024 License: MIT Imports: 19 Imported by: 1

README

wess

GoVersion GoDoc License Report

master Test codecov

dev Test codecov

WEb Simple Server

Running a WESS instance

Basics

Running a WESS instance is very easy, by default on port 80 all interfaces:

func main() {
  server := wess.NewServer(wess.ServerOptions{})
  shutdown, stop, _ := server.Start(context.Background())
  err = <-shutdown
}

err will contain the eventual errors when the server shuts down and stop is a chan that allows you to stop the server programmatically.

Of course that server does not serve much...

You can change the port, give an address to listen to:

server := wess.NewServer(wess.ServerOptions{
  Address: "192.168.1.1",
  Port:    8000,
})

You can also overwrite the default handlers used when a route is not found or a method is not Allowed:

server := wess.NewServer(wess.ServerOptions{
  Logger:                  log,
  NotFoundHandler:         notFoundHandler(log),
  MethodNotAllowedHandler: methodNotAllowedHandler(Options),
})

If you add a ProbePort, wess will also serve some health routes for Kubernetes or other probe oriented environments. These following routes are available:

  • /healthz/liveness
  • /healthz/readiness

You can change the root path from /healthz with the HealthRootPath option:

server := wess.NewServer(wess.ServerOptions{
  ProbePort:      32000,
  HealthRootPath: "/probez",
})

Note: If the probe port is the same as the main port, all routes are handled by the same web server. Otherwise, 2 web servers are instantiated.

Adding routes

You can add a simple route with AddRoute and AddRouteWithFunc:

server.AddRoute("GET", "/something", somethingHandler)
server.AddRouteWithFunc("GET", "/somewhere", somewhereFunc)

The first method accepts a http.Handler while the second accepts a http.HandlerFunc.

Here is an embedded example:

server.AddRouteWithFunc("GET", "/hello", func(w http.ResponseWriter, r *http.Request) {
  log := logger.Must(logger.FromContext(r.Context())).Child(nil, "hello")

  w.WriteHeader(http.StatusOK)
  w.Header().Add("Content-Type", "text/plain")
  written, _ := w.Write([]byte("Hello, World!"))
  log.Debugf("Witten %d bytes", written)
})

For more complex cases, you can ask for a SubRouter:

main() {
  // ...
  APIRoutes(server.SubRouter("/api/v1"), dbClient)
}

func APIRoutes(router *mux.Router, db *db.Client) {
  router.Method("GET").Path("/users").Handler(GetUsers(db))
}

(See the vue-with-api sample for a complete implementation)

Adding a frontend

To add a frontend, the easiest is to use vite. You can also use webpack. As long as you can bundle all the distribution files in the same folder.

In the folder you want to write your wess application, create the frontend instance (Here, using Vue. You can also use react):

npm create vite@latest frontent -- --template vue

or with yarn:

yarn create vite frontend --template vue

During the development phase of the frontend, you should run the dev server directly from the frontend folder:

cd frontend
npm install
npm run dev

or with yarn:

cd frontend
yarn install
yarn dev

Once the frontend is done, build the project:

npm run build

or with yarn:

yarn build

And add a wess server in the parent folder of the frontend:

var (
  //go:embed all:frontend/dist
  frontendFS embed.FS
)

func main() {
  server := wess.NewServer(wess.ServerOptions{
    Port: 8080,
  })
  _ = server.AddFrontend("/", frontendFS, "frontend/dist")
  shutdown, stop, _ := server.Start(context.Background())
  <-shutdown
}

Then, create a single binary that will contain the server and the frontend code:

go build .

That's it, you now have a single small executable file!

Running the samples

The samples folder contains a few examples of wess in action.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var VERSION = "1.0.9"

VERSION is the version of the package

Functions

This section is empty.

Types

type CorsLogger added in v1.0.2

type CorsLogger struct {
	Logger *logger.Logger
}

CORS Logger

func (CorsLogger) Printf added in v1.0.2

func (corsLogger CorsLogger) Printf(format string, args ...interface{})

type Server

type Server struct {
	// ShutdownTimeout is the maximum amount of time to wait for the
	// server to shutdown. Default: 15 seconds
	ShutdownTimeout time.Duration
	// contains filtered or unexported fields
}

Server defines a Web Server

func NewServer

func NewServer(options ServerOptions) *Server

NewServer creates a new Web Server

func (Server) AddFrontend

func (server Server) AddFrontend(path string, rootFS fs.FS, rootPath string) error

AddFrontend adds a frontend to the server

The frontend is a static website that will be served by the server.

func (Server) AddRoute

func (server Server) AddRoute(method, path string, handler http.Handler)

AddRoute adds a route to the server

func (Server) AddRouteWithFunc

func (server Server) AddRouteWithFunc(method, path string, handlerFunc http.HandlerFunc)

AddRouteWithFunc adds a route to the server

func (Server) IsReady

func (server Server) IsReady() bool

IsReady tells if the server is ready

func (*Server) Start

func (server *Server) Start(context context.Context) (shutdown chan error, stop chan os.Signal, err error)

Start starts the server

Callers should wait on the returned shutdown channel.

Callers can stop the server programatically by sending a signal on the returned stop channel.

func (Server) SubRouter

func (server Server) SubRouter(path string) *mux.Router

SubRouter creates a subrouter

type ServerOptions

type ServerOptions struct {
	Address   string // The address to listen on, Default: all interfaces
	Port      int    // The port to listen on, Default: 80
	ProbePort int    // The port to listen on for the health probe, Default: 0 (disabled)

	// The gorilla/mux router to use.
	// If not specified, a new one is created.
	Router *mux.Router

	// HealthRootPath is the root path for the health probe.
	// By default: "/healthz"
	HealthRootPath string

	// DisableGeneralOptionsHandler, if true, passes "OPTIONS *"
	// requests to the Handler, otherwise responds with 200 OK
	// and Content-Length: 0.
	DisableGeneralOptionsHandler bool

	// TLSConfig optionally provides a TLS configuration for use
	// by ServeTLS and ListenAndServeTLS. Note that this value is
	// cloned by ServeTLS and ListenAndServeTLS, so it's not
	// possible to modify the configuration with methods like
	// tls.Config.SetSessionTicketKeys. To use
	// SetSessionTicketKeys, use Server.Serve with a TLS Listener
	// instead.
	TLSConfig *tls.Config

	// ReadTimeout is the maximum duration for reading the entire
	// request, including the body. A zero or negative value means
	// there will be no timeout.
	//
	// Because ReadTimeout does not let Handlers make per-request
	// decisions on each request body's acceptable deadline or
	// upload rate, most users will prefer to use
	// ReadHeaderTimeout. It is valid to use them both.
	ReadTimeout time.Duration

	// ReadHeaderTimeout is the amount of time allowed to read
	// request headers. The connection's read deadline is reset
	// after reading the headers and the Handler can decide what
	// is considered too slow for the body. If ReadHeaderTimeout
	// is zero, the value of ReadTimeout is used. If both are
	// zero, there is no timeout.
	ReadHeaderTimeout time.Duration

	// WriteTimeout is the maximum duration before timing out
	// writes of the response. It is reset whenever a new
	// request's header is read. Like ReadTimeout, it does not
	// let Handlers make decisions on a per-request basis.
	// A zero or negative value means there will be no timeout.
	WriteTimeout time.Duration

	// IdleTimeout is the maximum amount of time to wait for the
	// next request when keep-alives are enabled. If IdleTimeout
	// is zero, the value of ReadTimeout is used. If both are
	// zero, there is no timeout.
	IdleTimeout time.Duration

	// ShutdownTimeout is the maximum amount of time to wait for the
	// server to shutdown. Default: 15 seconds
	ShutdownTimeout time.Duration

	// MaxHeaderBytes controls the maximum number of bytes the
	// server will read parsing the request header's keys and
	// values, including the request line. It does not limit the
	// size of the request body.
	// If zero, DefaultMaxHeaderBytes is used.
	MaxHeaderBytes int

	// TLSNextProto optionally specifies a function to take over
	// ownership of the provided TLS connection when an ALPN
	// protocol upgrade has occurred. The map key is the protocol
	// name negotiated. The Handler argument should be used to
	// handle HTTP requests and will initialize the Request's TLS
	// and RemoteAddr if not already set. The connection is
	// automatically closed when the function returns.
	// If TLSNextProto is not nil, HTTP/2 support is not enabled
	// automatically.
	TLSNextProto map[string]func(*http.Server, *tls.Conn, http.Handler)

	// ConnState specifies an optional callback function that is
	// called when a client connection changes state. See the
	// ConnState type and associated constants for details.
	ConnState func(net.Conn, http.ConnState)

	// Logger is the logger used by this server
	// If not specified, nothing gets logged.
	Logger *logger.Logger

	// ErrorLog specifies an optional logger for errors accepting
	// connections, unexpected behavior from handlers, and
	// underlying FileSystem errors.
	// If nil, logging is done via the Logger defined above.
	ErrorLog *log.Logger

	// BaseContext optionally specifies a function that returns
	// the base context for incoming requests on this server.
	// The provided Listener is the specific Listener that's
	// about to start accepting requests.
	// If BaseContext is nil, the default is context.Background().
	// If non-nil, it must return a non-nil context.
	BaseContext func(net.Listener) context.Context

	// ConnContext optionally specifies a function that modifies
	// the context used for a new connection c. The provided ctx
	// is derived from the base context and has a ServerContextKey
	// value.
	ConnContext func(ctx context.Context, c net.Conn) context.Context

	// Configurable Handler to be used when no route matches.
	NotFoundHandler http.Handler

	// Configurable Handler to be used when the request method
	// does not match the route.
	MethodNotAllowedHandler http.Handler

	// AllowedCORSHeaders is the list of allowed headers
	AllowedCORSHeaders []string

	// AllowedCORSMethods is the list of allowed methods
	AllowedCORSMethods []string

	// AllowedCORSOrigins is the list of allowed origins
	AllowedCORSOrigins []string

	// ExposedCORSHeader is the list of headers that are safe to expose to
	// the API of a CORS API specification
	ExposedCORSHeaders []string

	// CORSMaxAge indicates how long (in seconds) the results of a preflight
	// request can be cached
	CORSMaxAge time.Duration

	// CORSAllowCredentials indicates whether the request can include user credentials
	// like cookies, HTTP authentication or client side SSL certificates
	CORSAllowCredentials bool

	// AllowOriginFunc is a custom function to validate the origin
	AllowOriginFunc func(origin string) bool

	// CPRSAllowPrivateNetwork indicates whether to acceptrequests
	// over a private network
	CORSAllowPrivateNetwork bool

	// CORSOptionsPasthrough instructs preflight to let other potential next handlers to
	// process the OPTIONS method. Turn this on if your application handles OPTIONS.
	CORSOptionsPasthrough bool

	// CORSOptionsSuccessStatus provides a status code to use for
	// successful OPTIONS requests, instead of http.StatusNoContent (204)
	CORSOptionsSuccessStatus int
}

ServerOptions defines the options for the server

Directories

Path Synopsis
samples
vue
vue-docker Module

Jump to

Keyboard shortcuts

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