Documentation
¶
Overview ¶
Example ¶
// CC0-1.0: Creative Commons Zero v1.0 Universal
// No Rights Reserved - (CC) ZERO - (0) PUBLIC DOMAIN
//
// To the extent possible under law, the Teal.Finance contributors
// have waived all copyright and related or neighboring rights
// to this file "full-example_test.go" to be copied without restrictions.
// Refer to https://creativecommons.org/publicdomain/zero/1.0
package main
import (
"log"
"net"
"net/http"
"time"
"github.com/teal-finance/server"
"github.com/teal-finance/server/chain"
"github.com/teal-finance/server/cors"
"github.com/teal-finance/server/limiter"
"github.com/teal-finance/server/metrics"
"github.com/teal-finance/server/opa"
"github.com/teal-finance/server/reserr"
)
func main() {
// Uniformize error responses with API doc
resErr := reserr.New("https://my-dns.com/doc")
middlewares, connState := setMiddlewares(resErr)
// Handles both REST API and static web files
h := handler(resErr)
h = middlewares.Then(h)
runServer(h, connState)
}
func setMiddlewares(resErr reserr.ResErr) (middlewares chain.Chain, connState func(net.Conn, http.ConnState)) {
// Start a metrics server in background if export port > 0.
// The metrics server is for use with Prometheus or another compatible monitoring tool.
metrics := metrics.Metrics{}
middlewares, connState = metrics.StartServer(9093, true)
// Limit the input request rate per IP
reqLimiter := limiter.New(10, 20, true, resErr)
middlewares = middlewares.Append()
// Endpoint authentication rules (Open Policy Agent)
policy, err := opa.New(resErr, []string{"rego.json"})
if err != nil {
log.Fatal(err)
}
// CORS
allowedOrigins := []string{"http://my-dns.com"}
middlewares = middlewares.Append(
server.LogRequests,
reqLimiter.Limit,
server.Header("MyServerName-1.2.3"),
policy.Auth,
cors.HandleCORS(allowedOrigins),
)
return middlewares, connState
}
// runServer runs in foreground the main server.
func runServer(h http.Handler, connState func(net.Conn, http.ConnState)) {
server := http.Server{
Addr: ":8080",
Handler: h,
TLSConfig: nil,
ReadTimeout: 1 * time.Second,
ReadHeaderTimeout: 1 * time.Second,
WriteTimeout: 1 * time.Second,
IdleTimeout: 1 * time.Second,
MaxHeaderBytes: 222,
TLSNextProto: nil,
ConnState: connState,
ErrorLog: log.Default(),
BaseContext: nil,
ConnContext: nil,
}
log.Print("Server listening on http://localhost", server.Addr)
log.Fatal(server.ListenAndServe())
}
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Server ¶
type Server struct {
Version string
ResErr reserr.ResErr
// CORS
AllowedOrigins []string // used for CORS
// OPA
OPAFilenames []string
// contains filtered or unexported fields
}
Example ¶
// CC0-1.0: Creative Commons Zero v1.0 Universal
// No Rights Reserved - (CC) ZERO - (0) PUBLIC DOMAIN
//
// To the extent possible under law, the Teal.Finance contributors
// have waived all copyright and related or neighboring rights
// to this file "easy-example_test.go" to be copied without restrictions.
// Refer to https://creativecommons.org/publicdomain/zero/1.0
package main
import (
"log"
"net/http"
"github.com/go-chi/chi"
"github.com/teal-finance/server"
"github.com/teal-finance/server/fileserver"
"github.com/teal-finance/server/reserr"
)
func main() {
s := server.Server{
Version: "MyApp-1.2.3",
ResErr: "https://my-dns.com/doc",
AllowedOrigins: []string{"http://my-dns.com"},
OPAFilenames: []string{"rego.json"},
}
// Handles both REST API and static web files
h := handler(s.ResErr)
log.Fatal(s.RunServer(h, 8080, 9093, 10, 20, true))
}
// handler creates the mapping between the endpoints and the handler functions.
func handler(resErr reserr.ResErr) http.Handler {
r := chi.NewRouter()
// Static website files
fs := fileserver.FileServer{Dir: "/var/www/my-site", ResErr: resErr}
r.Get("/", fs.ServeFile("index.html", "text/html; charset=utf-8"))
r.Get("/js/*", fs.ServeDir("text/javascript; charset=utf-8"))
r.Get("/css/*", fs.ServeDir("text/css; charset=utf-8"))
r.Get("/images/*", fs.ServeImages())
// API
r.Get("/api/v1/items", items)
r.Get("/api/v1/ducks", resErr.NotImplemented)
// Other endpoints
r.NotFound(resErr.InvalidPath)
return r
}
func items(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`["item1","item2","item3"]`))
}
Output:
func (*Server) RunServer ¶
func (s *Server) RunServer(h http.Handler, port, expPort, maxReqBurst, maxReqPerMinute int, devMode bool) error
RunServer runs the HTTP server in foreground. Optionally it also starts a metrics server in background (if export port > 0). The metrics server is for use with Prometheus or another compatible monitoring tool.
Click to show internal directories.
Click to hide internal directories.
