Documentation ¶
Overview ¶
Package smartapi allows to quickly implement solid REST APIs in Golang. The idea behind the project is to replace handler functions with ordinary looking functions. This allows service layer methods to be used as handlers. Designation of a dedicated API layer is still advisable in order to map errors to status codes, write cookies, headers, etc.
SmartAPI is based on github.com/go-chi/chi. This allows Chi middlewares to be used.
Examples ¶
This example returns a greeting with a name based on a query param `name`.
package main import ( "fmt" "log" "net/http" "github.com/mmbednarek/smartapi" ) func MountAPI() http.Handler { r := smartapi.NewRouter() r.Get("/greeting", Greeting, smartapi.QueryParam("name"), ) return r.MustHandler() } func Greeting(name string) string { return fmt.Sprintf("Hello %s!\n", name) } func main() { log.Fatal(http.ListenAndServe(":8080", MountAPI())) }
It's possible to use even standard Go functions ¶
But it's a good practice to use your own handler functions for your api.
package main import ( "encoding/base32" "encoding/base64" "log" "net/http" "github.com/mmbednarek/smartapi" ) func MountAPI() http.Handler { r := smartapi.NewRouter() r.Route("/encode", func(r smartapi.Router) { r.Post("/base64", base64.StdEncoding.EncodeToString) r.Post("/base32", base32.StdEncoding.EncodeToString) }, smartapi.ByteSliceBody()) r.Route("/decode", func(r smartapi.Router) { r.Post("/base64", base64.StdEncoding.DecodeString) r.Post("/base32", base32.StdEncoding.DecodeString) }, smartapi.StringBody()) return r.MustHandler() } func main() { log.Fatal(http.ListenAndServe(":8080", MountAPI())) }
You can use SmartAPI with service layer methods as shown here.
package main import ( "log" "net/http" "github.com/mmbednarek/smartapi" ) type Date struct { Day int `json:"day"` Month int `json:"month"` Year int `json:"year"` } type User struct { Login string `json:"login"` Password string `json:"password,omitempty"` Email string `json:"email"` DateOfBirth Date `json:"date_of_birth"` } type Service interface { RegisterUser(user *User) error Auth(login, password string) (string, error) GetUserData(session string) (*User, error) UpdateUser(session string, user *User) error } func newHandler(service Service) http.Handler { r := smartapi.NewRouter() r.Post("/user", service.RegisterUser, smartapi.JSONBody(User{}), ) r.Post("/user/auth", service.Auth, smartapi.PostQueryParam("login"), smartapi.PostQueryParam("password"), ) r.Get("/user", service.GetUserData, smartapi.Header("X-Session-ID"), ) r.Patch("/user", service.UpdateUser, smartapi.Header("X-Session-ID"), smartapi.JSONBody(User{}), ) return r.MustHandler() } func main() { svr := service.NewService() // Your service implementation log.Fatal(http.ListenAndServe(":8080", newHandler(svr))) }
Middlewares can be used just as in Chi. `Use(...)` appends middlewares to be used. `With(...)` creates a copy of a router with chosen middlewares.
Routing works similarity to Chi routing. Parameters can be prepended to be used in all endpoints in that route.
r.Route("/v1/foo", func(r smartapi.Router) { r.Route("/bar", func(r smartapi.Router) { r.Get("/test", func(ctx context.Context, foo string, test string) { ... }, smartapi.QueryParam("test"), ) }, smartapi.Header("X-Foo"), ) }, smartapi.Context(), )
Support for legacy handlers ¶
Legacy handlers are supported with no overhead. They are directly passed as ordinary handler functions. No additional variadic arguments are required for legacy handler to be used.
Index ¶
- func NewRouter() *router
- func NewRouterLogger(logger Logger) *router
- func StartAPI(a API, address string) error
- type API
- type ApiError
- type Argument
- type Cookies
- type EndpointParam
- func AsByteSlice(param EndpointParam) EndpointParam
- func AsInt(param EndpointParam) EndpointParam
- func BodyReader() EndpointParam
- func ByteSliceBody() EndpointParam
- func Context() EndpointParam
- func Cookie(name string) EndpointParam
- func Header(name string) EndpointParam
- func JSONBody(v interface{}) EndpointParam
- func JSONBodyDirect(v interface{}) EndpointParam
- func PostQueryParam(name string) EndpointParam
- func QueryParam(name string) EndpointParam
- func Request() EndpointParam
- func RequestStruct(s interface{}) EndpointParam
- func RequestStructDirect(s interface{}) EndpointParam
- func RequiredCookie(name string) EndpointParam
- func RequiredHeader(name string) EndpointParam
- func RequiredPostQueryParam(name string) EndpointParam
- func RequiredQueryParam(name string) EndpointParam
- func ResponseCookies() EndpointParam
- func ResponseHeaders() EndpointParam
- func ResponseStatus(status int) EndpointParam
- func ResponseWriter() EndpointParam
- func StringBody() EndpointParam
- func URLParam(name string) EndpointParam
- func XMLBody(v interface{}) EndpointParam
- type Headers
- type Logger
- type Method
- type RouteHandler
- type Router
- type Server
- func (r *Server) AddEndpoint(method Method, name string, handler interface{}, params []EndpointParam)
- func (r *Server) Connect(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Delete(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Get(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Handle(pattern string, handler http.Handler)
- func (r *Server) Handler() (http.Handler, error)
- func (r *Server) Head(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) MustHandler() http.Handler
- func (r *Server) Options(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Patch(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Post(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Put(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Route(pattern string, handler RouteHandler, params ...EndpointParam)
- func (s *Server) Start(address string) error
- func (r *Server) Trace(pattern string, handler interface{}, args ...EndpointParam)
- func (r *Server) Use(middlewares ...func(http.Handler) http.Handler)
- func (r *Server) With(middlewares ...func(http.Handler) http.Handler) Router
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewRouterLogger ¶
func NewRouterLogger(logger Logger) *router
Types ¶
type ApiError ¶
ApiError represents an API error
type Argument ¶
type Argument interface { EndpointParam // contains filtered or unexported methods }
Argument represents an argument passed to a function
type EndpointParam ¶
type EndpointParam interface {
// contains filtered or unexported methods
}
EndpointParam is used with endpointData definition
func AsByteSlice ¶
func AsByteSlice(param EndpointParam) EndpointParam
AsByteSlice converts an argument and passes it as a byte slice
func AsInt ¶
func AsInt(param EndpointParam) EndpointParam
AsInt converts an argument and passes it as an int into the function
func BodyReader ¶
func BodyReader() EndpointParam
BodyReader passes an io.Reader interface to read request's body.
func ByteSliceBody ¶
func ByteSliceBody() EndpointParam
ByteSliceBody reads request's body end passes it as a byte slice.
func Cookie ¶
func Cookie(name string) EndpointParam
Cookie reads a cookie from the request and passes it as a string
func Header ¶
func Header(name string) EndpointParam
Header reads a header from the request and passes it as string to a function
func JSONBody ¶
func JSONBody(v interface{}) EndpointParam
JSONBody reads request's body and unmarshals it into a pointer to a json structure
func JSONBodyDirect ¶
func JSONBodyDirect(v interface{}) EndpointParam
JSONBodyDirect reads request's body and unmarshals it into a json structure
func PostQueryParam ¶
func PostQueryParam(name string) EndpointParam
PostQueryParam parses query end passes post query param into a string as an argument
func QueryParam ¶
func QueryParam(name string) EndpointParam
QueryParam reads a query param and passes it as a string
func RequestStruct ¶
func RequestStruct(s interface{}) EndpointParam
RequestStruct passes request's arguments into struct's fields by tags
func RequestStructDirect ¶
func RequestStructDirect(s interface{}) EndpointParam
RequestStructDirect passes request's arguments into struct's fields by tags
func RequiredCookie ¶
func RequiredCookie(name string) EndpointParam
RequiredCookie reads a cookie from the request and passes it as a string
func RequiredHeader ¶
func RequiredHeader(name string) EndpointParam
RequiredHeader reads a header from the request and passes it as string to a function
func RequiredPostQueryParam ¶
func RequiredPostQueryParam(name string) EndpointParam
RequiredPostQueryParam reads a post query param and passes it as a string. Returns 400 BAD REQUEST if empty.
func RequiredQueryParam ¶
func RequiredQueryParam(name string) EndpointParam
RequiredQueryParam reads a query param and passes it as a string. Returns 400 BAD REQUEST when empty
func ResponseCookies ¶
func ResponseCookies() EndpointParam
ResponseCookies passes an interface to set cookie values
func ResponseHeaders ¶
func ResponseHeaders() EndpointParam
ResponseHeaders passes an interface to set response header values
func ResponseStatus ¶
func ResponseStatus(status int) EndpointParam
ResponseStatus allows to set successful response status
func ResponseWriter ¶
func ResponseWriter() EndpointParam
ResponseWriter passes an http.ResponseWriter into a function
func StringBody ¶
func StringBody() EndpointParam
StringBody reads request's body end passes it as a string
func URLParam ¶
func URLParam(name string) EndpointParam
URLParam reads a url param and passes it as a string
func XMLBody ¶
func XMLBody(v interface{}) EndpointParam
XMLBody reads request's body and unmarshals it into a pointer to an xml structure
type Logger ¶
type Logger interface { LogApiError(ctx context.Context, err ApiError) LogError(ctx context.Context, err error) }
Logger logs the outcome of unsuccessful http requests
var DefaultLogger Logger = defaultLogger{}
DefaultLogger is simple implementation of the Logger interface
type RouteHandler ¶
type RouteHandler func(r Router)
type Router ¶
type Router interface { Use(middlewares ...func(http.Handler) http.Handler) With(middlewares ...func(http.Handler) http.Handler) Router AddEndpoint(method Method, pattern string, handler interface{}, args []EndpointParam) Post(pattern string, handler interface{}, args ...EndpointParam) Get(pattern string, handler interface{}, args ...EndpointParam) Put(pattern string, handler interface{}, args ...EndpointParam) Patch(pattern string, handler interface{}, args ...EndpointParam) Delete(pattern string, handler interface{}, args ...EndpointParam) Head(pattern string, handler interface{}, args ...EndpointParam) Options(pattern string, handler interface{}, args ...EndpointParam) Connect(pattern string, handler interface{}, args ...EndpointParam) Trace(pattern string, handler interface{}, args ...EndpointParam) Route(pattern string, handler RouteHandler, args ...EndpointParam) Handle(pattern string, handler http.Handler) Handler() (http.Handler, error) MustHandler() http.Handler }
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server handles http endpoints
func (*Server) AddEndpoint ¶
func (r *Server) AddEndpoint(method Method, name string, handler interface{}, params []EndpointParam)
func (*Server) Connect ¶
func (r *Server) Connect(pattern string, handler interface{}, args ...EndpointParam)
Connect adds an endpoint with a CONNECT Method
func (*Server) Delete ¶
func (r *Server) Delete(pattern string, handler interface{}, args ...EndpointParam)
Delete adds an endpoint with a DELETE Method
func (*Server) Get ¶
func (r *Server) Get(pattern string, handler interface{}, args ...EndpointParam)
Get adds an endpoint with a GET Method
func (*Server) Head ¶
func (r *Server) Head(pattern string, handler interface{}, args ...EndpointParam)
Head adds an endpoint with a HEAD Method
func (*Server) MustHandler ¶
MustHandler returns a handler but panics if handler cannot be obtained
func (*Server) Options ¶
func (r *Server) Options(pattern string, handler interface{}, args ...EndpointParam)
Options adds an endpoint with a OPTIONS Method
func (*Server) Patch ¶
func (r *Server) Patch(pattern string, handler interface{}, args ...EndpointParam)
Patch adds an endpoint with a PATCH Method
func (*Server) Post ¶
func (r *Server) Post(pattern string, handler interface{}, args ...EndpointParam)
Post adds an endpoint with a POST Method
func (*Server) Put ¶
func (r *Server) Put(pattern string, handler interface{}, args ...EndpointParam)
Put adds an endpoint with a PUT Method
func (*Server) Route ¶
func (r *Server) Route(pattern string, handler RouteHandler, params ...EndpointParam)
Route routs endpoints to a specific path
func (*Server) Trace ¶
func (r *Server) Trace(pattern string, handler interface{}, args ...EndpointParam)
Trace adds an endpoint with a TRACE Method
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package mocks is a generated GoMock package.
|
Package mocks is a generated GoMock package. |