Skip to content

Commit

Permalink
update controller to provide more specific HTTP response codes
Browse files Browse the repository at this point in the history
  • Loading branch information
snykk committed Feb 4, 2023
1 parent a37f9ba commit b71d526
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 135 deletions.
8 changes: 4 additions & 4 deletions http/controllers/base_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ type BaseResponse struct {
Data interface{} `json:"data,omitempty"`
}

func NewSuccessResponse(c *gin.Context, message string, data interface{}) {
c.JSON(http.StatusOK, BaseResponse{
func NewSuccessResponse(c *gin.Context, statusCode int, message string, data interface{}) {
c.JSON(statusCode, BaseResponse{
Status: true,
Message: message,
Data: data,
})
}

func NewErrorResponse(c *gin.Context, code int, err string) {
c.JSON(code, BaseResponse{
func NewErrorResponse(c *gin.Context, statusCode int, err string) {
c.JSON(statusCode, BaseResponse{
Status: false,
Message: err,
})
Expand Down
37 changes: 19 additions & 18 deletions http/controllers/books/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,70 +34,70 @@ func (c *BookController) Store(ctx *gin.Context) {
}

ctxx := ctx.Request.Context()
b, err := c.bookUsecase.Store(ctxx, bookRequest.ToDomain())
b, statusCode, err := c.bookUsecase.Store(ctxx, bookRequest.ToDomain())
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

go c.ristrettoCache.Del("books")

controllers.NewSuccessResponse(ctx, "book inserted successfully", map[string]interface{}{
controllers.NewSuccessResponse(ctx, statusCode, "book inserted successfully", map[string]interface{}{
"book": responses.FromDomain(b),
})
}

func (c *BookController) GetAll(ctx *gin.Context) {
if val := c.ristrettoCache.Get("books"); val != nil {
controllers.NewSuccessResponse(ctx, "book data fetched successfully", map[string]interface{}{
controllers.NewSuccessResponse(ctx, http.StatusOK, "book data fetched successfully", map[string]interface{}{
"books": val,
})
return
}

ctxx := ctx.Request.Context()
listOfBooks, err := c.bookUsecase.GetAll(ctxx)
listOfBooks, statusCode, err := c.bookUsecase.GetAll(ctxx)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

bookResponses := responses.ToResponseList(listOfBooks)

if bookResponses == nil {
controllers.NewSuccessResponse(ctx, "book data is empty", []int{})
controllers.NewSuccessResponse(ctx, statusCode, "book data is empty", []int{})
return
}

go c.ristrettoCache.Set("books", bookResponses)

controllers.NewSuccessResponse(ctx, "book data fetched successfully", map[string]interface{}{
controllers.NewSuccessResponse(ctx, statusCode, "book data fetched successfully", map[string]interface{}{
"books": bookResponses,
})
}

func (c *BookController) GetById(ctx *gin.Context) {
id, _ := strconv.Atoi(ctx.Param("id"))
if val := c.ristrettoCache.Get(fmt.Sprintf("book/%d", id)); val != nil {
controllers.NewSuccessResponse(ctx, fmt.Sprintf("book data with id %d fetched successfully", id), map[string]interface{}{
controllers.NewSuccessResponse(ctx, http.StatusOK, fmt.Sprintf("book data with id %d fetched successfully", id), map[string]interface{}{
"book": val,
})
return
}

ctxx := ctx.Request.Context()

bookDomain, err := c.bookUsecase.GetById(ctxx, id)
bookDomain, statusCode, err := c.bookUsecase.GetById(ctxx, id)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

bookResponse := responses.FromDomain(bookDomain)

go c.ristrettoCache.Set(fmt.Sprintf("book/%d", id), bookResponse)

controllers.NewSuccessResponse(ctx, fmt.Sprintf("book data with id %d fetched successfully", id), map[string]interface{}{
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("book data with id %d fetched successfully", id), map[string]interface{}{
"book": bookResponse,
})
}
Expand All @@ -113,15 +113,15 @@ func (c *BookController) Update(ctx *gin.Context) {

ctxx := ctx.Request.Context()
bookDomain := bookUpdateRequest.ToDomain()
newBook, err := c.bookUsecase.Update(ctxx, bookDomain, id)
newBook, statusCode, err := c.bookUsecase.Update(ctxx, bookDomain, id)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

go c.ristrettoCache.Del("books", fmt.Sprintf("book/%d", id))

controllers.NewSuccessResponse(ctx, fmt.Sprintf("book data with id %d updated successfully", id), map[string]interface{}{
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("book data with id %d updated successfully", id), map[string]interface{}{
"book": responses.FromDomain(newBook),
})
}
Expand All @@ -130,12 +130,13 @@ func (c *BookController) Delete(ctx *gin.Context) {
id, _ := strconv.Atoi(ctx.Param("id"))

ctxx := ctx.Request.Context()
if err := c.bookUsecase.Delete(ctxx, id); err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
statusCode, err := c.bookUsecase.Delete(ctxx, id)
if err != nil {
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

go c.ristrettoCache.Del("books", fmt.Sprintf("book/%d", id))

controllers.NewSuccessResponse(ctx, fmt.Sprintf("book data with id %d deleted successfully", id), nil)
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("book data with id %d deleted successfully", id), nil)
}
6 changes: 3 additions & 3 deletions http/controllers/books/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func TestStore(t *testing.T) {

// Assertions
// Assert status code
assert.Equal(t, http.StatusOK, w.Result().StatusCode)
assert.Equal(t, http.StatusCreated, w.Result().StatusCode)
assert.Contains(t, w.Result().Header.Get("Content-Type"), "application/json")
assert.Contains(t, body, "book inserted successfully")
})
Expand Down Expand Up @@ -283,7 +283,7 @@ func TestGetById(t *testing.T) {

// Assertions
// Assert status code
assert.Equal(t, http.StatusInternalServerError, w.Result().StatusCode)
assert.Equal(t, http.StatusNotFound, w.Result().StatusCode)
assert.Contains(t, w.Result().Header.Get("Content-Type"), "application/json")
})
}
Expand Down Expand Up @@ -414,7 +414,7 @@ func TestDelete(t *testing.T) {

// Assertions
// Assert status code
assert.Equal(t, http.StatusInternalServerError, w.Result().StatusCode)
assert.Equal(t, http.StatusNotFound, w.Result().StatusCode)
assert.Contains(t, w.Result().Header.Get("Content-Type"), "application/json")
})
}
56 changes: 28 additions & 28 deletions http/controllers/reviews/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,76 +44,76 @@ func (c *ReviewController) Store(ctx *gin.Context) {
ctxx := ctx.Request.Context()
reviewDom := reviewRequest.ToDomain()

userReview, _ := c.reviewUsecase.GetUserReview(ctxx, reviewDom.BookId, userClaims.UserID)
userReview, _, _ := c.reviewUsecase.GetUserReview(ctxx, reviewDom.BookId, userClaims.UserID)
if userReview.ID != 0 {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, "user already make a review")
controllers.NewErrorResponse(ctx, http.StatusBadRequest, "user already make a review")
return
}
review, err := c.reviewUsecase.Store(ctxx, reviewDom, userClaims.UserID)
review, statusCode, err := c.reviewUsecase.Store(ctxx, reviewDom, userClaims.UserID)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

go c.ristrettoCache.Del("reviews", "users", fmt.Sprintf("user/%d", userClaims.UserID), "books", fmt.Sprintf("book/%d", reviewRequest.BookId))

controllers.NewSuccessResponse(ctx, "review created successfully", gin.H{
controllers.NewSuccessResponse(ctx, statusCode, "review created successfully", gin.H{
"reviews": responses.FromDomain(review),
})
}

func (c *ReviewController) GetAll(ctx *gin.Context) {
if val := c.ristrettoCache.Get("reviews"); val != nil {
controllers.NewSuccessResponse(ctx, "review data fetched successfully", map[string]interface{}{
controllers.NewSuccessResponse(ctx, http.StatusOK, "review data fetched successfully", map[string]interface{}{
"reviews": val,
})
return
}

ctxx := ctx.Request.Context()

listOfReviews, err := c.reviewUsecase.GetAll(ctxx)
listOfReviews, statusCode, err := c.reviewUsecase.GetAll(ctxx)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

reviews := responses.ToResponseList(listOfReviews)

if reviews == nil {
controllers.NewSuccessResponse(ctx, "review data is empty", []int{})
controllers.NewSuccessResponse(ctx, statusCode, "review data is empty", []int{})
return
}

go c.ristrettoCache.Set("reviews", reviews)

controllers.NewSuccessResponse(ctx, "review data fetched successfully", map[string]interface{}{
controllers.NewSuccessResponse(ctx, statusCode, "review data fetched successfully", map[string]interface{}{
"reviews": reviews,
})
}

func (c *ReviewController) GetById(ctx *gin.Context) {
id, _ := strconv.Atoi(ctx.Param("id"))
if val := c.ristrettoCache.Get(fmt.Sprintf("review/%d", id)); val != nil {
controllers.NewSuccessResponse(ctx, fmt.Sprintf("review data with id %d fetched successfully", id), map[string]interface{}{
controllers.NewSuccessResponse(ctx, http.StatusOK, fmt.Sprintf("review data with id %d fetched successfully", id), map[string]interface{}{
"review": val,
})
return
}

ctxx := ctx.Request.Context()

bookDomain, err := c.reviewUsecase.GetById(ctxx, id)
bookDomain, statusCode, err := c.reviewUsecase.GetById(ctxx, id)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

bookResponse := responses.FromDomain(bookDomain)

go c.ristrettoCache.Set(fmt.Sprintf("review/%d", id), bookResponse)

controllers.NewSuccessResponse(ctx, fmt.Sprintf("review data with id %d fetched successfully", id), map[string]interface{}{
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("review data with id %d fetched successfully", id), map[string]interface{}{
"review": bookResponse,
})
}
Expand All @@ -122,20 +122,20 @@ func (c *ReviewController) GetByBookId(ctx *gin.Context) {
bookId, _ := strconv.Atoi(ctx.Param("id"))
ctxx := ctx.Request.Context()

reviewsDomain, err := c.reviewUsecase.GetByBookId(ctxx, bookId)
reviewsDomain, statusCode, err := c.reviewUsecase.GetByBookId(ctxx, bookId)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusNotFound, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

reviews := responses.ToResponseList(reviewsDomain)

if reviews == nil {
controllers.NewSuccessResponse(ctx, fmt.Sprintf("review data with book id %d is empty", bookId), []int{})
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("review data with book id %d is empty", bookId), []int{})
return
}

controllers.NewSuccessResponse(ctx, fmt.Sprintf("review data with book id %d fetched successfully", bookId), map[string]interface{}{
controllers.NewSuccessResponse(ctx, http.StatusOK, fmt.Sprintf("review data with book id %d fetched successfully", bookId), map[string]interface{}{
"review": reviews,
})
}
Expand All @@ -144,20 +144,20 @@ func (c *ReviewController) GetByUserid(ctx *gin.Context) {
userId, _ := strconv.Atoi(ctx.Param("id"))
ctxx := ctx.Request.Context()

reviewsDomain, err := c.reviewUsecase.GetByUserId(ctxx, userId)
reviewsDomain, statusCode, err := c.reviewUsecase.GetByUserId(ctxx, userId)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusNotFound, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

reviews := responses.ToResponseList(reviewsDomain)

if reviews == nil {
controllers.NewSuccessResponse(ctx, fmt.Sprintf("review data with user id %d is empty", userId), []int{})
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("review data with user id %d is empty", userId), []int{})
return
}

controllers.NewSuccessResponse(ctx, fmt.Sprintf("review data with user id %d fetched successfully", userId), map[string]interface{}{
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("review data with user id %d fetched successfully", userId), map[string]interface{}{
"review": reviews,
})
}
Expand All @@ -178,15 +178,15 @@ func (c *ReviewController) Update(ctx *gin.Context) {

ctxx := ctx.Request.Context()
reviewDom := reviewRequest.ToDomain()
review, err := c.reviewUsecase.Update(ctxx, reviewDom, userClaims.UserID, reviewId)
review, statusCode, err := c.reviewUsecase.Update(ctxx, reviewDom, userClaims.UserID, reviewId)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

go c.ristrettoCache.Del("reviews", fmt.Sprintf("review/%d", review.ID), "users", fmt.Sprintf("user/%d", userClaims.UserID), "books", fmt.Sprintf("book/%d", reviewRequest.BookId))

controllers.NewSuccessResponse(ctx, "review updated successfully", gin.H{
controllers.NewSuccessResponse(ctx, statusCode, "review updated successfully", gin.H{
"reviews": responses.FromDomain(review),
})
}
Expand All @@ -196,13 +196,13 @@ func (c *ReviewController) Delete(ctx *gin.Context) {
reviewid, _ := strconv.Atoi(ctx.Param("id"))

ctxx := ctx.Request.Context()
bookId, err := c.reviewUsecase.Delete(ctxx, userClaims.UserID, reviewid)
bookId, statusCode, err := c.reviewUsecase.Delete(ctxx, userClaims.UserID, reviewid)
if err != nil {
controllers.NewErrorResponse(ctx, http.StatusInternalServerError, err.Error())
controllers.NewErrorResponse(ctx, statusCode, err.Error())
return
}

go c.ristrettoCache.Del("reviews", fmt.Sprintf("review/%d", reviewid), "books", fmt.Sprintf("book/%d", userClaims.UserID), "books", fmt.Sprintf("book/%d", bookId))

controllers.NewSuccessResponse(ctx, fmt.Sprintf("review data with id %d deleted successfully", reviewid), nil)
controllers.NewSuccessResponse(ctx, statusCode, fmt.Sprintf("review data with id %d deleted successfully", reviewid), nil)
}
6 changes: 3 additions & 3 deletions http/controllers/reviews/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func TestStore(t *testing.T) {

// Assertions
// Assert status code
assert.Equal(t, http.StatusOK, w.Result().StatusCode)
assert.Equal(t, http.StatusCreated, w.Result().StatusCode)
assert.Contains(t, w.Result().Header.Get("Content-Type"), "application/json")
assert.Contains(t, body, "review created successfully")
})
Expand Down Expand Up @@ -319,7 +319,7 @@ func TestGetById(t *testing.T) {

// Assertions
// Assert status code
assert.Equal(t, http.StatusInternalServerError, w.Result().StatusCode)
assert.Equal(t, http.StatusNotFound, w.Result().StatusCode)
assert.Contains(t, w.Result().Header.Get("Content-Type"), "application/json")
})
}
Expand Down Expand Up @@ -472,7 +472,7 @@ func TestDelete(t *testing.T) {

// Assertions
// Assert status code
assert.Equal(t, http.StatusInternalServerError, w.Result().StatusCode)
assert.Equal(t, http.StatusNotFound, w.Result().StatusCode)
assert.Contains(t, w.Result().Header.Get("Content-Type"), "application/json")
})
}
Loading

0 comments on commit b71d526

Please sign in to comment.