stgin

package module
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: May 6, 2022 License: MIT Imports: 10 Imported by: 1

README

#STGIN

STgin is a functional rest framework that provides easy APIs in order to maintain your application RESTful APIS.

It is currently built upon go-gin framework, but has the ability to easily switch between any other library/framework using the translator function in server file.

A comparison between STgin and go-gin, writing a simple API:

// Given response type as
type HealthCheckResponse struct {
	DBConnection    bool    `json:"database_connection"`
	Message         string  `json:"message"`
}
// and request type as
type HealthCheckRequest struct {
	Whatever        string   `json:"whatever"`
}

STgin implementation:

health := healthController.POST("/health", func(request stgin.RequestContext) stgin.Status {
    var reqBody HealthCheckRequest
    request.Body.WriteInto(&reqBody)
    // do something with reqBody
    var response HealthCheckResponse = GetHealth()
    if response.DBConnection {
        return stgin.Ok(&response) 
    } else {
        return stgin.InternalServerError(&response)
    }
})

go-gin implementation:

r.POST("/health", func(c *gin.Context) {
    var reqBody HealthCheckRequest
    bodyBytes, err := ioutil.ReadAll(c.Request.Body)
	// potential error handling
    err = json.Unmarshal(bodyBytes, &reqBody)
	// potential error handling
	// do something with reqBody
    var response HealthCheckResponse = GetHealth()
    jsonResponse, _ := json.Marshal(response)
    if response.DBConnection {
    	c.Status(200)
    	_, writeError := c.Writer.Write(jsonResponse)
    	// potential error handling
    } else {
    	c.Status(500)
    	_, writeError = c.Writer.Write(jsonResponse)
    	// potential error handling
    }
})

Or just easily add headers with a receiver function instead of manually writing headers:

stgin.Ok(&body).WithHeaders(...)

Structure

The structure of STgin types and interfaces is pretty simple, a Server may have several Controllers, and each controller may have serveral Routes.

    
    -Server =>
        -Controller 1 ->
            -Route 1
            -Route 2
        -Cotroller 2 ->
            -Route 1

Server: Is run on the specified port, contains the controllers.

Controller: Contains routes which are exposed to the server, has a name, and may have a route prefix (i.e., /home)

Route: Holds route specifications (i.e., method, path, API action)

RequestContext: Holds the information about the requests, such as uri, body, headers, ...

Status: Is a wrapper around an actual http response, holds status code, response headers, response body, ... (i.e., Ok, BadRequest, ...)

API: Is a type alias for a function which accepts a request context and returns a status.

Custom Actions

STgin does not provide actions about stuff like Authentication, because simple authentication is not useful most of the time, and you may need customized authentications.

For instance:

type AuthInfo struct {
	Username    string      `json:"username"`
	AccountId   int         `json:"account_id"`
	Roles       []string    `json:"roles"`
}

func authenticate(rc stgin.RequestContext) (AuthInfo, bool) {
    if name, found := rc.GetQuery("user"); !found {
    	...
    } else {
        ...
    }
}
// written once in your base package
func Authenticated(rc stgin.RequestContext, action func(AuthInfo) stgin.Status) stgin.Status {
    authInfo, isAuthenticated := authenticate(rc)
    if !isAuthenticated {
        return stgin.Unauthorized(...)
    } else {
        return action(authInfo)
    }
}

// In the apis section
myAPI := stgin.GET("/test", func(request stgin.RequestContext) stgin.Status {
    return Authenticated(request, func(authInfo AuthInfo) stgin.Status {
        return stgin.Ok(&Greet(authInfo.Username))
    })
})

#TODOs

  • Add most common statuses as predefined functions
  • Add support for cookies

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type API

type API = func(c RequestContext) Status

type ApiJourneyListener

type ApiJourneyListener = func(RequestContext, Status)

func WatchAPIs

func WatchAPIs() ApiJourneyListener

type Controller

type Controller struct {
	Name string
	// contains filtered or unexported fields
}

func NewController

func NewController(name string) *Controller

func (*Controller) AddJourneyListeners

func (controller *Controller) AddJourneyListeners(listeners ...ApiJourneyListener)

func (*Controller) AddRequestListeners

func (controller *Controller) AddRequestListeners(listeners ...RequestListener)

func (*Controller) AddResponseListener

func (controller *Controller) AddResponseListener(listeners ...ResponseListener)

func (*Controller) AddRoutes

func (controller *Controller) AddRoutes(routes ...Route)

func (*Controller) SetRoutePrefix

func (controller *Controller) SetRoutePrefix(prefix string)

type RequestBody

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

func (*RequestBody) WriteInto

func (rb *RequestBody) WriteInto(a any) error

type RequestContext

type RequestContext struct {
	Url         string
	QueryParams map[string][]string
	PathParams  map[string]string
	Headers     http.Header
	Body        *RequestBody

	Method string
	// contains filtered or unexported fields
}

func (RequestContext) GetPathParam

func (c RequestContext) GetPathParam(name string) (string, bool)

func (RequestContext) GetQueries

func (c RequestContext) GetQueries(name string) []string

func (RequestContext) GetQuery

func (c RequestContext) GetQuery(name string) (string, bool)

type RequestListener

type RequestListener = func(RequestContext) RequestContext

type ResponseListener

type ResponseListener = func(Status) Status

type Route

type Route struct {
	Path   string
	Method string
	Action API
}

func DELETE

func DELETE(path string, api API) Route

func GET

func GET(path string, api API) Route

func OPTIONS added in v0.2.2

func OPTIONS(path string, api API) Route

func PATCH

func PATCH(path string, api API) Route

func POST

func POST(path string, api API) Route

func PUT

func PUT(path string, api API) Route

type RouteCreationStage

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

func OnDelete

func OnDelete(path string) RouteCreationStage

func OnGET

func OnGET(path string) RouteCreationStage

func OnOptions added in v0.2.2

func OnOptions(path string) RouteCreationStage

func OnPOST

func OnPOST(path string) RouteCreationStage

func OnPUT

func OnPUT(path string) RouteCreationStage

func OnPatch

func OnPatch(path string) RouteCreationStage

func OnPath

func OnPath(path string) RouteCreationStage

func (RouteCreationStage) Do

func (stage RouteCreationStage) Do(api API) Route

func (RouteCreationStage) WithMethod

func (stage RouteCreationStage) WithMethod(method string) RouteCreationStage

type Server

type Server struct {
	Controllers []*Controller
	// contains filtered or unexported fields
}

func NewServer

func NewServer(port int) *Server

func (*Server) AddJourneyListeners

func (server *Server) AddJourneyListeners(listeners ...ApiJourneyListener)

func (*Server) AddRequestListeners

func (server *Server) AddRequestListeners(listeners ...RequestListener)

func (*Server) AddResponseListeners

func (server *Server) AddResponseListeners(listeners ...ResponseListener)

func (*Server) MethodNowAllowedAction added in v0.2.2

func (server *Server) MethodNowAllowedAction(action API)

func (*Server) NotFoundAction added in v0.2.2

func (server *Server) NotFoundAction(action API)

func (*Server) Register

func (server *Server) Register(controllers ...*Controller)

func (*Server) Start

func (server *Server) Start() error

type Status

type Status struct {
	StatusCode int
	Entity     any
	Headers    http.Header
}

func BadRequest

func BadRequest(body any) Status

func CreateResponse

func CreateResponse(statusCode int, body any) Status

func Created

func Created(body any) Status

func Forbidden

func Forbidden(body any) Status

func Found

func Found(location string) Status

func InternalServerError

func InternalServerError(body any) Status

func MethodNotAllowed added in v0.2.2

func MethodNotAllowed(body any) Status

func MovedPermanently

func MovedPermanently(location string) Status

func NotFound

func NotFound(body any) Status

func Ok

func Ok(body any) Status

func PermanentRedirect

func PermanentRedirect(location string) Status

func Unauthorized

func Unauthorized(body any) Status

func (Status) WithHeaders

func (status Status) WithHeaders(headers http.Header) Status

Jump to

Keyboard shortcuts

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