Skip to content

Commit

Permalink
Merge branch 'release/v0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
diffuse committed Jul 5, 2020
2 parents f344c29 + 5993c7f commit 1fefa67
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 87 deletions.
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ gloss (Golang open simple service) provides boilerplate routing, database setup,
microservice up and running. It includes example code to increment and retrieve counter values from a PostgreSQL
database. Ideally, one would fork, or clone + mirror push this repository, then edit the handlers + routes, database
queries, and configurations for their own purposes. It uses [chi](https://github.com/go-chi/chi) for routing, and
[pgx](https://github.com/jackc/pgx) for its PostgreSQL database driver.
[pgx](https://github.com/jackc/pgx) for its PostgreSQL database driver, but other databases or routers can be used
by implementing the `Database` interface from `domain.go`, and/or the `Handler` interface from `net/http`.

### Prerequisites
- [Docker](https://www.docker.com/)
Expand Down Expand Up @@ -73,14 +74,27 @@ psql -h localhost -p 5432 -U test -d test
```

### Adapting to your own implementation
- Add your business logic methods to the `gloss.Database` interface (found in `domain.go`, then implement it in a
custom package (e.g. the example counter `IncrementCounter` and `GetCounterVal` methods, implemented in the pgsql
package)
- You can also just edit the pgsql package and change the domain interface methods if you want to use PostgreSQL
- Use your `gloss.Database` implementation by assigning an instance of your package's Database to the `Db` var in
`handlers.go`
- Replace/change the example handler bodies in `handlers.go` to perform your business logic
- Update the routes in `routes.go` to use your handlers
#### Database
- Add your business logic methods to the `Database` interface (found in `domain.go`), then implement them in a
custom package
- See the `IncrementCounter` and `GetCounterVal` methods for an example of this, implemented in the `pgsql`
package
- You can also just edit the `pgsql` package and change the domain interface methods if you want to continue using
PostgreSQL

#### Routing
- Implement the `net/http` `Handler` interface, or edit the existing implementation in the `chi` package
- Replace/change the example handler bodies in `handlers.go` to perform your business logic
- Update the routes in `handlers.go`:`setupRoutes` to use your handlers

#### Putting it all together
- Pass an instance of your `Database` implementation to your custom `Handler`, and use the instance to perform
business logic in handler functions
- An example of this is shown in `cmd/gloss/main.go`, where `pgsql`'s `Database` implementation is used with `chi`'s
`Handler` implementation
- A `pgsql.Database` instance is created, then passed as a parameter to `chi.NewRouter`, which creates a router,
associates handler functions in the `chi` package with routes, then stores the `pgsql.Database` instance so it can
be used in the custom handlers

### Disclaimer and considerations for deployment
The deployment scripts, configurations, and any defaults included in this repository are not, under any circumstances,
Expand Down
78 changes: 78 additions & 0 deletions chi/handlers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package chi

import (
"github.com/diffuse/gloss"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"net/http"
"strconv"
)

type Router struct {
*chi.Mux
db gloss.Database
}

// NewRouter creates a router, associates a database
// with it, and mounts API routes
func NewRouter(db gloss.Database) *Router {
r := &Router{db: db}
r.setupRoutes()

return r
}

// setupRoutes
func (rt *Router) setupRoutes() {
// set routes
routes := chi.NewRouter()
routes.Post("/counter/{counterId}", rt.IncrementCounterById)
routes.Get("/counter/{counterId}", rt.GetCounterById)

// setup router
rt.Mux = chi.NewRouter()

// set middleware
rt.Mux.Use(
middleware.Logger,
middleware.Recoverer)

// mount routes on versioned path
rt.Mux.Mount("/v1", routes)
}

// Increment the value of the counter with ID counterId
func (rt *Router) IncrementCounterById(w http.ResponseWriter, r *http.Request) {
// get the counter ID
counterId, err := strconv.ParseUint(chi.URLParam(r, "counterId"), 10, 32)
if err != nil {
http.Error(w, "invalid counter ID", http.StatusBadRequest)
return
}

// increment in db
if err := rt.db.IncrementCounter(int(counterId)); err != nil {
http.Error(w, "failed to increment counter value", http.StatusInternalServerError)
}
}

// Get the value of the counter with ID counterId
func (rt *Router) GetCounterById(w http.ResponseWriter, r *http.Request) {
// get the counter ID
counterId, err := strconv.ParseInt(chi.URLParam(r, "counterId"), 10, 32)
if err != nil {
http.Error(w, "invalid counter ID", http.StatusBadRequest)
return
}

// get value and return to requester
val, err := rt.db.GetCounterVal(int(counterId))
if err != nil {
http.Error(w, "failed to get counter value", http.StatusNotFound)
return
}

if _, err := w.Write([]byte(strconv.Itoa(val))); err != nil {
panic(err)
}
}
25 changes: 10 additions & 15 deletions cmd/gloss/main.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
package main

import (
"github.com/diffuse/gloss"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/diffuse/gloss/chi"
"github.com/diffuse/gloss/pgsql"
"log"
"net/http"
"time"
)

func main() {
// close the db connections on exit
defer gloss.Db.Close()
// create a thread-safe database instance for use with the router
log.Println("connecting to database")
db := pgsql.NewDatabase()
defer db.Close()

// setup router
r := chi.NewRouter()

// set middleware
r.Use(
middleware.Logger,
middleware.Recoverer)

// mount routes on versioned path
r.Mount("/v1", gloss.GetRoutes())
// create a router and associate the database with it
log.Println("setting up routes")
r := chi.NewRouter(db)

// create server with some reasonable defaults
s := &http.Server{
Expand All @@ -35,5 +29,6 @@ func main() {
}

// serve
log.Println("serving")
log.Fatal(s.ListenAndServe())
}
51 changes: 0 additions & 51 deletions handlers.go

This file was deleted.

2 changes: 1 addition & 1 deletion pgsql/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

type Database struct {
db *pgx.Conn
db *pgx.Conn
ctx context.Context
}

Expand Down
11 changes: 0 additions & 11 deletions routes.go

This file was deleted.

0 comments on commit 1fefa67

Please sign in to comment.