noob

package module
v0.1.7 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2023 License: MIT Imports: 28 Imported by: 0

README

Noob

Code Smells Go Reference GitHub go.mod Go version (subdirectory of monorepo) GitHub release (latest by date)

Noob is a REST API framework for faster development by providing several common functions, such as:

  • Query Parsing
  • Logging
  • Try-Catch-Finally block
  • Env loader
  • Response Templating

Currently, Noob based on Gin v1.7.4. Thanks to gin-gonic

Contents

TODO

  • Write unit test

Installation

To install this package, you need to install Go (version 1.17+ is required) & initiate your Go workspace first.

  1. After you initiate your workspace then you can install this package with below command.
go get -u github.com/alfarih31/nb-go-http
  1. Import it in your code
import "github.com/alfarih31/nb-go-http"

Quick Start & Usage

See the example: sample_app

Contributors

License

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

Documentation

Index

Constants

View Source
const CORSAllowCredentials = "Access-Control-Allow-Credentials"
View Source
const CORSAllowHeaders = "Access-Control-Allow-Headers"
View Source
const CORSAllowMethods = "Access-Control-Allow-Methods"
View Source
const CORSAllowOrigin = "Access-Control-Allow-Origin"
View Source
const CORSExposeHeaders = "Access-Control-Expose-Headers"
View Source
const CORSMaxAge = "Access-Control-Max-Age"
View Source
const DefaultErrCode = 1
View Source
const Version = "v1.5.1"

Variables

View Source
var DefaultCORSCfg = CORSCfg{
	Enable:           true,
	AllowOrigins:     nil,
	AllowHeaders:     "*",
	AllowMethods:     "GET,POST,PUT,DELETE,PATCH,OPTIONS",
	AllowCredentials: true,
	ExposeHeaders:    "authorization,content-type",
	MaxAge:           time.Duration(0),
}
View Source
var DefaultCfg = Cfg{
	Host:           "",
	Port:           8080,
	Path:           "/",
	RequestTimeout: 0,
	UseListener:    false,
}
View Source
var DefaultForbiddenErrorResponse = NewResponseError(StatusForbidden, ResponseBody{
	Code:    statusCodeErrForbidden,
	Message: "forbidden",
})
View Source
var DefaultInternalServerErrorResponse = NewResponseError(StatusInternalServerError, ResponseBody{
	Code:    statusCodeErrInternal,
	Message: "internal server error",
})
View Source
var DefaultMeta = keyvalue.KeyValue{
	"app_name":        "Core",
	"app_description": "Core API",
	"app_version":     "v0.1.0",
}
View Source
var DefaultNotFoundErrorResponse = NewResponseError(StatusNotFound, ResponseBody{
	Code:    statusCodeErrNotFound,
	Message: "not found",
})
View Source
var DefaultRequestTimeoutErrorResponse = NewResponseError(StatusRequestTimeout, ResponseBody{
	Code:    statusCodeErrRequestTimeout,
	Message: "request timed out",
})
View Source
var DefaultResponseHeader = ResponseHeader{
	"Content-Type": {"application/json"},
}
View Source
var DefaultSuccessNoContentResponse = NewResponseNoBody(StatusNoContent)
View Source
var DefaultSuccessResponse = NewResponse(StatusOK, ResponseBody{
	Code:    statusCodeOk,
	Message: "success",
})
View Source
var DefaultThrottlingCfg = ThrottlingCfg{
	Enable:         false,
	MaxBurstSize:   defaultMaxEventPerSec,
	MaxEventPerSec: defaultMaxBurstSize,
}
View Source
var DefaultTooManyRequestsErrorResponse = NewResponseError(StatusTooManyRequests, ResponseBody{
	Code:    statusCodeErrTooManyRequest,
	Message: "too many request",
})
View Source
var StartTime = utils.NewDatetimeNow().GetTime()

Functions

func APIStatus

func APIStatus() keyvalue.KeyValue

func CustomLogger added in v0.1.3

func CustomLogger(modulePath string, logger *logrus.Logger) gin.HandlerFunc

func GetRuntimeFrames

func GetRuntimeFrames(skip int) *runtime.Frames

func StackTrace

func StackTrace() []*gostackparse.Goroutine

func TCFunc

func TCFunc(run Func)

Types

type CORSCfg

type CORSCfg struct {
	Enable           bool
	AllowOrigins     []string
	AllowMethods     string
	AllowHeaders     string
	AllowCredentials bool
	ExposeHeaders    string
	MaxAge           time.Duration
}

type Cfg

type Cfg struct {
	Host           string
	Port           int
	Path           string
	RequestTimeout time.Duration
	UseListener    bool
}

type CoreError

type CoreError struct {
	Err    error                     `json:"err"`
	Code   uint                      `json:"code"`
	Meta   interface{}               `json:"meta"`
	Stack  []*gostackparse.Goroutine `json:"_stacks,omitempty"`
	Frames *runtime.Frames           `json:"_frames,omitempty"`
}

func NewCoreError

func NewCoreError(msg string, meta ...interface{}) *CoreError

func (CoreError) Compose

func (msg CoreError) Compose(message string, data ...interface{}) *CoreError

func (*CoreError) Error

func (msg *CoreError) Error() string

func (*CoreError) Errors

func (msg *CoreError) Errors() interface{}

func (*CoreError) JSON

func (msg *CoreError) JSON() interface{}

func (CoreError) MarshalJSON

func (msg CoreError) MarshalJSON() ([]byte, error)

func (CoreError) StackTrace

func (msg CoreError) StackTrace() *runtime.Frames

func (*CoreError) Trace

func (msg *CoreError) Trace()

type Ctx

type Ctx struct {
	Provider *HTTPProviderCtx

	Listener net.Listener
	*Router
	// contains filtered or unexported fields
}

func New

func New(modulePath string, listener ...net.Listener) *Ctx

New return Core context, used as core of the application

func (*Ctx) Start

func (co *Ctx) Start() error

Start will run the Core & start serving the application

type Errors

type Errors []*CoreError

func (Errors) MarshalJSON

func (e Errors) MarshalJSON() ([]byte, error)

func (Errors) String

func (e Errors) String() string

type Func

type Func struct {
	Try     func()
	Catch   func(e interface{}, frames *runtime.Frames)
	Finally func()
}

type HTTPProviderCtx

type HTTPProviderCtx struct {
	Engine *gin.Engine
	// contains filtered or unexported fields
}

func HTTP

func HTTP() *HTTPProviderCtx

func (*HTTPProviderCtx) Router

func (t *HTTPProviderCtx) Router(path string) *Router

func (*HTTPProviderCtx) Run

func (t *HTTPProviderCtx) Run(baseUrl string) error

func (*HTTPProviderCtx) RunListener

func (t *HTTPProviderCtx) RunListener(listener net.Listener) error

type HTTPStatusCode

type HTTPStatusCode uint
const (
	StatusContinue           HTTPStatusCode = 100 // RFC 7231, 6.2.1
	StatusSwitchingProtocols HTTPStatusCode = 101 // RFC 7231, 6.2.2
	StatusProcessing         HTTPStatusCode = 102 // RFC 2518, 10.1
	StatusEarlyHints         HTTPStatusCode = 103 // RFC 8297

	StatusOK                   HTTPStatusCode = 200 // RFC 7231, 6.3.1
	StatusCreated              HTTPStatusCode = 201 // RFC 7231, 6.3.2
	StatusAccepted             HTTPStatusCode = 202 // RFC 7231, 6.3.3
	StatusNonAuthoritativeInfo HTTPStatusCode = 203 // RFC 7231, 6.3.4
	StatusNoContent            HTTPStatusCode = 204 // RFC 7231, 6.3.5
	StatusResetContent         HTTPStatusCode = 205 // RFC 7231, 6.3.6
	StatusPartialContent       HTTPStatusCode = 206 // RFC 7233, 4.1
	StatusMultiStatus          HTTPStatusCode = 207 // RFC 4918, 11.1
	StatusAlreadyReported      HTTPStatusCode = 208 // RFC 5842, 7.1
	StatusIMUsed               HTTPStatusCode = 226 // RFC 3229, 10.4.1

	StatusMultipleChoices  HTTPStatusCode = 300 // RFC 7231, 6.4.1
	StatusMovedPermanently HTTPStatusCode = 301 // RFC 7231, 6.4.2
	StatusFound            HTTPStatusCode = 302 // RFC 7231, 6.4.3
	StatusSeeOther         HTTPStatusCode = 303 // RFC 7231, 6.4.4
	StatusNotModified      HTTPStatusCode = 304 // RFC 7232, 4.1
	StatusUseProxy         HTTPStatusCode = 305 // RFC 7231, 6.4.5

	StatusTemporaryRedirect HTTPStatusCode = 307 // RFC 7231, 6.4.7
	StatusPermanentRedirect HTTPStatusCode = 308 // RFC 7538, 3

	StatusBadRequest                   HTTPStatusCode = 400 // RFC 7231, 6.5.1
	StatusUnauthorized                 HTTPStatusCode = 401 // RFC 7235, 3.1
	StatusPaymentRequired              HTTPStatusCode = 402 // RFC 7231, 6.5.2
	StatusForbidden                    HTTPStatusCode = 403 // RFC 7231, 6.5.3
	StatusNotFound                     HTTPStatusCode = 404 // RFC 7231, 6.5.4
	StatusMethodNotAllowed             HTTPStatusCode = 405 // RFC 7231, 6.5.5
	StatusNotAcceptable                HTTPStatusCode = 406 // RFC 7231, 6.5.6
	StatusProxyAuthRequired            HTTPStatusCode = 407 // RFC 7235, 3.2
	StatusRequestTimeout               HTTPStatusCode = 408 // RFC 7231, 6.5.7
	StatusConflict                     HTTPStatusCode = 409 // RFC 7231, 6.5.8
	StatusGone                         HTTPStatusCode = 410 // RFC 7231, 6.5.9
	StatusLengthRequired               HTTPStatusCode = 411 // RFC 7231, 6.5.10
	StatusPreconditionFailed           HTTPStatusCode = 412 // RFC 7232, 4.2
	StatusRequestEntityTooLarge        HTTPStatusCode = 413 // RFC 7231, 6.5.11
	StatusRequestURITooLong            HTTPStatusCode = 414 // RFC 7231, 6.5.12
	StatusUnsupportedMediaType         HTTPStatusCode = 415 // RFC 7231, 6.5.13
	StatusRequestedRangeNotSatisfiable HTTPStatusCode = 416 // RFC 7233, 4.4
	StatusExpectationFailed            HTTPStatusCode = 417 // RFC 7231, 6.5.14
	StatusTeapot                       HTTPStatusCode = 418 // RFC 7168, 2.3.3
	StatusMisdirectedRequest           HTTPStatusCode = 421 // RFC 7540, 9.1.2
	StatusUnprocessableEntity          HTTPStatusCode = 422 // RFC 4918, 11.2
	StatusLocked                       HTTPStatusCode = 423 // RFC 4918, 11.3
	StatusFailedDependency             HTTPStatusCode = 424 // RFC 4918, 11.4
	StatusTooEarly                     HTTPStatusCode = 425 // RFC 8470, 5.2.
	StatusUpgradeRequired              HTTPStatusCode = 426 // RFC 7231, 6.5.15
	StatusPreconditionRequired         HTTPStatusCode = 428 // RFC 6585, 3
	StatusTooManyRequests              HTTPStatusCode = 429 // RFC 6585, 4
	StatusRequestHeaderFieldsTooLarge  HTTPStatusCode = 431 // RFC 6585, 5
	StatusUnavailableForLegalReasons   HTTPStatusCode = 451 // RFC 7725, 3

	StatusInternalServerError           HTTPStatusCode = 500 // RFC 7231, 6.6.1
	StatusNotImplemented                HTTPStatusCode = 501 // RFC 7231, 6.6.2
	StatusBadGateway                    HTTPStatusCode = 502 // RFC 7231, 6.6.3
	StatusServiceUnavailable            HTTPStatusCode = 503 // RFC 7231, 6.6.4
	StatusGatewayTimeout                HTTPStatusCode = 504 // RFC 7231, 6.6.5
	StatusHTTPVersionNotSupported       HTTPStatusCode = 505 // RFC 7231, 6.6.6
	StatusVariantAlsoNegotiates         HTTPStatusCode = 506 // RFC 2295, 8.1
	StatusInsufficientStorage           HTTPStatusCode = 507 // RFC 4918, 11.5
	StatusLoopDetected                  HTTPStatusCode = 508 // RFC 5842, 7.2
	StatusNotExtended                   HTTPStatusCode = 510 // RFC 2774, 7
	StatusNetworkAuthenticationRequired HTTPStatusCode = 511 // RFC 6585, 6
)

List gathered from net/http/status

func (HTTPStatusCode) Copy

func (c HTTPStatusCode) Copy() *HTTPStatusCode

type Handler

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

Handler is custom type to wrap HandlerFunc, so we can give a name to them

func NewHandler

func NewHandler(handler HandlerFunc) Handler

func (Handler) String

func (h Handler) String() string

String return name of the handler. So fmt.Print of a handler will return its name. Warning, this features is EXPERIMENTAL!

type HandlerChain

type HandlerChain []Handler

HandlerChain is type for slice of Handler

func NewHandlerChain

func NewHandlerChain(handlers []HandlerFunc) HandlerChain

func (HandlerChain) String

func (hc HandlerChain) String() string

func (HandlerChain) Strings

func (hc HandlerChain) Strings() []string

Strings return list name of each handler

type HandlerCtx

type HandlerCtx struct {
	*gin.Context
	// contains filtered or unexported fields
}

func WrapHandlerCtx

func WrapHandlerCtx(ec *gin.Context) *HandlerCtx

func (*HandlerCtx) Copy

func (c *HandlerCtx) Copy() *HandlerCtx

func (*HandlerCtx) Errors

func (c *HandlerCtx) Errors() Errors

func (*HandlerCtx) GetNext

func (c *HandlerCtx) GetNext() HandlerFunc

func (*HandlerCtx) GetPrevError

func (c *HandlerCtx) GetPrevError() (err error)

func (*HandlerCtx) GetPrevResponse

func (c *HandlerCtx) GetPrevResponse() (res Response)

func (*HandlerCtx) Next

func (c *HandlerCtx) Next() (res Response, err error)

func (*HandlerCtx) Send

func (c *HandlerCtx) Send(res Response)

func (*HandlerCtx) SendError

func (c *HandlerCtx) SendError(e interface{}, frames *runtime.Frames)

func (*HandlerCtx) StackError

func (c *HandlerCtx) StackError(e *CoreError)

type HandlerFunc

type HandlerFunc func(context *HandlerCtx) (Response, error)

func HandleThrottling

func HandleThrottling() HandlerFunc

type Query

type Query struct {
	Key      string
	Type     QueryValueType
	Default  interface{}
	Required bool
}

type QueryParser

type QueryParser HandlerCtx

func (QueryParser) GetBool

func (p QueryParser) GetBool(key string, opt ...QueryParserOption) (*bool, error)

func (QueryParser) GetInt

func (p QueryParser) GetInt(key string, opt ...QueryParserOption) (*int, error)

func (QueryParser) GetInt32

func (p QueryParser) GetInt32(key string, opt ...QueryParserOption) (*int32, error)

func (QueryParser) GetInt64

func (p QueryParser) GetInt64(key string, opt ...QueryParserOption) (*int64, error)

func (QueryParser) GetQueries

func (p QueryParser) GetQueries(target interface{}, qs []Query) error

func (QueryParser) GetString

func (p QueryParser) GetString(key string, opt ...QueryParserOption) (*string, error)

type QueryParserOption

type QueryParserOption struct {
	Default  interface{}
	Required bool
}

type QueryValueType

type QueryValueType uint
const (
	QueryValueTypeString QueryValueType = iota
	QueryValueTypeBool
	QueryValueTypeInt
	QueryValueTypeInt32
	QueryValueTypeInt64
)

type Response

type Response interface {
	Compose(sourceRes Response, replaceExist ...bool) Response
	ComposeBody(body ResponseBody, replaceExist ...bool) Response
	ComposeHeader(h ResponseHeader, replaceExist ...bool) Response
	GetBody() *ResponseBody
	GetHeader() *ResponseHeader
	GetCode() *HTTPStatusCode
	Copy() Response
}

func HandleAPIStatus

func HandleAPIStatus(c *HandlerCtx) (Response, error)

func HandleNotFound

func HandleNotFound(context *HandlerCtx) (Response, error)

func HandleTimeout

func HandleTimeout(c *HandlerCtx) (Response, error)

func NewResponse

func NewResponse(code HTTPStatusCode, body ResponseBody, header ...ResponseHeader) Response

func NewResponseNoBody

func NewResponseNoBody(code HTTPStatusCode, header ...ResponseHeader) Response

func NewResponseSuccess

func NewResponseSuccess(body ResponseBody, header ...ResponseHeader) Response

type ResponseBody

type ResponseBody struct {
	Code    uint        `json:"code,omitempty"`
	Message string      `json:"message,omitempty"`
	Data    interface{} `json:"data,omitempty"`
	Errors  interface{} `json:"_error,omitempty"`
}

func (ResponseBody) Copy

func (b ResponseBody) Copy() *ResponseBody

type ResponseError

type ResponseError interface {
	Response
	CopyError() ResponseError
	SetMessage(msg string) ResponseError
	SetError(err error) ResponseError
	Error() string
}

func NewResponseError

func NewResponseError(code HTTPStatusCode, body ResponseBody, header ...ResponseHeader) ResponseError

type ResponseHeader

type ResponseHeader map[string][]string

func (ResponseHeader) Copy

func (r ResponseHeader) Copy() *ResponseHeader

type ResponseMap

type ResponseMap map[HTTPStatusCode]Response

type Router

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

func (*Router) Branch

func (e *Router) Branch(path string) *Router

Branch used for branching router path

func (*Router) DELETE

func (e *Router) DELETE(path string, handlersFunc ...HandlerFunc)

func (*Router) GET

func (e *Router) GET(path string, handlersFunc ...HandlerFunc)

func (*Router) HEAD

func (e *Router) HEAD(path string, handlersFunc ...HandlerFunc)

func (*Router) Handlers

func (e *Router) Handlers() []routerHandler

Handlers return slice to routerHandler

func (*Router) OPTIONS

func (e *Router) OPTIONS(path string, handlersFunc ...HandlerFunc)

func (*Router) PATCH

func (e *Router) PATCH(path string, handlersFunc ...HandlerFunc)

func (*Router) POST

func (e *Router) POST(path string, handlersFunc ...HandlerFunc)

func (*Router) POSTUSE

func (e *Router) POSTUSE(handlersFunc ...HandlerFunc)

POSTUSE assign handler to be executed after other handlers in the groups is executed

func (*Router) PUT

func (e *Router) PUT(path string, handlersFunc ...HandlerFunc)

func (*Router) USE

func (e *Router) USE(handlersFunc ...HandlerFunc)

type ThrottlingCfg

type ThrottlingCfg struct {
	Enable         bool
	MaxEventPerSec int
	MaxBurstSize   int
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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