apiserv

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

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

Go to latest
Published: Apr 7, 2022 License: MIT Imports: 33 Imported by: 2

README

apiserv GoDoc Status Build Status

apiserv: Yet Another API Server

Documentation

Index

Constants

View Source
const (
	MimeJSON       = "application/json; charset=utf-8"
	MimeXML        = "application/xml; charset=utf-8"
	MimeJavascript = "application/javascript; charset=utf-8"
	MimeHTML       = "text/html; charset=utf-8"
	MimePlain      = "text/plain; charset=utf-8"
	MimeBinary     = "application/octet-stream"
)

Common mime-types

Variables

View Source
var (
	// ErrDir is Returned from ctx.File when the path is a directory not a file.
	ErrDir = errors.New("file is a directory")

	// ErrInvalidURL gets returned on invalid redirect urls.
	ErrInvalidURL = errors.New("invalid redirect error")

	// ErrEmptyCallback is returned when a callback is empty
	ErrEmptyCallback = errors.New("empty callback")

	// ErrEmptyData is returned when the data payload is empty
	ErrEmptyData = errors.New("empty data")
)
View Source
var DefaultOpts = Options{
	WriteTimeout: time.Minute,
	ReadTimeout:  time.Minute,

	MaxHeaderBytes: 16 << 10,

	KeepAlivePeriod: 3 * time.Minute,

	Logger: log.New(os.Stderr, "apiserv: ", 0),
}

DefaultOpts are the default options used for creating new servers.

View Source
var EnableCacheResponse bool

Functions

func GetSecureCookie

func GetSecureCookie(ctx *Context) *securecookie.SecureCookie

GetSecureCookie returns the *securecookie.SecureCookie associated with the Context, or nil.

func JSONRequest

func JSONRequest(method, url string, reqData, respData interface{}) (err error)

func TryCompressed

func TryCompressed(ctx *Context, fname string) error

TryCompressed will try serving compressed files if they exist on the disk or use on the fly gzip.

Types

type AutoCertHosts

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

func NewAutoCertHosts

func NewAutoCertHosts(hosts ...string) *AutoCertHosts

func (*AutoCertHosts) Contains

func (a *AutoCertHosts) Contains(host string) bool

func (*AutoCertHosts) IsAllowed

func (a *AutoCertHosts) IsAllowed(_ context.Context, host string) error

func (*AutoCertHosts) Set

func (a *AutoCertHosts) Set(hosts ...string)

type CertPair

type CertPair struct {
	CertFile string `json:"certFile"`
	KeyFile  string `json:"KeyFile"`
}

CertPair is a pair of (cert, key) files to listen on TLS

type Context

type Context struct {
	http.ResponseWriter

	Req *http.Request

	Params router.Params
	// contains filtered or unexported fields
}

Context is the default context passed to handlers it is not thread safe and should never be used outside the handler

func (*Context) BindJSON

func (ctx *Context) BindJSON(out interface{}) error

BindJSON parses the request's body as json, and closes the body. Note that unlike gin.Context.Bind, this does NOT verify the fields using special tags.

func (*Context) BindJSONP

func (ctx *Context) BindJSONP(val interface{}) (cb string, err error)

BindJSONP parses the request's callback and data search queries and closes the body

func (*Context) ClientIP

func (ctx *Context) ClientIP() string

ClientIP returns the current client ip, accounting for X-Real-Ip and X-forwarded-For headers as well.

func (*Context) CloseBody

func (ctx *Context) CloseBody() error

CloseBody closes the request body.

func (*Context) ContentType

func (ctx *Context) ContentType() string

ContentType returns the request's content-type.

func (*Context) Done

func (ctx *Context) Done() bool

Done returns wither the context is marked as done or not.

func (*Context) EnableGzip

func (ctx *Context) EnableGzip(level int)

func (*Context) File

func (ctx *Context) File(fp string) error

File serves a file using http.ServeContent. See http.ServeContent.

func (*Context) Get

func (ctx *Context) Get(key string) interface{}

Get returns a context value

func (*Context) GetCookie

func (ctx *Context) GetCookie(name string) (out string, ok bool)

GetCookie returns the given cookie's value.

func (*Context) GetCookieValue

func (ctx *Context) GetCookieValue(name string, valDst interface{}) error

GetCookieValue unmarshals a cookie, only needed if you stored an object for the cookie not a string.

func (*Context) JSON

func (ctx *Context) JSON(code int, indent bool, v interface{}) error

JSON outputs a json object, it is highly recommended to return *Response rather than use this directly. calling this function marks the Context as done, meaning any returned responses won't be written out.

func (*Context) JSONP

func (ctx *Context) JSONP(code int, callbackKey string, v interface{}) (err error)

JSONP outputs a jsonP object, it is highly recommended to return *Response rather than use this directly. calling this function marks the Context as done, meaning any returned responses won't be written out.

func (*Context) MultipartReader

func (ctx *Context) MultipartReader() (*multipart.Reader, error)

MultipartReader is like Request.MultipartReader but supports multipart/*, not just form-data

func (*Context) Next

func (ctx *Context) Next() Response

Next is a QoL function that calls NextMiddleware() then NextHandler() if NextMiddleware() didn't return a response.

func (*Context) NextHandler

func (ctx *Context) NextHandler() Response

NextHandler is a func to execute all the handlers in the group up until one returns a Response.

func (*Context) NextMiddleware

func (ctx *Context) NextMiddleware() Response

NextMiddleware is a middleware-only func to execute all the other middlewares in the group and return before the handlers. will panic if called from a handler.

func (*Context) Param

func (ctx *Context) Param(key string) string

Param is a shorthand for ctx.Params.Get(name).

func (*Context) Path

func (ctx *Context) Path() string

Path is a shorthand for ctx.Req.URL.EscapedPath().

func (*Context) Printf

func (ctx *Context) Printf(code int, contentType, s string, args ...interface{}) (int, error)

Printf is a QoL function to handle outputing plain strings with optional fmt.Printf-style formating. calling this function marks the Context as done, meaning any returned responses won't be written out.

func (*Context) Query

func (ctx *Context) Query(key string) string

Query is a shorthand for ctx.Req.URL.Query().Get(key).

func (*Context) QueryDefault

func (ctx *Context) QueryDefault(key, def string) string

QueryDefault returns the query key or a default value.

func (*Context) Read

func (ctx *Context) Read(p []byte) (int, error)

Read is a QoL shorthand for ctx.Req.Body.Read. Context implements io.Reader

func (*Context) RemoveCookie

func (ctx *Context) RemoveCookie(name string)

RemoveCookie deletes the given cookie and sets its expires date in the past.

func (*Context) ReqHeader

func (ctx *Context) ReqHeader() http.Header

ReqHeader returns the request header.

func (*Context) Set

func (ctx *Context) Set(key string, val interface{})

Set sets a context value, useful in passing data to other handlers down the chain

func (*Context) SetContentType

func (ctx *Context) SetContentType(typ string)

SetContentType sets the responses's content-type.

func (*Context) SetCookie

func (ctx *Context) SetCookie(name string, value interface{}, domain string, forceHTTPS bool, duration time.Duration) (err error)

SetCookie sets an http-only cookie using the passed name, value and domain. Returns an error if there was a problem encoding the value. if forceSecure is true, it will set the Secure flag to true, otherwise it sets it based on the connection. if duration == -1, it sets expires to 10 years in the past, if 0 it gets ignored (aka session-only cookie), if duration > 0, the expiration date gets set to now() + duration. Note that for more complex options, you can use http.SetCookie(ctx, &http.Cookie{...}).

func (*Context) Status

func (ctx *Context) Status() int

Status returns last value written using WriteHeader.

func (*Context) Write

func (ctx *Context) Write(p []byte) (int, error)

Write implements http.ResponseWriter

func (*Context) WriteHeader

func (ctx *Context) WriteHeader(s int)

WriteHeader and Write are to implement ResponseWriter and allows ghetto hijacking of http.ServeContent errors, without them we'd end up with plain text errors, we wouldn't want that, would we? WriteHeader implements http.ResponseWriter

func (*Context) WriteReader

func (ctx *Context) WriteReader(contentType string, r io.Reader) (int64, error)

WriteReader outputs the data from the passed reader with optional content-type.

type Error

type Error struct {
	Message   string `json:"message,omitempty"`
	Field     string `json:"field,omitempty"`
	IsMissing bool   `json:"isMissing,omitempty"`
}

Error is returned in the error field of a Response.

func (*Error) Error

func (e *Error) Error() string

type Group

type Group interface {
	// Use adds more middleware to the current group.
	// returning non-nil from a middleware returns early and doesn't execute the handlers.
	Use(mw ...Handler)

	// Group returns a sub-group starting at the specified path with this group's middlewares + any other ones.
	Group(name, path string, mw ...Handler) Group

	// Routes returns the current routes set.
	Routes() [][3]string

	// AddRoute adds a handler (or more) to the specific method and path
	// it is NOT safe to call this once you call one of the run functions
	AddRoute(method, path string, handlers ...Handler) error

	// GET is an alias for AddRoute("GET", path, handlers...).
	GET(path string, handlers ...Handler) error
	// PUT is an alias for AddRoute("PUT", path, handlers...).
	PUT(path string, handlers ...Handler) error
	// POST is an alias for AddRoute("POST", path, handlers...).
	POST(path string, handlers ...Handler) error
	// DELETE is an alias for AddRoute("DELETE", path, handlers...).
	DELETE(path string, handlers ...Handler) error

	// Static is a QoL wrapper to serving a directory.
	// If allowListing is true, it will fallback to using http.FileServer.
	Static(path, localPath string, allowListing bool) error

	// StaticFile is a QoL wrapper to serving a static file.
	StaticFile(path, localPath string) error
}

Group represents a handler group.

type Handler

type Handler func(ctx *Context) Response

Handler is the default server Handler In a handler chain, returning a non-nil breaks the chain.

func AllowCORS

func AllowCORS(methods, headers, origins []string, groups ...Group) Handler

AllowCORS allows CORS responses. If methods is empty, it will respond with the requested method. If headers is empty, it will respond with the requested headers. If origins is empty, it will respond with the requested origin. will automatically install an OPTIONS handler to each passed group.

func FromHTTPHandler

func FromHTTPHandler(h http.Handler) Handler

FromHTTPHandler returns a Handler from an http.Handler.

func FromHTTPHandlerFunc

func FromHTTPHandlerFunc(h http.HandlerFunc) Handler

FromHTTPHandlerFunc returns a Handler from an http.Handler.

func Gzip

func Gzip(level int) Handler

func LogRequests

func LogRequests(logJSONRequests bool) Handler

LogRequests is a request logger middleware. If logJSONRequests is true, it'll attempt to parse the incoming request's body and output it to the log.

func SecureCookie

func SecureCookie(hashKey, blockKey []byte) Handler

SecureCookie is a middleware to enable SecureCookies. For more details check `go doc securecookie.New`

func StaticDir

func StaticDir(dir, paramName string) Handler

StaticDir is a shorthand for StaticDirWithLimit(dir, paramName, -1).

func StaticDirStd

func StaticDirStd(prefix, dir string, allowListing bool) Handler

StaticDirStd is a QoL wrapper for http.FileServer(http.Dir(dir)).

func StaticDirWithLimit

func StaticDirWithLimit(dir, paramName string, limit int) Handler

StaticDirWithLimit returns a handler that handles serving static files. paramName is the path param, for example: s.GET("/s/*fp", StaticDirWithLimit("./static/", "fp", 1000)). if limit is > 0, it will only ever serve N files at a time. BUG: returns 0 size for some reason

type JSONPResponse

type JSONPResponse struct {
	Callback string `json:"-"`
	JSONResponse
}

JSONPResponse is the default standard api response

func NewJSONPErrorResponse

func NewJSONPErrorResponse(callbackKey string, code int, errs ...interface{}) *JSONPResponse

NewJSONPErrorResponse returns a new error response. each err can be: 1. string or []byte 2. error 3. Error / *Error 4. another response, its Errors will be appended to the returned Response. 5. if errs is empty, it will call http.StatusText(code) and set that as the error.

func NewJSONPResponse

func NewJSONPResponse(callbackKey string, data interface{}) *JSONPResponse

NewJSONPResponse returns a new success response (code 200) with the specific data

func (*JSONPResponse) WriteToCtx

func (r *JSONPResponse) WriteToCtx(ctx *Context) error

WriteToCtx writes the response to a ResponseWriter

type JSONResponse

type JSONResponse struct {
	Data    interface{} `json:"data,omitempty"`
	Errors  []Error     `json:"errors,omitempty"`
	Code    int         `json:"code"`
	Success bool        `json:"success"`
	Indent  bool        `json:"-"`
}

JSONResponse is the default standard api response

func NewJSONErrorResponse

func NewJSONErrorResponse(code int, errs ...interface{}) (r *JSONResponse)

NewJSONErrorResponse returns a new error response. each err can be: 1. string or []byte 2. error 3. Error / *Error 4. another response, its Errors will be appended to the returned Response. 5. MultiError 6. if errs is empty, it will call http.StatusText(code) and set that as the error.

func NewJSONResponse

func NewJSONResponse(data interface{}) *JSONResponse

NewJSONResponse returns a new success response (code 200) with the specific data

func ReadJSONResponse

func ReadJSONResponse(rc io.ReadCloser, dataValue interface{}) (r *JSONResponse, err error)

ReadJSONResponse reads a response from an io.ReadCloser and closes the body. dataValue is the data type you're expecting, for example:

r, err := ReadJSONResponse(res.Body, &map[string]*Stats{})

func (*JSONResponse) ErrorList

func (r *JSONResponse) ErrorList() *tkErrors.ErrorList

ErrorList returns an errors.ErrorList of this response's errors or nil. Deprecated: handled using MultiError

func (*JSONResponse) WriteToCtx

func (r *JSONResponse) WriteToCtx(ctx *Context) error

WriteToCtx writes the response to a ResponseWriter

type M

type M map[string]interface{}

func (M) ToJSON

func (m M) ToJSON(indent bool) string

ToJSON returns a string json representation of M, mostly for debugging.

type MultiError

type MultiError []error

MultiError handles returning multiple errors.

func (MultiError) Err

func (me MultiError) Err() error

Err returns nil if me is empty.

func (MultiError) Error

func (me MultiError) Error() string

func (*MultiError) Push

func (me *MultiError) Push(err error)

Push adds an error to the MultiError slice if err != nil.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option is a func to set internal server Options.

func MaxHeaderBytes

func MaxHeaderBytes(v int) Option

MaxHeaderBytes sets the max size of headers on the server. see http.Server.MaxHeaderBytes

func ReadTimeout

func ReadTimeout(v time.Duration) Option

ReadTimeout sets the read timeout on the server. see http.Server.ReadTimeout

func SetErrLogger

func SetErrLogger(v *log.Logger) Option

SetErrLogger sets the error logger on the server.

func SetKeepAlivePeriod

func SetKeepAlivePeriod(p time.Duration) Option

SetKeepAlivePeriod sets the underlying socket's keepalive period, set to -1 to disable socket keepalive. Not to be confused with http keep-alives which is controlled by apiserv.SetKeepAlivesEnabled.

func SetNoCatchPanics

func SetNoCatchPanics(enable bool) Option

SetNoCatchPanics toggles catching panics in handlers.

func SetOnReqDone

func SetOnReqDone(fn router.OnRequestDone) Option

func SetProfileLabels

func SetProfileLabels(enable bool) Option

func SetRouterOptions

func SetRouterOptions(v *router.Options) Option

SetRouterOptions sets apiserv/router.Options on the server.

func WriteTimeout

func WriteTimeout(v time.Duration) Option

WriteTimeout sets the write timeout on the server. see http.Server.WriteTimeout

type Options

type Options struct {
	Logger          *log.Logger
	RouterOptions   *router.Options
	ReadTimeout     time.Duration
	WriteTimeout    time.Duration
	KeepAlivePeriod time.Duration
	MaxHeaderBytes  int
}

Options allows finer control over the apiserv

type Response

type Response interface {
	WriteToCtx(ctx *Context) error
}

Response represents a generic return type for http responses.

var (
	RespMethodNotAllowed Response = NewJSONErrorResponse(http.StatusMethodNotAllowed)
	RespNotFound         Response = NewJSONErrorResponse(http.StatusNotFound)
	RespForbidden        Response = NewJSONErrorResponse(http.StatusForbidden)
	RespBadRequest       Response = NewJSONErrorResponse(http.StatusBadRequest)
	RespOK               Response = NewJSONResponse("OK")
	RespEmpty            Response = &simpleResp{code: http.StatusNoContent}
	RespPlainOK          Response = &simpleResp{code: http.StatusOK}
	RespRedirectRoot              = Redirect("/", false)

	// Break can be returned from a handler to break a handler chain.
	// It doesn't write anything to the connection.
	// if you reassign this, a wild animal will devour your face.
	Break Response = &simpleResp{}
)

Common responses

func File

func File(contentType, fp string) Response

File returns a file response. example: return File("plain/html", "index.html")

func PlainResponse

func PlainResponse(contentType string, val interface{}) Response

PlainResponse returns SimpleResponse(200, contentType, val).

func Redirect

func Redirect(url string, perm bool) Response

Redirect returns a redirect Response. if perm is false it uses http.StatusFound (302), otherwise http.StatusMovedPermanently (302)

func RedirectWithCode

func RedirectWithCode(url string, code int) Response

RedirectWithCode returns a redirect Response with the specified status code.

func SimpleResponse

func SimpleResponse(code int, contentType string, val interface{}) Response

SimpleResponse is a QoL wrapper to return a response with the specified code and content-type. val can be: nil, []byte, string, io.Writer, anything else will be written with fmt.Printf("%v").

type Server

type Server struct {
	PanicHandler    func(ctx *Context, v interface{})
	NotFoundHandler func(ctx *Context)
	// contains filtered or unexported fields
}

Server is the main server

func New

func New(opts ...Option) *Server

New returns a new server with the specified options.

func NewWithOpts

func NewWithOpts(opts *Options) *Server

NewWithOpts allows passing the Options struct directly

func (Server) AddRoute

func (g Server) AddRoute(method, path string, handlers ...Handler) error

AddRoute adds a handler (or more) to the specific method and path it is NOT safe to call this once you call one of the run functions

func (*Server) Addrs

func (s *Server) Addrs() (out []string)

Addrs returns all the listening addresses used by the underlying http.Server(s).

func (*Server) AllowCORS

func (s *Server) AllowCORS(path string, allowedMethods ...string) error

AllowCORS is an alias for s.AddRoute("OPTIONS", path, AllowCORS(allowedMethods...))

func (*Server) Close

func (s *Server) Close() error

Close immediately closes all the active underlying http servers and connections.

func (*Server) Closed

func (s *Server) Closed() bool

Closed returns true if the server is already shutdown/closed

func (Server) DELETE

func (g Server) DELETE(path string, handlers ...Handler) error

DELETE is an alias for AddRoute("DELETE", path, handlers...).

func (Server) GET

func (g Server) GET(path string, handlers ...Handler) error

GET is an alias for AddRoute("GET", path, handlers...).

func (Server) Group

func (g Server) Group(name, path string, mw ...Handler) Group

group returns a sub-handler group based on the current group's middleware

func (*Server) Logf

func (s *Server) Logf(f string, args ...interface{})

Logf logs to the default server logger if set

func (Server) POST

func (g Server) POST(path string, handlers ...Handler) error

POST is an alias for AddRoute("POST", path, handlers...).

func (Server) PUT

func (g Server) PUT(path string, handlers ...Handler) error

PUT is an alias for AddRoute("PUT", path, handlers...).

func (Server) Routes

func (g Server) Routes() [][3]string

Routes returns the current routes set. Each route is returned in the order of group name, method, path.

func (*Server) Run

func (s *Server) Run(addr string) error

Run starts the server on the specific address

func (*Server) RunAutoCert

func (s *Server) RunAutoCert(certCacheDir string, domains ...string) error

RunAutoCert enables automatic support for LetsEncrypt, using the optional passed domains list. certCacheDir is where the certificates will be cached, defaults to "./autocert". Note that it must always run on *BOTH* ":80" and ":443" so the addr param is omitted.

func (*Server) RunTLS

func (s *Server) RunTLS(addr string, certPairs []CertPair) error

RunTLS starts the server on the specific address, using tls

func (*Server) RunTLSAndAuto

func (s *Server) RunTLSAndAuto(certCacheDir string, certPairs []CertPair, hosts *AutoCertHosts) error

RunTLSAndAuto allows using custom certificates and autocert together. It will always listen on both :80 and :443

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP allows using the server in custom scenarios that expects an http.Handler.

func (*Server) SetKeepAlivesEnabled

func (s *Server) SetKeepAlivesEnabled(v bool)

SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled. By default, keep-alives are always enabled.

func (*Server) Shutdown

func (s *Server) Shutdown(timeout time.Duration) error

Shutdown gracefully shutsdown all the underlying http servers. You can optionally set a timeout.

func (Server) Static

func (g Server) Static(path, localPath string, allowListing bool) error

func (Server) StaticFile

func (g Server) StaticFile(path, localPath string) error

func (Server) Use

func (g Server) Use(mw ...Handler)

Use adds more middleware to the current group.

type XMLResponse

type XMLResponse struct {
	Data    interface{} `json:"data,omitempty"`
	Errors  []*Error    `json:"errors,omitempty"`
	Code    int         `json:"code"`
	Success bool        `json:"success"`
	Indent  bool        `json:"-"`
}

XMLResponse is the default standard api response using xml from data

func NewXMLResponse

func NewXMLResponse(data interface{}) *XMLResponse

func (*XMLResponse) WriteToCtx

func (r *XMLResponse) WriteToCtx(ctx *Context) error

WriteToCtx writes the response to a ResponseWriter

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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