Skip to content

Commit

Permalink
Switch to pressly/chi router (#7)
Browse files Browse the repository at this point in the history
* Switch to `pressly/chi` router
* Use generic error for missing records
  • Loading branch information
devmach committed Feb 25, 2017
1 parent 94e11bd commit 4193068
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 66 deletions.
55 changes: 38 additions & 17 deletions event/routes.go
@@ -1,17 +1,20 @@
package event

import (
"github.com/gin-gonic/gin"
"net/http"

"github.com/gomeetups/gomeetups/models"
"github.com/pressly/chi"
"github.com/pressly/chi/render"
)

func handleSearch(services *models.Services) gin.HandlerFunc {
return func(c *gin.Context) {
func handleSearch(services *models.Services) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

var params = models.ValidEventSearchParams{
Name: c.DefaultQuery("name", ""),
Description: c.DefaultQuery("description", ""),
GroupID: c.DefaultQuery("group", ""),
Name: r.URL.Query().Get("name"),
Description: r.URL.Query().Get("description"),
GroupID: r.URL.Query().Get("group"),
}

if events, err := services.EventService.SearchEvents(&params); err == nil {
Expand All @@ -33,20 +36,23 @@ func handleSearch(services *models.Services) gin.HandlerFunc {
}
}

c.JSON(200, gin.H{
render.JSON(w, r, map[string]interface{}{
"entries": events,
})

} else {
c.JSON(200, gin.H{"error": err})
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, map[string]interface{}{
"error": err,
})
}

}
}

func handleEventDetails(services *models.Services) gin.HandlerFunc {
return func(c *gin.Context) {
eventID := c.Params.ByName("eventID")
func handleEventDetails(services *models.Services) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
eventID := chi.URLParam(r, "eventID")
if event, err := services.EventService.Get(eventID); err == nil {

if space, _ := services.SpaceService.Get(event.SpaceID); space != nil {
Expand All @@ -55,15 +61,30 @@ func handleEventDetails(services *models.Services) gin.HandlerFunc {

event.Rsvps, _ = services.RsvpService.GetByEventID(event.EventID)

c.JSON(200, gin.H{"event": event})
render.JSON(w, r, map[string]interface{}{
"event": event,
})
} else {
c.JSON(404, gin.H{"error": err.Error()})
status := http.StatusInternalServerError

if err == models.ErrRecordNotFound {
status = http.StatusNotFound
}
render.Status(r, status)

render.JSON(w, r, map[string]interface{}{
"error": err.Error(),
})
}
}
}

// Router Contains routes for Group endpoints
func Router(router *gin.RouterGroup, services *models.Services) {
router.GET("/", handleSearch(services))
router.GET("/:eventID", handleEventDetails(services))
// Router Contains routes for event endpoints
func Router(services *models.Services) http.Handler {
router := chi.NewRouter()

router.Get("/", handleSearch(services))
router.Get("/:eventID", handleEventDetails(services))

return router
}
3 changes: 1 addition & 2 deletions event/serviceMemory.go
@@ -1,7 +1,6 @@
package event

import (
"errors"
"strings"

"github.com/gomeetups/gomeetups/fixtures"
Expand Down Expand Up @@ -56,5 +55,5 @@ func (*ServiceMemory) Get(eventID string) (event models.Event, err error) {
}
}

return models.Event{}, errors.New("Not found!")
return models.Event{}, models.ErrRecordNotFound
}
52 changes: 37 additions & 15 deletions group/routes.go
@@ -1,16 +1,19 @@
package group

import (
"net/http"

"github.com/gomeetups/gomeetups/models"
"github.com/gin-gonic/gin"
"github.com/pressly/chi"
"github.com/pressly/chi/render"
)

func handleSearch(services *models.Services) gin.HandlerFunc {
return func(c *gin.Context) {
func handleSearch(services *models.Services) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

var params = models.ValidGroupSearchParams{
Name: c.DefaultQuery("name", ""),
Description: c.DefaultQuery("description", ""),
Name: r.URL.Query().Get("name"),
Description: r.URL.Query().Get("description"),
}

if groups, err := services.GroupService.SearchGroups(&params); err == nil {
Expand All @@ -36,20 +39,23 @@ func handleSearch(services *models.Services) gin.HandlerFunc {

}

c.JSON(200, gin.H{
render.JSON(w, r, map[string]interface{}{
"entries": groups,
})

} else {
c.JSON(200, gin.H{"error": err})
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, map[string]interface{}{
"error": err,
})
}

}
}

func handleGroupDetails(services *models.Services) gin.HandlerFunc {
return func(c *gin.Context) {
groupID := c.Params.ByName("groupID")
func handleGroupDetails(services *models.Services) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
groupID := chi.URLParam(r, "groupID")
if group, err := services.GroupService.Get(groupID); err == nil {

addresses, _ := services.AddressService.GetByGroupID([]string{group.GroupID})
Expand All @@ -63,15 +69,31 @@ func handleGroupDetails(services *models.Services) gin.HandlerFunc {
group.Photos = photos[group.GroupID]
}

c.JSON(200, gin.H{"group": group})
render.JSON(w, r, map[string]interface{}{
"group": group,
})

} else {
c.JSON(404, gin.H{"error": err.Error()})

status := http.StatusInternalServerError

if err == models.ErrRecordNotFound {
status = http.StatusNotFound
}
render.Status(r, status)
render.JSON(w, r, map[string]interface{}{
"error": err.Error(),
})
}
}
}

// Router Contains routes for Group endpoints
func Router(router *gin.RouterGroup, services *models.Services) {
router.GET("/", handleSearch(services))
router.GET("/:groupID", handleGroupDetails(services))
func Router(services *models.Services) http.Handler {
router := chi.NewRouter()

router.Get("/", handleSearch(services))
router.Get("/:groupID", handleGroupDetails(services))

return router
}
3 changes: 1 addition & 2 deletions group/serviceMemory.go
@@ -1,7 +1,6 @@
package group

import (
"errors"
"strings"

"github.com/gomeetups/gomeetups/fixtures"
Expand Down Expand Up @@ -58,5 +57,5 @@ func (*ServiceMemory) Get(groupID string) (group models.Group, err error) {
}
}

return models.Group{}, errors.New("Not found!")
return models.Group{}, models.ErrRecordNotFound
}
46 changes: 38 additions & 8 deletions main.go
@@ -1,9 +1,13 @@
package main

import (
"context"
"fmt"
"net/http"
"os"
"time"

"github.com/Sirupsen/logrus"
"github.com/gomeetups/gomeetups/address"
"github.com/gomeetups/gomeetups/event"
"github.com/gomeetups/gomeetups/group"
Expand All @@ -12,15 +16,24 @@ import (
"github.com/gomeetups/gomeetups/rsvp"
"github.com/gomeetups/gomeetups/space"
"github.com/gomeetups/gomeetups/user"

"github.com/gin-gonic/gin"
"github.com/pressly/chi"
"github.com/pressly/lg"
)

var newYork, _ = time.LoadLocation("America/New_York")

func main() {
router := gin.Default()
func getListenAddr() string {
PORT := os.Getenv("PORT")
HOST := os.Getenv("HOST")

if PORT == "" {
PORT = "5000"
}

return fmt.Sprintf("%s:%s", HOST, PORT)
}

func main() {
services := models.Services{
GroupService: &group.ServiceMemory{},
AddressService: &address.ServiceMemory{},
Expand All @@ -31,9 +44,26 @@ func main() {
RsvpService: &rsvp.ServiceMemory{},
}

group.Router(router.Group("/api/v1/groups"), &services)
event.Router(router.Group("/api/v1/events"), &services)
user.Router(router.Group("/api/v1/users"), &services)
logger := logrus.New()
logger.Formatter = &logrus.JSONFormatter{}

lg.RedirectStdlogOutput(logger)
lg.DefaultLogger = logger

serverCtx := context.Background()
serverCtx = lg.WithLoggerContext(serverCtx, logger)

lg.Log(serverCtx).Infof("Listening on %s", getListenAddr())

router := chi.NewRouter()
router.Use(lg.RequestLogger(logger))

router.Route("/api/v1", func(router chi.Router) {
router.Mount("/groups", group.Router(&services))
router.Mount("/events", event.Router(&services))
router.Mount("/users", user.Router(&services))
})

http.ListenAndServe(":3000", router)
service := chi.ServerBaseContext(router, serverCtx)
http.ListenAndServe(getListenAddr(), service)
}
7 changes: 7 additions & 0 deletions models/app.go
@@ -0,0 +1,7 @@
package models

import "errors"

var (
ErrRecordNotFound = errors.New("Record not found!")
)
1 change: 0 additions & 1 deletion models/user.go
Expand Up @@ -6,7 +6,6 @@ import (
)

var (
ErrUserNotFound = errors.New("User not found!")
ErrUserInvalidParam = errors.New("Invalid parameter!")
ErrUserInvalidPassword = errors.New("Invalid Password!")
)
Expand Down
53 changes: 35 additions & 18 deletions user/routes.go
@@ -1,15 +1,18 @@
package user

import (
"net/http"

"github.com/gomeetups/gomeetups/models"
"github.com/gin-gonic/gin"
"github.com/pressly/chi"
"github.com/pressly/chi/render"
)

func handleSearch(services *models.Services) gin.HandlerFunc {
return func(c *gin.Context) {
func handleSearch(services *models.Services) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

var params = models.ValidUserSearchParams{
DisplayName: c.DefaultQuery("displayName", ""),
DisplayName: r.URL.Query().Get("displayName"),
}

if users, err := services.UserService.Search(&params); err == nil {
Expand All @@ -22,39 +25,53 @@ func handleSearch(services *models.Services) gin.HandlerFunc {
scrubbedData[idx] = user
}

c.JSON(200, gin.H{
render.JSON(w, r, map[string]interface{}{
"entries": scrubbedData,
})

} else {
c.JSON(404, gin.H{"error": err.Error()})
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, map[string]interface{}{
"error": err.Error(),
})
}

}
}

func handleUserDetails(services *models.Services) gin.HandlerFunc {
return func(c *gin.Context) {
userID := c.Params.ByName("userID")
func handleUserDetails(services *models.Services) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
userID := chi.URLParam(r, "userID")
if record, err := services.UserService.GetByID(userID); err == nil {
user := *record
user.Email = "***"

c.JSON(200, gin.H{"user": user})
render.JSON(w, r, map[string]interface{}{
"user": user,
})

} else {
statusCode := 500
status := http.StatusInternalServerError

if err == models.ErrUserNotFound {
statusCode = 404
if err == models.ErrRecordNotFound {
status = http.StatusNotFound
}

c.JSON(statusCode, gin.H{"error": err.Error()})
render.Status(r, status)
render.JSON(w, r, map[string]interface{}{
"error": err.Error(),
})

}
}
}

// Router Contains routes for Group endpoints
func Router(router *gin.RouterGroup, services *models.Services) {
router.GET("/", handleSearch(services))
router.GET("/:userID", handleUserDetails(services))
// Router Contains routes for user endpoints
func Router(services *models.Services) http.Handler {
router := chi.NewRouter()

router.Get("/", handleSearch(services))
router.Get("/:userID", handleUserDetails(services))

return router
}

0 comments on commit 4193068

Please sign in to comment.