Skip to content

Commit

Permalink
feat: add user api
Browse files Browse the repository at this point in the history
  • Loading branch information
mabdh committed Jan 27, 2022
1 parent 76748ed commit 4316f82
Show file tree
Hide file tree
Showing 16 changed files with 893 additions and 19 deletions.
7 changes: 7 additions & 0 deletions api/handlers/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package handlers

import "errors"

var (
errMissingUserID = errors.New("missing user id")
)
167 changes: 167 additions & 0 deletions api/handlers/user_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package handlers

import (
"errors"
"net/http"
"net/url"
"strconv"

"github.com/odpf/columbus/star"
"github.com/odpf/columbus/user"
"github.com/odpf/salt/log"
)

// UserHandler exposes a REST interface to user
type UserHandler struct {
starRepository star.Repository
logger log.Logger
}

func (h *UserHandler) GetStarred(w http.ResponseWriter, r *http.Request) {
userID := user.FromContext(r.Context())
if userID == "" {
h.logger.Warn(errMissingUserID.Error())
WriteJSONError(w, http.StatusBadRequest, errMissingUserID.Error())
return
}

starCfg := h.buildStarConfig(r.URL.Query())

starredAssets, err := h.starRepository.GetAllByUserID(r.Context(), starCfg, userID)
if err != nil {
if errors.As(err, new(star.InvalidError)) {
WriteJSONError(w, http.StatusBadRequest, err.Error())
return
}
if errors.As(err, new(star.NotFoundError)) {
WriteJSONError(w, http.StatusNotFound, err.Error())
return
}
internalServerError(w, h.logger, err.Error())
return
}

writeJSON(w, http.StatusOK, starredAssets)
}

func (h *UserHandler) StarAsset(w http.ResponseWriter, r *http.Request) {
userID := user.FromContext(r.Context())
if userID == "" {
h.logger.Warn(errMissingUserID.Error())
WriteJSONError(w, http.StatusBadRequest, errMissingUserID.Error())
return
}

starring := h.buildStar(r.URL.Query())

starID, err := h.starRepository.Create(r.Context(), userID, starring)
if err != nil {
if errors.As(err, new(star.InvalidError)) {
WriteJSONError(w, http.StatusBadRequest, err.Error())
return
}
if errors.As(err, new(star.UserNotFoundError)) {
WriteJSONError(w, http.StatusNotFound, err.Error())
return
}
if errors.As(err, new(star.DuplicateRecordError)) {
// idempotent
writeJSON(w, http.StatusNoContent, starID)
return
}
internalServerError(w, h.logger, err.Error())
return
}

writeJSON(w, http.StatusNoContent, starID)
}

func (h *UserHandler) GetStarredAsset(w http.ResponseWriter, r *http.Request) {
userID := user.FromContext(r.Context())
if userID == "" {
h.logger.Warn(errMissingUserID.Error())
WriteJSONError(w, http.StatusBadRequest, errMissingUserID.Error())
return
}

starring := h.buildStar(r.URL.Query())

starID, err := h.starRepository.GetUserStarredAsset(r.Context(), userID, starring)
if err != nil {
if errors.As(err, new(star.InvalidError)) {
WriteJSONError(w, http.StatusBadRequest, err.Error())
return
}
if errors.As(err, new(star.NotFoundError)) {
WriteJSONError(w, http.StatusNotFound, err.Error())
return
}
internalServerError(w, h.logger, err.Error())
return
}

writeJSON(w, http.StatusOK, starID)
}

func (h *UserHandler) UnstarAsset(w http.ResponseWriter, r *http.Request) {
userID := user.FromContext(r.Context())
if userID == "" {
h.logger.Warn(errMissingUserID.Error())
WriteJSONError(w, http.StatusBadRequest, errMissingUserID.Error())
return
}

starring := h.buildStar(r.URL.Query())

err := h.starRepository.Delete(r.Context(), userID, starring)
if err != nil {
if errors.As(err, new(star.InvalidError)) {
WriteJSONError(w, http.StatusBadRequest, err.Error())
return
}
if errors.As(err, new(star.NotFoundError)) {
// idempotent
writeJSON(w, http.StatusNoContent, "success")
return
}
internalServerError(w, h.logger, err.Error())
return
}

writeJSON(w, http.StatusNoContent, "success")
}

func (h *UserHandler) buildStarConfig(query url.Values) star.Config {
var page, size int
var err error
sizeString := query.Get("size")
if sizeString != "" {
size, err = strconv.Atoi(sizeString)
if err != nil {
h.logger.Warn("can't parse \"size\" query params")
}
}
pageString := query.Get("page")
if pageString != "" {
page, err = strconv.Atoi(pageString)
if err != nil {
h.logger.Warn("can't parse \"page\" query params")
}
}
return star.Config{Page: page, Size: size}
}

func (h *UserHandler) buildStar(query url.Values) *star.Star {
return &star.Star{
AssetType: query.Get("asset_type"),
AssetURN: query.Get("asset_urn"),
}
}

func NewUserHandler(logger log.Logger, repo star.Repository) *UserHandler {
h := &UserHandler{
starRepository: repo,
logger: logger,
}
return h
}
Loading

0 comments on commit 4316f82

Please sign in to comment.