Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

common http response format #44

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions application/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,31 @@ const (
// AuthCodeKey is a auth code url query parameter
AuthCodeKey = "authcode"
)

const (
EntityNotFoundErr = 400001
EmptyParameterErr = 400002
InvalidRequestBodyErr = 400003
CannotCreateErr = 400004
TaskRoomPeriodFINCreateErr = 400005
TaskMemberOnDutyCreateErr = 400006
TaskMemberBefore1HRCreateErr = 400007
TaskMemberBefore4HRCreateErr = 400008
TaskMemberPostedDiaryCreateErr = 400009

OnlyMemberErr = 401001
OnlyMasterErr = 401002
OnlyMemberOrMasterErr = 401003

StatusInternalServerError = 500 // RFC 7231, 6.6.1
StatusNotImplemented = 501 // RFC 7231, 6.6.2
StatusBadGateway = 502 // RFC 7231, 6.6.3
StatusServiceUnavailable = 503 // RFC 7231, 6.6.4
StatusGatewayTimeout = 504 // RFC 7231, 6.6.5
StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6
StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1
StatusInsufficientStorage = 507 // RFC 4918, 11.5
StatusLoopDetected = 508 // RFC 5842, 7.2
StatusNotExtended = 510 // RFC 2774, 7
StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
)
1 change: 1 addition & 0 deletions application/controller/alarmController.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ func (ac *alarmController) List() gin.HandlerFunc {
})
}
c.JSON(http.StatusOK, AlarmListResponse{Alarms: rep})

}
}
80 changes: 39 additions & 41 deletions application/controller/roomController.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ type listResponseRoom struct {
// @Tags rooms
// @Accept json
// @Produce json
// @Success 200 {object} listResponseRoom
// @Failure 400
// @Success 200 {object} application.JSONSuccessResponse{data=listResponseRoom,code=int,message=string}
// @Failure 400001 {object} application.JSONBadResponse{code=int,message=string} "EntityNotFoundErr"
// @Failure 500 {object} application.JSONServerErrResponse{code=int,message=string}
// @Router /rooms [get]
// @Security ApiKeyAuth
func (rc *roomController) GetAll() gin.HandlerFunc {
Expand All @@ -71,7 +72,7 @@ func (rc *roomController) GetAll() gin.HandlerFunc {
rooms, err := rc.roomService.GetAllJoinedRooms(currentMember.ID)
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.EntityNotFoundErr, err.Error())
return
}
roomsResponse := []responseRoom{}
Expand All @@ -93,7 +94,7 @@ func (rc *roomController) GetAll() gin.HandlerFunc {
UpdatedAt: room.UpdatedAt,
})
}
c.JSON(http.StatusOK, listResponseRoom{Rooms: roomsResponse})
application.Ok(c, listResponseRoom{Rooms: roomsResponse})
}
}

Expand All @@ -118,27 +119,28 @@ type detailResponseRoom struct {
// @Accept json
// @Produce json
// @Param id path int true "교환일기방 ID" Format(uint)
// @Success 200 {object} detailResponseRoom
// @Failure 400
// @Success 200 {object} application.JSONSuccessResponse{data=detailResponseRoom,code=int,message=string}
// @Failure 400001 {object} application.JSONBadResponse{code=int,message=string} "EntityNotFoundErr"
// @Failure 400002 {object} application.JSONBadResponse{code=int,message=string} "EmptyParameterErr"
// @Failure 401003 {object} application.JSONBadResponse{code=int,message=string} "OnlyMemberOrMasterErr"
// @Failure 500 {object} application.JSONServerErrResponse{code=int,message=string}
// @Router /rooms/{id} [get]
// @Security ApiKeyAuth
func (rc *roomController) Get() gin.HandlerFunc {
return func(c *gin.Context) {
currentMember := c.MustGet(application.CurrentMemberKey).(application.CurrentMemberDTO)
roomID, err := application.ParseUint(c.Param("room_id"))
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.EmptyParameterErr, err.Error())
return
}
room, err := rc.roomService.Get(roomID, entity.JoinedOrder)
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, err.Error())
application.FailResponse(c, application.EntityNotFoundErr, err.Error())
return
}
if !room.IsAlreadyJoined(currentMember.ID) {
c.JSON(http.StatusUnauthorized, "Only member or master can access")
application.FailResponse(c, application.OnlyMemberOrMasterErr, "Only member or master can access")
return
}

Expand All @@ -161,7 +163,7 @@ func (rc *roomController) Get() gin.HandlerFunc {
UpdatedAt: room.UpdatedAt,
IsMaster: room.IsMaster(currentMember.ID),
}
c.JSON(http.StatusOK, res)
application.Ok(c, res)
}
}

Expand All @@ -178,26 +180,28 @@ type roomOrderResponse struct {
// @Produce json
// @Param id path int true "교환일기방 ID" Format(uint)
// @Success 200 {object} roomOrderResponse
// @Failure 400
// @Success 200 {object} application.JSONSuccessResponse{data=detailResponseRoom,code=int,message=string}
// @Failure 400001 {object} application.JSONBadResponse{code=int,message=string} "EntityNotFoundErr"
// @Failure 400002 {object} application.JSONBadResponse{code=int,message=string} "EmptyParameterErr"
// @Failure 401003 {object} application.JSONBadResponse{code=int,message=string} "OnlyMemberOrMasterErr"
// @Failure 500 {object} application.JSONServerErrResponse{code=int,message=string}
// @Router /rooms/{id}/orders [get]
// @Security ApiKeyAuth
func (rc *roomController) GetOrders() gin.HandlerFunc {
return func(c *gin.Context) {
currentMember := c.MustGet(application.CurrentMemberKey).(application.CurrentMemberDTO)
roomID, err := application.ParseUint(c.Param("room_id"))
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.EmptyParameterErr, err.Error())
return
}
room, err := rc.roomService.Get(roomID, entity.DiaryOrder)
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, err.Error())
application.FailResponse(c, application.EntityNotFoundErr, err.Error())
return
}
if !room.IsAlreadyJoined(currentMember.ID) {
c.JSON(http.StatusUnauthorized, "Only member or master can access room orders")
application.FailResponse(c, application.OnlyMemberOrMasterErr, "Only member or master can access room orders")
return
}

Expand All @@ -214,7 +218,7 @@ func (rc *roomController) GetOrders() gin.HandlerFunc {
Members: &members,
TurnAccountID: room.TurnAccountID,
}
c.JSON(http.StatusOK, res)
application.Ok(c, res)
}
}

Expand Down Expand Up @@ -245,14 +249,13 @@ func (rc *roomController) Post() gin.HandlerFunc {
currentMember := c.MustGet(application.CurrentMemberKey).(application.CurrentMemberDTO)
var req postRequestRoom
if err := c.BindJSON(&req); err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.InvalidRequestBodyErr, err.Error())
return
}
room, err := rc.roomService.Create(currentMember.ID, req.Name, req.Code, req.Hint, req.Theme, req.Period)
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, err.Error())
application.FailResponse(c, application.CannotCreateErr, err.Error())
return
}

Expand All @@ -266,12 +269,12 @@ func (rc *roomController) Post() gin.HandlerFunc {
room.DueAt,
); err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, err.Error())
application.FailResponse(c, application.TaskRoomPeriodFINCreateErr, err.Error())
return
}

res := postResponseRoom{RoomID: room.ID}
c.JSON(http.StatusOK, res)
application.Ok(c, res)
}
}

Expand Down Expand Up @@ -330,25 +333,23 @@ func (rc *roomController) Patch() gin.HandlerFunc {
currentMember := c.MustGet(application.CurrentMemberKey).(application.CurrentMemberDTO)
var req patchRequestRoom
if err := c.BindJSON(&req); err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.InvalidRequestBodyErr, err.Error())
return
}

roomID, err := application.ParseUint(c.Param("room_id"))
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.EmptyParameterErr, err.Error())
return
}

room, err := rc.roomService.Get(roomID, entity.Ignore)
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, err.Error())
application.FailResponse(c, application.EntityNotFoundErr, err.Error())
return
}

// TODO: 여기부터 처리할것
if !room.IsMaster(currentMember.ID) {
c.JSON(http.StatusUnauthorized, "Only master can patch room")
return
Expand All @@ -362,7 +363,7 @@ func (rc *roomController) Patch() gin.HandlerFunc {
}

res := patchResponseRoom{RoomID: room.ID}
c.JSON(http.StatusOK, res)
application.Ok(c, res)
}
}

Expand All @@ -372,7 +373,7 @@ func (rc *roomController) Patch() gin.HandlerFunc {
// @Accept json
// @Produce json
// @Param id path int true "교환일기방 ID"
// @Success 204
// @Success 204 "NO CONTENT"
// @Failure 400
// @Router /rooms/{id} [delete]
// @Security ApiKeyAuth
Expand All @@ -381,8 +382,7 @@ func (rc *roomController) Delete() gin.HandlerFunc {
currentMember := c.MustGet(application.CurrentMemberKey).(application.CurrentMemberDTO)
roomID, err := application.ParseUint(c.Param("room_id"))
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.EmptyParameterErr, err.Error())
return
}

Expand All @@ -404,7 +404,7 @@ func (rc *roomController) Delete() gin.HandlerFunc {
c.JSON(http.StatusBadRequest, err.Error())
return
}
c.Status(http.StatusNoContent)
application.NoConent(c)
}
}

Expand Down Expand Up @@ -435,8 +435,7 @@ func (rc *roomController) Join() gin.HandlerFunc {
}
roomID, err := application.ParseUint(c.Param("room_id"))
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.EmptyParameterErr, err.Error())
return
}

Expand All @@ -451,7 +450,7 @@ func (rc *roomController) Join() gin.HandlerFunc {
c.JSON(http.StatusUnauthorized, err.Error())
return
}
c.Status(http.StatusCreated)
application.Created(c, nil)
}
}

Expand All @@ -472,15 +471,14 @@ func (rc *roomController) Leave() gin.HandlerFunc {
currentMember := c.MustGet(application.CurrentMemberKey).(application.CurrentMemberDTO)
roomID, err := application.ParseUint(c.Param("room_id"))
if err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
application.FailResponse(c, application.EmptyParameterErr, err.Error())
return
}
if err := rc.roomService.LeaveRoom(roomID, currentMember.ID); err != nil {
logger.Error(err.Error())
c.JSON(http.StatusBadRequest, err.Error())
return
}
c.Status(http.StatusNoContent)
application.NoConent(c)
}
}
64 changes: 64 additions & 0 deletions application/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package application

import (
"net/http"

"github.com/gin-gonic/gin"
)

// JSONSuccessResponse ...
type JSONSuccessResponse struct {
Code uint `json:"code" example:"200"`
Message string `json:"message" example:"Ok"`
Data interface{} `json:"data"`
}

// JSONBadResponse ...
type JSONBadResponse struct {
Code int `json:"code" example:"40001"`
Message string `json:"message" example:"4xx errors"`
}

// JSONServerErrResponse ...
type JSONServerErrResponse struct {
Code int `json:"code" example:"500"`
Message string `json:"message" example:"Error database"`
}

func Ok(c *gin.Context, data interface{}) {
c.JSON(http.StatusOK, JSONSuccessResponse{
Code: http.StatusOK,
Message: "Ok",
Data: data,
})
}

func Created(c *gin.Context, data interface{}) {
c.JSON(http.StatusOK, JSONSuccessResponse{
Code: http.StatusCreated,
Message: "Created",
Data: data,
})
}

func NoConent(c *gin.Context) {
c.JSON(http.StatusOK, JSONSuccessResponse{
Code: http.StatusNoContent,
Message: "No Conent",
Data: c.Request.TLS.NegotiatedProtocolIsMutual,
})
}

func FailResponse(c *gin.Context, code int, message string) {
if code == http.StatusInternalServerError {
c.JSON(code, JSONServerErrResponse{
Code: code,
Message: message,
})
return
}
c.JSON(code, JSONBadResponse{
Code: code,
Message: message,
})
}
Loading