nath

package module
v0.0.0-...-6f641eb Latest Latest
Warning

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

Go to latest
Published: Mar 4, 2023 License: MIT Imports: 40 Imported by: 0

README

Nath

Nath is a set of conveniences for quickly setting up a server with OpenAPI support, tracing and telemety.

Nath heavily uses other libraries, eg. Echo, OpenTelemetry, etc. See credits below.

Features

  • Define OpenAPI specs with code
  • OpenTelemetry support
  • Prometheus metrics
  • Integrated job queue with Asynq
  • OIDC authentication
  • Migrations with Goose

Usage

Simple example
nath.
	New(
		nath.WithOpts(nath.ServerOptions{
			Port:       port,
			ID:         os.Getenv("ID"), // used for prometheus and jaeger registration
			HideBanner: true,
		}),
		nath.WithOIDC(nath.OIDCOptions{
			Issuer:            "https://id.example.org",
			AuthURI:           "protocol/openid-connect/auth",
			TokenURI:          "protocol/openid-connect/token",
			ClientID:          "client",
			Secret:            "1234567890",
			KeysURI:           "protocol/openid-connect/certs",
			RedirectURI:       fmt.Sprintf("http://localhost:%d/api/auth/code", port),
			ClientRedirectURI: fmt.Sprintf("http://localhost:%d/api/auth/userinfo", port),
		}),
		nath.WithDefaultMiddleware(),
		nath.WithMetrics(),
	).
	Routes(example.NewResource(example.NewService(example.WithRepository())).Routes()).
	Run()
With migrations etc.
package main

import (
	"embed"
	"flag"
	"fmt"
	"os"
	"strconv"

	"github.com/joho/godotenv"
	"github.com/khvh/nath"
	"github.com/khvh/nath/logger"
	"github.com/khvh/nath/migration"
	"github.com/khvh/thw/db"
	"github.com/khvh/thw/internal/question"
	"github.com/rs/zerolog/log"
)

//go:embed migrations/*.sql
var migrations embed.FS

func main() {
	err := godotenv.Load()
	if err != nil {
		log.Trace().Msg("Error loading .env")
	}

	defaultVal, err := strconv.Atoi(os.Getenv("DEV"))
	if err != nil {
		defaultVal = 1
	}

	logger.Init(defaultVal, defaultVal <= 0)

	flagSet := flag.NewFlagSet("api", flag.ExitOnError)

	err = flagSet.Parse(os.Args[1:])
	if err != nil {
		log.Panic().Err(err).Send()
	}

	args := flagSet.Args()

	if len(args) > 0 && (args[0] == "status" || args[0] == "up" || args[0] == "down") {
		migration.Init(migrations, args, migration.DialectSQLite, os.Getenv("DSN"))
	} else {
		port, err := strconv.Atoi(os.Getenv("PORT"))
		if err != nil {
			port = 3000
		}

		err = db.Init(os.Getenv("DSN"))
		if err != nil {
			log.Fatal().Err(err).Send()
		}

		nath.
			New(
				nath.WithOpts(nath.ServerOptions{
					Port:       port,
					ID:         os.Getenv("ID"), // used for prometheus and jaeger registration
					HideBanner: true,
				}),
				nath.WithOIDC(nath.OIDCOptions{
					Issuer:            "https://id.example.org",
					AuthURI:           "protocol/openid-connect/auth",
					TokenURI:          "protocol/openid-connect/token",
					ClientID:          "client",
					Secret:            "1234567890",
					KeysURI:           "protocol/openid-connect/certs",
					RedirectURI:       fmt.Sprintf("http://localhost:%d/api/auth/code", port),
					ClientRedirectURI: fmt.Sprintf("http://localhost:%d/api/auth/userinfo", port),
				}),
				nath.WithDefaultMiddleware(),
				nath.WithMetrics(),
			).
			Routes(example.NewResource(example.NewService(example.WithRepository())).Routes()).
			Run()
	}
}

Credits

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Body

func Body[T any](c echo.Context) *T

Body binds echo.Context.Body to a provided value, returns nil on error

func BodyP

func BodyP[T any](c echo.Context) *T

BodyP binds echo.Context.Body to a provided value, panics on error

Types

type CodeResponse

type CodeResponse struct {
	AccessToken      string `json:"access_token" url:"accessToken"`
	ExpiresIn        int    `json:"expires_in" url:"expiresIn"`
	RefreshExpiresIn int    `json:"refresh_expires_in" url:"refresh_expires_in"`
	RefreshToken     string `json:"refresh_token" url:"refresh_token"`
	TokenType        string `json:"token_type" url:"token_type"`
	NotBeforePolicy  int    `json:"not-before-policy" url:"notBeforePolicy"`
	SessionState     string `json:"session_state" url:"sessionState"`
	Scope            string `json:"scope" url:"scope"`
}

CodeResponse == oidc successful login data

type Configuration

type Configuration func(s *Server) error

Configuration ...

func WithDefaultMiddleware

func WithDefaultMiddleware() Configuration

WithDefaultMiddleware ...

func WithFrontend

func WithFrontend(data *embed.FS, dir string) Configuration

WithFrontend ...

func WithMetrics

func WithMetrics() Configuration

WithMetrics ...

func WithMiddleware

func WithMiddleware(middleware ...fiber.Handler) Configuration

WithMiddleware add middleware to Echo

func WithOIDC

func WithOIDC(opts OIDCOptions) Configuration

WithOIDC enables OpenID Connect auth

func WithOpts

func WithOpts(opts ...ServerOptions) Configuration

WithOpts create Server with options

func WithQueue

func WithQueue(url, pw string, opts queue.Queues, fn func(q *queue.Queue)) Configuration

WithQueue ...

func WithTracing

func WithTracing(url ...string) Configuration

WithTracing ...

type OIDCOptions

type OIDCOptions struct {
	Issuer            string `json:"issuer,omitempty" yaml:"issuer,omitempty"`
	AuthURI           string `json:"authUri,omitempty" yaml:"authUri,omitempty"`
	KeysURI           string `json:"keysURI,omitempty" yaml:"keysURI,omitempty"`
	TokenURI          string `json:"tokenURI,omitempty" yaml:"tokenURI,omitempty"`
	ClientID          string `json:"clientId,omitempty" yaml:"clientId,omitempty"`
	Secret            string `json:"secret,omitempty" yaml:"secret,omitempty"`
	RedirectURI       string `json:"redirectURI,omitempty" yaml:"redirectURI,omitempty"`
	ClientRedirectURI string `json:"clientRedirectURI,omitempty" yaml:"clientRedirectURI,omitempty"`
}

OIDCOptions ...

type Route

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

Route ...

func Delete

func Delete[O any](path string, handler ...fiber.Handler) *Route

Delete route constructor

func Get

func Get[O any](path string, handler ...fiber.Handler) *Route

Get route constructor

func Group

func Group(path string, rts ...*Route) (string, []*Route)

Group returns path, rts for nath.Server Group

func Patch

func Patch[O any, B any](path string, handler ...fiber.Handler) *Route

Patch route constructor

func Post

func Post[O any, B any](path string, handler ...fiber.Handler) *Route

Post route constructor

func Put

func Put[O any, B any](path string, handler ...fiber.Handler) *Route

Put route constructor

func (*Route) WithAPIAuth

func (r *Route) WithAPIAuth() *Route

WithAPIAuth mark spec that it needs to be authenticated with api key

func (*Route) WithAuth

func (r *Route) WithAuth() *Route

WithAuth mark spec that it needs to be authenticated

func (*Route) WithQuery

func (r *Route) WithQuery(obj any) *Route

WithQuery ...

func (*Route) WithSpecOpts

func (r *Route) WithSpecOpts(s ...spec.Opt) *Route

WithSpecOpts adds additional spec values to Spec

type Server

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

Server ...

func New

func New(cfgs ...Configuration) *Server

New constructs Server

func (*Server) Group

func (s *Server) Group(path string, routes ...*Route) *Server

Group groups routes

func (*Server) Route

func (s *Server) Route(routes ...*Route) *Server

Route ...

func (*Server) Routes

func (s *Server) Routes(path string, routes []*Route) *Server

Routes registers routes for path

func (*Server) Run

func (s *Server) Run()

Run starts the server

func (*Server) ValidateJWTRequest

func (s *Server) ValidateJWTRequest(ctx context.Context, req *http.Request) (map[string]any, error)

ValidateJWTRequest validates jwt against jwks etc

func (*Server) ValidateJWTToken

func (s *Server) ValidateJWTToken(ctx context.Context, token string) (map[string]any, error)

ValidateJWTToken validates jwt against jwks etc

type ServerOptions

type ServerOptions struct {
	ID            string `json:"id,omitempty" yaml:"id,omitempty"`
	Description   string `json:"description,omitempty" yaml:"description,omitempty"`
	Version       string `json:"version,omitempty" yaml:"version,omitempty"`
	Host          string `json:"host,omitempty" yaml:"host,omitempty"`
	Port          int    `json:"port,omitempty" yaml:"port,omitempty"`
	HideBanner    bool   `json:"hideBanner,omitempty" yaml:"hideBanner,omitempty"`
	RequestLogger bool   `json:"requestLogger,omitempty" yaml:"requestLogger,omitempty"`
}

ServerOptions ...

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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