GoDoc and some typos...
This commit is contained in:
parent
9f37579562
commit
543b39f822
15 changed files with 37 additions and 19 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
|
# Go Restful API Boilerplate
|
||||||
|
|
||||||
## Go Restful API Boilerplate
|
[![GoDoc Badge]][GoDoc] [![GoReportCard Badge]][GoReportCard]
|
||||||
|
|
||||||
Easily extendible RESTful API boilerplate aiming to follow idiomatic go and best practice.
|
Easily extendible RESTful API boilerplate aiming to follow idiomatic go and best practice.
|
||||||
|
|
||||||
|
|
@ -75,3 +76,8 @@ EMAIL_FROM_NAME | string || from name used in sending emails
|
||||||
### Contributing
|
### Contributing
|
||||||
|
|
||||||
Any feedback and pull requests are welcome and highly appreciated. Please open an issue first if you intend to send in a larger pull request or want to add additional features.
|
Any feedback and pull requests are welcome and highly appreciated. Please open an issue first if you intend to send in a larger pull request or want to add additional features.
|
||||||
|
|
||||||
|
[GoDoc]: https://godoc.org/github.com/dhax/go-base
|
||||||
|
[GoDoc Badge]: https://godoc.org/github.com/dhax/go-base?status.svg
|
||||||
|
[GoReportCard]: https://goreportcard.com/report/github.com/dhax/go-base
|
||||||
|
[GoReportCard Badge]: https://goreportcard.com/badge/github.com/dhax/go-base
|
||||||
|
|
@ -27,7 +27,7 @@ type AccountStore interface {
|
||||||
Delete(*auth.Account) error
|
Delete(*auth.Account) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountResource implements account managment handler.
|
// AccountResource implements account management handler.
|
||||||
type AccountResource struct {
|
type AccountResource struct {
|
||||||
Store AccountStore
|
Store AccountStore
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package admin ties together administration resources and handlers.
|
||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package api configures an http server for administration and application resources.
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -19,8 +20,8 @@ import (
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewAPI configures application resources and routes.
|
// New configures application resources and routes.
|
||||||
func NewAPI() (*chi.Mux, error) {
|
func New() (*chi.Mux, error) {
|
||||||
logger := logging.NewLogger()
|
logger := logging.NewLogger()
|
||||||
|
|
||||||
db, err := database.DBConn()
|
db, err := database.DBConn()
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type AccountStore interface {
|
||||||
DeleteToken(*auth.Token) error
|
DeleteToken(*auth.Token) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccountResource implements account managment handler.
|
// AccountResource implements account management handler.
|
||||||
type AccountResource struct {
|
type AccountResource struct {
|
||||||
Store AccountStore
|
Store AccountStore
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ func (rs *AccountResource) accountCtx(next http.Handler) http.Handler {
|
||||||
|
|
||||||
type accountRequest struct {
|
type accountRequest struct {
|
||||||
*auth.Account
|
*auth.Account
|
||||||
// override protected data here, although not really neccessary here
|
// override protected data here, although not really necessary here
|
||||||
// as we limit updated database columns in store as well
|
// as we limit updated database columns in store as well
|
||||||
ProtectedID int `json:"id"`
|
ProtectedID int `json:"id"`
|
||||||
ProtectedActive bool `json:"active"`
|
ProtectedActive bool `json:"active"`
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package app ties together application resources and handlers.
|
||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ type Server struct {
|
||||||
// NewServer creates and configures an APIServer serving all application routes.
|
// NewServer creates and configures an APIServer serving all application routes.
|
||||||
func NewServer() (*Server, error) {
|
func NewServer() (*Server, error) {
|
||||||
log.Println("configuring server...")
|
log.Println("configuring server...")
|
||||||
api, err := NewAPI()
|
api, err := New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// Package auth provides JSON Web Token (JWT) authentication and authorization middleware.
|
||||||
|
// It implements a passwordless authentication flow by sending login tokens vie email which are then exchanged for JWT access and refresh tokens.
|
||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -59,7 +61,7 @@ func NewResource(store Storer, mailer Mailer) (*Resource, error) {
|
||||||
return resource, nil
|
return resource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Router provides neccessary routes for passwordless authentication flow.
|
// Router provides necessary routes for passwordless authentication flow.
|
||||||
func (rs *Resource) Router() *chi.Mux {
|
func (rs *Resource) Router() *chi.Mux {
|
||||||
r := chi.NewRouter()
|
r := chi.NewRouter()
|
||||||
r.Use(render.SetContentType(render.ContentTypeJSON))
|
r.Use(render.SetContentType(render.ContentTypeJSON))
|
||||||
|
|
|
||||||
|
|
@ -241,14 +241,16 @@ func TestAuthResource_refresh(t *testing.T) {
|
||||||
if tc.status == http.StatusUnauthorized && authstore.SaveRefreshTokenInvoked {
|
if tc.status == http.StatusUnauthorized && authstore.SaveRefreshTokenInvoked {
|
||||||
t.Errorf("SaveRefreshToken invoked for status %d", tc.status)
|
t.Errorf("SaveRefreshToken invoked for status %d", tc.status)
|
||||||
}
|
}
|
||||||
if tc.status == http.StatusOK && !authstore.GetByRefreshTokenInvoked {
|
if tc.status == http.StatusOK {
|
||||||
t.Errorf("GetRefreshToken not invoked")
|
if !authstore.GetByRefreshTokenInvoked {
|
||||||
}
|
t.Errorf("GetRefreshToken not invoked")
|
||||||
if tc.status == http.StatusOK && !authstore.SaveRefreshTokenInvoked {
|
}
|
||||||
t.Errorf("SaveRefreshToken not invoked")
|
if !authstore.SaveRefreshTokenInvoked {
|
||||||
}
|
t.Errorf("SaveRefreshToken not invoked")
|
||||||
if tc.status == http.StatusOK && authstore.DeleteRefreshTokenInvoked {
|
}
|
||||||
t.Errorf("DeleteRefreshToken should not be invoked")
|
if authstore.DeleteRefreshTokenInvoked {
|
||||||
|
t.Errorf("DeleteRefreshToken should not be invoked")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
authstore.GetByRefreshTokenInvoked = false
|
authstore.GetByRefreshTokenInvoked = false
|
||||||
authstore.SaveRefreshTokenInvoked = false
|
authstore.SaveRefreshTokenInvoked = false
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func genRoutesDoc() {
|
func genRoutesDoc() {
|
||||||
api, _ := api.NewAPI()
|
api, _ := api.New()
|
||||||
fmt.Print("generating routes markdown file: ")
|
fmt.Print("generating routes markdown file: ")
|
||||||
md := docgen.MarkdownRoutesDoc(api, docgen.MarkdownOpts{
|
md := docgen.MarkdownRoutesDoc(api, docgen.MarkdownOpts{
|
||||||
ProjectPath: "github.com/dhax/go-base",
|
ProjectPath: "github.com/dhax/go-base",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package migrate implements postgres migrations.
|
||||||
package migrate
|
package migrate
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package database implements postgres connection and queries.
|
||||||
package database
|
package database
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package email provides email sending functionality.
|
||||||
package email
|
package email
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package logging provides structured logging with logrus.
|
||||||
package logging
|
package logging
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -93,7 +94,7 @@ func (l *StructuredLoggerEntry) Write(status, bytes int, elapsed time.Duration)
|
||||||
l.Logger = l.Logger.WithFields(logrus.Fields{
|
l.Logger = l.Logger.WithFields(logrus.Fields{
|
||||||
"resp_status": status,
|
"resp_status": status,
|
||||||
"resp_bytes_length": bytes,
|
"resp_bytes_length": bytes,
|
||||||
"resp_elasped_ms": float64(elapsed.Nanoseconds()) / 1000000.0,
|
"resp_elapsed_ms": float64(elapsed.Nanoseconds()) / 1000000.0,
|
||||||
})
|
})
|
||||||
|
|
||||||
l.Logger.Infoln("request complete")
|
l.Logger.Infoln("request complete")
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
// Package models contains application specific entities.
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue