simba

package module
v0.16.1 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2025 License: MIT Imports: 28 Imported by: 0

README

Simba

Simba is a type-safe HTTP router framework for Go that makes building REST APIs simple and enjoyable. It provides strong type safety through generics and a clean, intuitive API for handling HTTP requests. It also automatically generates OpenAPI (v3.1) documentation for your API.

Features

  • Type-safe routing with Go generics
  • Built-in authentication support
  • Middleware support
  • Strong request/response typing
  • Automatic OpenAPI documentation generation

Installation

go get -u github.com/sillen102/simba

Quick Start

Here's a simple example showing how to create a basic HTTP server with Simba:

package main

import (
    "context"
    "fmt"
    "net/http"
    "github.com/sillen102/simba"
)

type RequestBody struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

type ResponseBody struct {
    Message string `json:"message"`
}

func handler(ctx context.Context, req *simba.Request[RequestBody, simba.NoParams]) (*simba.Response[ResponseBody], error) {

    // Access the request body fields
    // req.Body.Age
    // req.Body.Name

    // Access the request cookies
    // req.Cookies

    // Access the request headers
    // req.Headers

    return &simba.Response[ResponseBody]{
        Headers: map[string][]string{"My-Header": {"header-value"}},
        Cookies: []*http.Cookie{{Name: "My-Cookie", Value: "cookie-value"}},
        Body: ResponseBody{
            Message: fmt.Sprintf("Hello %s, you are %d years old", req.Body.Name, req.Body.Age),
        },
        Status: http.StatusOK, // Can be omitted, defaults to 200 if there's a body, 204 if there's no body
    }, nil
}

func main() {
    // Using simba.Default() will use the default options for logger and request validation,
    // add default middleware like panic recovery and request id and add some endpoints like /health
    //
    // If you wish to build up your own router without any default middleware etc., use simba.New()
    app := simba.Default()
    app.Router.POST("/users", simba.JsonHandler(handler))
    app.Start()
}

Parameters

Handle parameters with type safety and validation support using go-playground validator:

type Params struct {
    UserID    string `path:"userId"`
    Name      string `query:"name" validate:"required"`
    Age       int    `header:"age" validate:"required"`
    SessionID string `cookie:"session_id" validate:"required"`
    Page      int64  `query:"page" validate:"omitempty,min=0" default:"0"`
    Size      int64  `query:"size" validate:"omitempty,min=0" default:"10"`
}

func getUser(ctx context.Context, req *simba.Request[simba.NoBody, Params]) (*simba.Response[respBody], error) {
    userID := req.Params.UserID
    name := req.Params.Name
    age := req.Params.Age

    // ... handle the request
}

app.GET("/users/{userId}", simba.JsonHandler(getUser))

Logging

Simba relies on slog to handle logging. If no logger is provided slog.Default will be used. If you use the Default constructor a slog logger will be injected into the request context for all requests. To access the injected logger, use the logging.From function in the logging package.

Example:

func handler(ctx context.Context, req *simba.Request[simba.NoBody, simba.NoParams]) (*simba.Response[respBody], error) {
    logger := logging.From(ctx)
    logger.Info("handling request")
    // ... handle the request
}

Configuration

Customize behavior with options functions:

app := simba.New(
    settings.WithServerHost("localhost"),
    settings.WithServerPort(8080),
})

Or use default and change a single one or few of the settings:

app := simba.Default()
app.Settings.Server.Port = 8080

Error Handling

Simba provides automatic error handling with standardized JSON responses. All errors are automatically wrapped and returned in a consistent format:

{
  "timestamp": "2024-12-04T20:28:33.852965Z",
  "status": 400,
  "error": "Bad Request",
  "path": "/api/resource",
  "method": "POST",
  "requestId": "40ad8bb4-215a-4748-8a7f-9e236d988c5b",
  "message": "request validation failed, 1 validation error",
  "validationErrors": [
    {
      "parameter": "email",
      "type": "body",
      "message": "'notanemail' is not a valid email address"
    }
  ]
}

Middleware

Simba supports middleware. Simply create a function that takes a handler and returns a handler and register it with the Use method on the router:

func myMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        r.Header.Set("X-Middleware", "123") // Here we simply add a header to every request
        next.ServeHTTP(w, r) // And the proceed to the next handler
    })
}

app.Router.Use(myMiddleware)

Authentication

Simba provides built-in support for authentication of the handlers by providing an authentication function signature respectively for Basic Auth, API Key Auth, and Bearer Token Auth. It uses generics so everything is type safe.

Notice that the authFunc signature differs slightly between the different authentication methods.

Basic Auth
type User struct {
    ID   string
    Name string
}

// authFunc is should use the basic auth function signature:
// BasicAuthHandlerFunc[AuthModel any] func(ctx context.Context, username, password string) (*AuthModel, error)
func authFunc(ctx context.Context, username, password string) (*User, error) {
    if !(username == "john" && password == "password") {
        return nil, simbaErrors.NewHttpError(http.StatusUnauthorized, "invalid username or password", nil)
    }

    return &User{
        ID:   1,
        Name: "John Doe",
        Role: "admin",
    }, nil
}

var authHandler = simba.BasicAuth[User](
    authFunc,
    simba.BasicAuthConfig{
        Name:        "admin",
        Description: "admin access only",
    }, 
)

// @ID authenticatedHandler
// @Summary authenticated handler
// @Description this is a handler that requires authentication
func authenticatedHandler(ctx context.Context, req *simbaModels.Request[simbaModels.NoBody, simbaModels.NoParams], user *User) (*simbaModels.Response[ResponseBody], error) {

    // Access the request cookies
    // req.Cookies
    
    // Access the request headers
    // req.Headers
    
    return &simbaModels.Response[ResponseBody]{
        Body: ResponseBody{
            Message: fmt.Sprintf("Hello %s, you are an %s", user.Name, user.Role),
        },
    }, nil
}

app := simba.Default()
app.GET("/users/{userId}", simba.AuthJsonHandler(getUser, authHandler))
API Key Auth
type User struct {
    ID   string
    Name string
}

// authFunc should use the API key auth function signature:
// APIKeyAuthHandlerFunc[AuthModel any] func(ctx context.Context, apiKey string) (*AuthModel, error)
func authFunc(ctx context.Context, apiKey string) (*User, error) {
	if apiKey != "valid-key" {
		return nil, simbaErrors.NewHttpError(http.StatusUnauthorized, "invalid api key", nil)
	}

	return &User{
		ID:   1,
		Name: "John Doe",
		Role: "admin",
	}, nil
}

var authHandler = simba.APIKeyAuth[User](
	authFunc,
	simba.APIKeyAuthConfig{
		Name:        "admin",
		FieldName:   "sessionid",
		In:          openapi.InHeader,
		Description: "admin access only",
	},
)

// @ID authenticatedHandler
// @Summary authenticated handler
// @Description this is a handler that requires authentication
func authenticatedHandler(ctx context.Context, req *simbaModels.Request[simbaModels.NoBody, simbaModels.NoParams], user *User) (*simbaModels.Response[ResponseBody], error) {

    // Access the request cookies
    // req.Cookies
    
    // Access the request headers
    // req.Headers
    
    return &simbaModels.Response[ResponseBody]{
        Body: ResponseBody{
            Message: fmt.Sprintf("Hello %s, you are an %s", user.Name, user.Role),
        },
    }, nil
}

app := simba.Default()
app.GET("/users/{userId}", simba.AuthJsonHandler(getUser, authHandler))
Bearer Token Auth
type User struct {
    ID   string
    Name string
}

// authFunc should use the Bearer token auth function signature:
// BearerAuthHandlerFunc[AuthModel any] func(ctx context.Context, token string) (*AuthModel, error)
func authFunc(ctx context.Context, token string) (*User, error) {
    if token != "token" {
        return nil, simbaErrors.NewHttpError(http.StatusUnauthorized, "invalid token", nil)
    }

    return &User{
        ID:   1,
        Name: "John Doe",
        Role: "admin",
    }, nil
}

var authHandler = simba.BearerAuth[User](
    BearerAuthFunc,
    simba.BearerAuthConfig{
        Name:        "admin",
        Format:      "jwt",
        Description: "Bearer token",
    },
)

// @ID authenticatedHandler
// @Summary authenticated handler
// @Description this is a handler that requires authentication
func authenticatedHandler(ctx context.Context, req *simbaModels.Request[simbaModels.NoBody, simbaModels.NoParams], user *User) (*simbaModels.Response[ResponseBody], error) {

    // Access the request cookies
    // req.Cookies
    
    // Access the request headers
    // req.Headers
    
    return &simbaModels.Response[ResponseBody]{
        Body: ResponseBody{
            Message: fmt.Sprintf("Hello %s, you are an %s", user.Name, user.Role),
        },
    }, nil
}

app := simba.Default()
app.GET("/users/{userId}", simba.AuthJsonHandler(getUser, authHandler))

OpenAPI Documentation Generation

Simba will automatically generate OpenAPI documentation for your APIs. By default, the OpenAPI documentation is available at /openapi.yml. And the Scalar UI is available at /docs. You can change these paths by providing a custom path in the application settings.

app := simba.Default()
app.Settings.Docs.OpenAPIFileType = mimetypes.ApplicationJSON
app.Settings.Docs.OpenAPIPath = "/swagger.json"
app.Settings.Docs.DocsPath = "/swagger-ui"

If you want to you can disable the OpenAPI documentation generation by setting the GenerateOpenAPIDocs to false in application settings.

app := simba.Default()
app.Settings.Docs.GenerateOpenAPIDocs = false

You can also generate the OpenAPI documentation yaml file but not serve any UI (in case you want to use a different or customized UI) by setting the MountDocsEndpoint to false in the application settings.

app := simba.Default()
app.Settings.Docs.MountDocsEndpoint = false
Customizing OpenAPI Documentation

By default, Simba will generate OpenAPI documentation based on the handler you have registered. It will use the package name to group the endpoints, and the handler name to generate the operation id, summary for the endpoint and the comment you have on your handler to generate a description. This makes it easy to generate OpenAPI documentation without any additional configuration. Just organize your handlers in packages, name them well and add descriptive comments.

If you want greater control over the generated API documentation you can customize the OpenAPI documentation by providing tags in the comment of your handler. Simba uses openapi-go under the hood to generate the documentation.

type reqParams struct {
    ID       string `path:"id" example:"XXX-XXXXX"`
    Locale   string `query:"locale" pattern:"^[a-z]{2}-[A-Z]{2}$"`
    MyHeader string `header:"My-Header" required:"true"`
    MyCookie string `cookie:"My-Cookie" required:"true"`
}

type reqBody struct {
    Title  string `json:"string" example:"My Order"`
    Amount int    `json:"amount" example:"100" required:"true"`
    Items  []struct {
        Count uint   `json:"count" example:"2"`
        Name  string `json:"name" example:"Item 1"`
    } `json:"items"`
}

// @ID get-user
// @Tag Users
// @Summary Get user
// @Description Get a user by ID (can span across multiple lines)
// @Error 404 User not found
func getUser(ctx context.Context, req *simba.Request[reqBody, reqParams], user *User) (*simba.Response[respBody], error) {
    // ... handle the request
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

All dependencies are under their respective licenses, which can be found in their repositories via the go.mod file.

Documentation

Index

Constants

View Source
const (
	AuthHeader   = "Authorization"
	BasicPrefix  = "Basic "
	BearerPrefix = "Bearer "
)

Variables

This section is empty.

Functions

func MapValidationMessage added in v0.10.6

func MapValidationMessage(e validator.FieldError, value string) string

MapValidationMessage returns appropriate error message based on the validation tag

func ValidateStruct added in v0.10.4

func ValidateStruct(request any, paramType simbaErrors.ParameterType) simbaErrors.ValidationErrors

ValidateStruct is a helper function for validating requests using the validator package. If the request is nil, it will return nil. If the request is valid, it will return an empty slice of ValidationErrors. If the request is invalid, it will return a slice of ValidationErrors containing the validation errors for each field.

Types

type APIKeyAuthConfig added in v0.13.0

type APIKeyAuthConfig struct {
	Name        string
	FieldName   string
	In          oapi.In
	Description string
}

type APIKeyAuthHandlerFunc added in v0.16.0

type APIKeyAuthHandlerFunc[AuthModel any] func(ctx context.Context, apiKey string) (*AuthModel, error)

APIKeyAuthHandlerFunc is a function that handles API key authentication. This is the function that should be implemented by the user. It should return the user model if the API key is valid, otherwise it should return an error.

type APIKeyAuthType added in v0.13.0

type APIKeyAuthType[AuthModel any] struct {
	Name        string
	FieldName   string
	In          oapi.In
	Description string
	Handler     APIKeyAuthHandlerFunc[AuthModel]
}

func (APIKeyAuthType[AuthModel]) GetDescription added in v0.13.0

func (t APIKeyAuthType[AuthModel]) GetDescription() string

func (APIKeyAuthType[AuthModel]) GetFieldName added in v0.13.0

func (t APIKeyAuthType[AuthModel]) GetFieldName() string

func (APIKeyAuthType[AuthModel]) GetFormat added in v0.13.0

func (t APIKeyAuthType[AuthModel]) GetFormat() string

func (APIKeyAuthType[AuthModel]) GetHandler added in v0.13.0

func (t APIKeyAuthType[AuthModel]) GetHandler() AuthHandlerFunc[AuthModel]

func (APIKeyAuthType[AuthModel]) GetIn added in v0.13.0

func (t APIKeyAuthType[AuthModel]) GetIn() oapi.In

func (APIKeyAuthType[AuthModel]) GetName added in v0.13.0

func (t APIKeyAuthType[AuthModel]) GetName() string

func (APIKeyAuthType[AuthModel]) GetType added in v0.13.0

func (t APIKeyAuthType[AuthModel]) GetType() openapiModels.AuthType

type Application

type Application struct {

	// ApplicationName is the name of the application
	ApplicationName string `yaml:"application-name" env:"APPLICATION_NAME" default:"Simba Application"`

	// ApplicationVersion is the version of the application
	ApplicationVersion string `yaml:"application-version" env:"APPLICATION_VERSION" default:"0.1.0"`

	// Server is the HTTP server for the application
	Server *http.Server

	// Router is the main Mux for the application
	Router *Router

	// Settings is the application Settings
	Settings *settings.Simba
}

Application is the main application struct that holds the Mux and other application Settings

func Default

func Default(opts ...settings.Option) *Application

Default returns a new Application application with default Simba

func New

func New(opts ...settings.Option) *Application

New returns a new Application application

func (*Application) Start added in v0.4.0

func (a *Application) Start()

func (*Application) Stop added in v0.4.0

func (a *Application) Stop() error

type AuthHandler added in v0.13.0

type AuthHandler[AuthModel any] interface {
	GetType() openapiModels.AuthType
	GetName() string
	GetFieldName() string
	GetFormat() string
	GetDescription() string
	GetIn() oapi.In
	GetHandler() AuthHandlerFunc[AuthModel]
}

func APIKeyAuth added in v0.13.0

func APIKeyAuth[AuthModel any](
	handler APIKeyAuthHandlerFunc[AuthModel],
	config APIKeyAuthConfig,
) AuthHandler[AuthModel]

APIKeyAuth creates an API key auth handler with configuration

func BasicAuth added in v0.13.0

func BasicAuth[AuthModel any](
	handler BasicAuthHandlerFunc[AuthModel],
	config BasicAuthConfig,
) AuthHandler[AuthModel]

BasicAuth creates a basic auth handler with configuration

func BearerAuth added in v0.13.0

func BearerAuth[AuthModel any](
	handler BearerAuthHandlerFunc[AuthModel],
	config BearerAuthConfig,
) AuthHandler[AuthModel]

BearerAuth creates a bearer auth handler with configuration

type AuthHandlerFunc added in v0.3.0

type AuthHandlerFunc[AuthModel any] func(r *http.Request) (*AuthModel, error)

AuthHandlerFunc is a function that handles authentication for a route.

type AuthenticatedJsonHandlerFunc added in v0.6.0

type AuthenticatedJsonHandlerFunc[RequestBody, Params, AuthModel, ResponseBody any] struct {
	// contains filtered or unexported fields
}

AuthenticatedJsonHandlerFunc is a function type for handling authenticated routes with Request body and params

func (AuthenticatedJsonHandlerFunc[RequestBody, Params, AuthModel, ResponseBody]) ServeHTTP added in v0.6.0

func (h AuthenticatedJsonHandlerFunc[RequestBody, Params, AuthModel, ResponseBody]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface for AuthenticatedJsonHandlerFunc

type AuthenticatedMultipartHandlerFunc added in v0.7.0

type AuthenticatedMultipartHandlerFunc[Params, AuthModel, ResponseBody any] struct {
	// contains filtered or unexported fields
}

AuthenticatedMultipartHandlerFunc is a function type for handling a MultipartRequest with params and an authenticated model

func (AuthenticatedMultipartHandlerFunc[Params, AuthModel, ResponseBody]) ServeHTTP added in v0.7.0

func (h AuthenticatedMultipartHandlerFunc[Params, AuthModel, ResponseBody]) ServeHTTP(w http.ResponseWriter, r *http.Request)

type BasicAuthConfig added in v0.13.0

type BasicAuthConfig struct {
	Name        string
	Description string
}

type BasicAuthHandlerFunc added in v0.16.0

type BasicAuthHandlerFunc[AuthModel any] func(ctx context.Context, username, password string) (*AuthModel, error)

BasicAuthHandlerFunc is a function that handles basic auth. This is the function that should be implemented by the user. It should return the user model if the username and password are valid, otherwise it should return an error.

type BasicAuthType added in v0.13.0

type BasicAuthType[AuthModel any] struct {
	Name        string
	Description string
	Handler     BasicAuthHandlerFunc[AuthModel]
}

func (BasicAuthType[AuthModel]) GetDescription added in v0.13.0

func (t BasicAuthType[AuthModel]) GetDescription() string

func (BasicAuthType[AuthModel]) GetFieldName added in v0.13.0

func (t BasicAuthType[AuthModel]) GetFieldName() string

func (BasicAuthType[AuthModel]) GetFormat added in v0.13.0

func (t BasicAuthType[AuthModel]) GetFormat() string

func (BasicAuthType[AuthModel]) GetHandler added in v0.13.0

func (t BasicAuthType[AuthModel]) GetHandler() AuthHandlerFunc[AuthModel]

func (BasicAuthType[AuthModel]) GetIn added in v0.13.0

func (t BasicAuthType[AuthModel]) GetIn() oapi.In

func (BasicAuthType[AuthModel]) GetName added in v0.13.0

func (t BasicAuthType[AuthModel]) GetName() string

func (BasicAuthType[AuthModel]) GetType added in v0.13.0

func (t BasicAuthType[AuthModel]) GetType() openapiModels.AuthType

type BearerAuthConfig added in v0.13.0

type BearerAuthConfig struct {
	Name        string
	Format      string
	Description string
}

type BearerAuthHandlerFunc added in v0.16.0

type BearerAuthHandlerFunc[AuthModel any] func(ctx context.Context, token string) (*AuthModel, error)

BearerAuthHandlerFunc is a function that handles bearer token authentication. This is the function that should be implemented by the user. It should return the user model if the token is valid, otherwise it should return an error.

type BearerAuthType added in v0.13.0

type BearerAuthType[AuthModel any] struct {
	Name        string
	Format      string
	Description string
	Handler     BearerAuthHandlerFunc[AuthModel]
}

func (BearerAuthType[AuthModel]) GetDescription added in v0.13.0

func (t BearerAuthType[AuthModel]) GetDescription() string

func (BearerAuthType[AuthModel]) GetFieldName added in v0.13.0

func (t BearerAuthType[AuthModel]) GetFieldName() string

func (BearerAuthType[AuthModel]) GetFormat added in v0.13.0

func (t BearerAuthType[AuthModel]) GetFormat() string

func (BearerAuthType[AuthModel]) GetHandler added in v0.13.0

func (t BearerAuthType[AuthModel]) GetHandler() AuthHandlerFunc[AuthModel]

func (BearerAuthType[AuthModel]) GetIn added in v0.13.0

func (t BearerAuthType[AuthModel]) GetIn() oapi.In

func (BearerAuthType[AuthModel]) GetName added in v0.13.0

func (t BearerAuthType[AuthModel]) GetName() string

func (BearerAuthType[AuthModel]) GetType added in v0.13.0

func (t BearerAuthType[AuthModel]) GetType() openapiModels.AuthType

type Handler

type Handler interface {
	ServeHTTP(w http.ResponseWriter, r *http.Request)
	// contains filtered or unexported methods
}

Handler specifies the interface for a handler that can be registered with the Router.

func AuthJsonHandler added in v0.6.0

func AuthJsonHandler[RequestBody, Params, AuthModel, ResponseBody any](
	handler func(ctx context.Context, req *simbaModels.Request[RequestBody, Params], authModel *AuthModel) (*simbaModels.Response[ResponseBody], error),
	authHandler AuthHandler[AuthModel],
) Handler

AuthJsonHandler handles a Request with the Request body and params.

Example usage:

Define a Request body struct:

type RequestBody struct {
	Test string `json:"test" validate:"required"`
}

Define a Request params struct:

type Params struct {
	Name   string `header:"name" validate:"required"`
	ID     int    `path:"id" validate:"required"`
	Active bool   `query:"active" validate:"required"`
	Page   int64  `query:"page" validate:"min=0"`
	Size   int64  `query:"size" validate:"min=0"`
}

Define a user struct:

type AuthModel struct {
	ID   int
	Name string
	Role string
}

Define a handler function:

func(ctx context.Context, req *simba.Request[RequestBody, Params], authModel *AuthModel) (*simba.Response[map[string]string], error) {
	// Access the Request body and params fields
	req.Body.Test
	req.Params.Name
	req.Params.ID
	req.Params.Page
	req.Params.Size

	// Access the user fields
	user.ID
	user.Name
	user.Role

	// Return a response
	return &simba.Response[map[string]string]{
		Headers: map[string][]string{"My-Header": {"header-value"}},
		Cookies: []*http.Cookie{{Name: "My-Cookie", Value: "cookie-value"}},
		Body:    map[string]string{"message": "success"},
		Status:  http.StatusOK,
	}, nil
}

Register the handler:

Mux.POST("/test/{id}", simba.AuthJsonHandler(handler))

func AuthMultipartHandler added in v0.7.0

func AuthMultipartHandler[Params, AuthModel, ResponseBody any](
	handler func(ctx context.Context, req *simbaModels.MultipartRequest[Params], authModel *AuthModel) (*simbaModels.Response[ResponseBody], error),
	authHandler AuthHandler[AuthModel],
) Handler

AuthMultipartHandler handles a MultipartRequest with params and an authenticated model. The MultipartRequest holds a MultipartReader and the parsed params. The reason to provide the reader is to allow the logic for processing the parts to be handled by the handler function.

Example usage:

Define a Request params struct:

type Params struct {
	Name   string `header:"name" validate:"required"`
	ID     int    `path:"id" validate:"required"`
	Active bool   `query:"active" validate:"required"`
	Page   int64  `query:"page" validate:"min=0"`
	Size   int64  `query:"size" validate:"min=0"`
}

Define a user struct:

type AuthModel struct {
	ID   int
	Name string
	Role string
}

Define a handler function:

func(ctx context.Context, req *simba.MultipartRequest[Params], authModel *AuthModel) (*simba.Response[map[string]string], error) {
	// Access the Multipart reader and params fields
	req.Params.Name
	req.Params.ID
	req.Params.Page
	req.Params.Size
	req.Reader // Multipart reader

	// Access the user fields
	user.ID
	user.Name
	user.Role

	// Return a response
	return &simba.Response[map[string]string]{
		Headers: map[string][]string{"My-Header": {"header-value"}},
		Cookies: []*http.Cookie{{Name: "My-Cookie", Value: "cookie-value"}},
		Body:    map[string]string{"message": "success"},
		Status:  http.StatusOK,
	}, nil
}

Register the handler:

Mux.POST("/test/{id}", simba.AuthMultipartHandler(handler))

func JsonHandler added in v0.6.0

func JsonHandler[RequestBody, Params, ResponseBody any](h JsonHandlerFunc[RequestBody, Params, ResponseBody]) Handler

JsonHandler handles a Request with the Request body and params.

Example usage:

Define a Request body struct:

type RequestBody struct {
	Test string `json:"test" validate:"required"`
}

Define a Request params struct:

type Params struct {
	Name   string `header:"name" validate:"required"`
	ID     int    `path:"id" validate:"required"`
	Active bool   `query:"active" validate:"required"`
	Page   int64  `query:"page" validate:"min=0"`
	Size   int64  `query:"size" validate:"min=0"`
}

Define a handler function:

func(ctx context.Context, req *simba.Request[RequestBody, Params]) (*simba.Response[map[string]string], error) {
	// Access the Request body and params fields
	req.Body.Test
	req.Params.Name
	req.Params.ID
	req.Params.Page
	req.Params.Size

	// Return a response
	return &simba.Response[map[string]string]{
		Headers: map[string][]string{"My-Header": {"header-value"}},
		Cookies: []*http.Cookie{{Name: "My-Cookie", Value: "cookie-value"}},
		Body:    map[string]string{"message": "success"},
		Status:  http.StatusOK,
	}, nil
}

Register the handler:

Mux.POST("/test/{id}", simba.JsonHandler(handler))

func MultipartHandler added in v0.7.0

func MultipartHandler[Params any, ResponseBody any](h MultipartHandlerFunc[Params, ResponseBody]) Handler

MultipartHandler handles a MultipartRequest with params. // The MultipartRequest holds a MultipartReader and the parsed params. // The reason to provide the reader is to allow the logic for processing the parts to be handled by the handler function.

Example usage:

Define a Request params struct:

type Params struct {
	Name   string `header:"name" validate:"required"`
	ID     int    `path:"id" validate:"required"`
	Active bool   `query:"active" validate:"required"`
	Page   int64  `query:"page" validate:"min=0"`
	Size   int64  `query:"size" validate:"min=0"`
}

Define a handler function:

func(ctx context.Context, req *simba.Request[RequestBody, Params]) (*simba.Response[map[string]string], error) {
	// Access the Multipart reader and params fields
	req.Params.Name
	req.Params.ID
	req.Params.Page
	req.Params.Size
	req.Reader // Multipart reader

	// Return a response
	return &simba.Response[map[string]string]{
		Headers: map[string][]string{"My-Header": {"header-value"}},
		Cookies: []*http.Cookie{{Name: "My-Cookie", Value: "cookie-value"}},
		Body:    map[string]string{"message": "success"},
		Status:  http.StatusOK,
	}, nil
}

Register the handler:

Mux.POST("/test/{id}", simba.MultipartHandler(handler))

type JsonHandlerFunc added in v0.6.0

type JsonHandlerFunc[RequestBody, Params, ResponseBody any] func(ctx context.Context, req *simbaModels.Request[RequestBody, Params]) (*simbaModels.Response[ResponseBody], error)

JsonHandlerFunc is a function type for handling routes with Request body and params

func (JsonHandlerFunc[RequestBody, Params, ResponseBody]) ServeHTTP added in v0.6.0

func (h JsonHandlerFunc[RequestBody, Params, ResponseBody]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface for JsonHandlerFunc

type MultipartHandlerFunc added in v0.7.0

type MultipartHandlerFunc[Params any, ResponseBody any] func(ctx context.Context, req *simbaModels.MultipartRequest[Params]) (*simbaModels.Response[ResponseBody], error)

MultipartHandlerFunc is a function type for handling routes with Request body and params

func (MultipartHandlerFunc[Params, ResponseBody]) ServeHTTP added in v0.7.0

func (h MultipartHandlerFunc[Params, ResponseBody]) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the http.Handler interface for JsonHandlerFunc

type Router added in v0.2.0

type Router struct {
	Mux *http.ServeMux
	// contains filtered or unexported fields
}

Router is a simple Mux that wraps http.ServeMux and allows for middleware chaining and type information storage for routes.

func (*Router) DELETE added in v0.2.0

func (r *Router) DELETE(path string, handler Handler)

DELETE registers a handler for DELETE requests to the given pattern

func (*Router) Extend added in v0.2.0

func (r *Router) Extend(middleware []func(http.Handler) http.Handler)

Extend extends the middleware chain with another chain

func (*Router) GET added in v0.2.0

func (r *Router) GET(path string, handler Handler)

GET registers a handler for GET requests to the given pattern

func (*Router) GenerateOpenAPIDocumentation added in v0.15.0

func (r *Router) GenerateOpenAPIDocumentation(ctx context.Context, title, version string) error

GenerateOpenAPIDocumentation generates the OpenAPI documentation for the routes mounted in the router if enabled in settings.Docs

func (*Router) HEAD added in v0.2.0

func (r *Router) HEAD(path string, handler Handler)

HEAD registers a handler for HEAD requests to the given pattern

func (*Router) Handle added in v0.6.0

func (r *Router) Handle(method, path string, handler Handler)

func (*Router) OPTIONS added in v0.2.0

func (r *Router) OPTIONS(path string, handler Handler)

OPTIONS registers a handler for OPTIONS requests to the given pattern

func (*Router) PATCH added in v0.2.0

func (r *Router) PATCH(path string, handler Handler)

PATCH registers a handler for PATCH requests to the given pattern

func (*Router) POST added in v0.2.0

func (r *Router) POST(path string, handler Handler)

POST registers a handler for POST requests to the given pattern

func (*Router) PUT added in v0.2.0

func (r *Router) PUT(path string, handler Handler)

PUT registers a handler for PUT requests to the given pattern

func (*Router) ServeHTTP added in v0.2.0

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements the http.Handler interface for the Router type

func (*Router) Use added in v0.2.0

func (r *Router) Use(middleware func(http.Handler) http.Handler)

Use registers a middleware handler

Jump to

Keyboard shortcuts

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