티스토리 뷰

프로그래밍

go 백엔드 제작 후기

LunaStratos 2022. 2. 7. 10:38

회사에서 golang으로 백엔드를 제작할 일이 있어서 기능을 담당해서 제작했다.

 

여기서 golang에 대해서 받은 느낌은

 

 

 야는 좀 델리케이트 하네

 

였다.

안쓰는 변수에 대해서 에러를 내뿜고, uint int 에 대한 지정을 철저히 안하면 언더플로우가 되어버리는 일이 발생한다.

그리고 특정 int형만 받는 메소드들도 있어서 어느정도 메모리구조를 알고 건드려야 하는 언어였다.

신입을 키우는 언어(?) 라는 생각도 들었는데 확실히 난잡한 언어는 아니지만 많이 생각해야 하는 언어인 점은 맞는거같다.

 

 

 

우선 백엔드 제작시 proto 파일을 만들어주어야 했다.

이 파일은 자바 스프링으로 치면 컨트롤러를 만들어 주는 부분과 비슷했다.

 

더보기
syntax = "proto3";

option go_package = "target/go/message";

package message;

service MessageProcedure {

  // [메시지 리스트]
  rpc GetMessageList(GetMessageListRequest) returns (GetMessageListReply) {}
  // [메시지 삭제]
  rpc DoMessageDelete (DoMessageRequest) returns (DoMessageReply) {}
  // [메시지 읽음]
  rpc DoMessageRead (DoMessageRequest) returns (DoMessageReply) {}
  // [메시지 모두 읽음]
  rpc DoMessageReadMarked (DoMessageListRequest) returns (DoMessageReply) {}
  // [메시지 모두 삭제]
  rpc DoMessageDeleteMarked (DoMessageListRequest) returns (DoMessageReply) {}
  // [SALE 메시지 생성]
  rpc CreateSaleMessage (CreateSaleMessageRequest) returns (CreateMessageReply) {}
  // [공지 메시지 생성]
  rpc CreateNoticeMessage (CreateNoticeMessageRequest) returns (CreateMessageReply) {}

}

message Empty {}


message GetMessageListRequest {
  uint32 pageNum = 1;
  string search = 2;
  uint32 maxLenInPage = 3;
  string categoryType = 4;
  string mode = 5;

}

message GetMessageListReply {
  uint32 code = 1;
  string message = 2;
  uint32 newCount = 3;
  uint32 allCount = 4;
  repeated Msg msg = 5;
  uint32 startPage = 6;
  uint32 endPage = 7;
  uint32 lastPage = 8;
  uint32 nowPage = 9;
}

// 메시지 정보 Repeat
message Msg {
  uint32 id = 1;
  string message = 2;
  string messageType = 3;
  string messageSubType = 4;
  string messageContents = 5;
  string readYn = 6;
  string dateTime = 7; // ui상의 날짜 표시
}

message CreateSaleMessageRequest {
  uint32 userId = 1;
  string messageSubType = 2;
  string region = 3;
  string country = 4;
  string buyerName = 5;
  MessageSale messageContent = 6;
}

message MessageSale{
  string title = 1;
  string country = 2;
  string stateProvince = 3;
  uint32 tileCount = 4;
  uint32 level = 5;
  string from = 6;
  double price = 7;
}


message CreateNoticeMessageRequest {
  uint32 userId = 1;
  string messageSubType = 2;
  MessageNotice messageContent = 3;
}

message MessageNotice{
  string dateOfApplication = 1;
  uint32 applicationAmount = 2;
  string reviewTheResult = 3;
  double withdrawFee = 4;
  string title = 5;
  string description = 6;
}

message CreateMessageReply {
  uint32 code = 1;
  string message = 2;
}

// msgId 공통
message DoMessageRequest {
  uint32 msgId = 1;
}

message DoMessageReply {
  uint32 code = 1;
  string message = 2;
}

// msgId 공통
message DoMessageListRequest {
  repeated uint32 msgIds = 1;
}

Request와 Reply부분으로 제작한다.

순서를 다 지정해 주어야 한다. 그리고 Array같은 경우 한번 더 message를 선언해서 어떤 구조가 될건지 만들어 줘야 했다. 

 

더보기
func (p *MessageProcedure) GetMessageList(
   ctx context.Context,
   rq *pb.GetMessageListRequest) (*pb.GetMessageListReply, error) {

   rdb := common.GetRDB()

   // 리턴 변수 선언
   var messageEntityList []entity.MessageEntity

   println(uint32(common.GetSession(ctx).Id))
   search := rq.GetSearch()
   userId := uint32(common.GetSession(ctx).Id)
   pageNum := rq.GetPageNum()
   maxLenInPage := int(rq.GetMaxLenInPage())
   categoryType := rq.GetCategoryType()
   mode := rq.GetMode()

   query := rdb.Table("t_message").Where("user_id = ?", userId)

   // 검색어 있을때
   if search != "" {
      filter := fmt.Sprintf("%s%s%s", "%", search, "%")
      query = query.Where("message LIKE ?", filter)
   }

   // categoryType, ALL 아니면 동작
   if categoryType != common.MESSAGE_STATUS_ALL {
      query = query.Where("message_type = ?", categoryType)
   }

   // 헤더의 메시지는 신규만 보여준다.
   if mode == "header" {
      query = query.Where("read_yn", "N")
   }

   // 전체 카운트
   var messageCount int64
   query.Where("deleted_at is null").Count(&messageCount)

   getPageCal := common.BoardPaging(int32(messageCount), int32(pageNum), int32(maxLenInPage))

   // 페이지 있을때
   if pageNum != 0 {
      query = query.Limit(maxLenInPage).Offset(int(getPageCal.Start))
   }

   query.Order("id desc").Find(&messageEntityList)

   var newMessageCount int64
   query.Where("read_yn", "N").Count(&newMessageCount)

   messageList := mapper.MessageList(messageEntityList)

   // 리턴 값 set
   res := &pb.GetMessageListReply{
      Code:      common.API_STATUS_CODE_200,
      Message:   "success!",
      Msg:       messageList,
      AllCount:  uint32(messageCount),
      NewCount:  uint32(newMessageCount),
      StartPage: uint32(getPageCal.StartPage),
      EndPage:   uint32(getPageCal.EndPage),
      LastPage:  uint32(getPageCal.LastPage),
      NowPage:   uint32(getPageCal.NowPage),
   }
   return res, nil
}

 

이런식으로 return을 시켜준다. 

orm으로 gorm을 사용중엔데 어디서는 int형을 요구하고 어디서는 int64를 요구하고... 아주 난리가 났다.

 

그리고 개발하면서 느끼는게 uint int형 이걸 조심해야 했다.

uint형의 경우 마이너스 값이 없기 때문에 언더플로우가 되는데... 페이징 계산같은 경우 마이너스 값을 쓰기 때문에 uint를 쓰면 안되었다.

 

아래는 실제 페이징 기능유틸인데

 

func BoardPaging(total int32, nowPage int32, cntPage int32) Page {
	var obj = Page{0, 0, 0, 0, 0, 0, 0, 0}

	obj.NowPage = nowPage
	obj.CntPerPage = cntPage
	obj.Total = total

	//제일 마지막 페이지 계산
	obj.LastPage = int32(math.Ceil(float64(float64(total) / float64(cntPage))))

	//시작, 끝 페이지 계산
	obj.EndPage = int32(math.Ceil(float64(float64(nowPage)/float64(cntPage)))) * cntPage

	if obj.LastPage < obj.EndPage {
		obj.EndPage = obj.LastPage
	}

	obj.StartPage = obj.NowPage - cntPage + 1

	if obj.StartPage < 1 {
		obj.StartPage = 1
	}

	// start === offset 값
	obj.End = nowPage*cntPage - 1
	obj.Start = obj.End - cntPage + 1
	return obj
}

type Page struct {
	NowPage    int32 // 현재 페이지
	StartPage  int32 // 시작 페이지
	EndPage    int32 // 종료 페이지
	Total      int32 // 총 글 갯수(all count)
	CntPerPage int32 // 1페이지 당 게시글 수 (설정값)
	LastPage   int32 // 마지막 페이지
	Start      int32 // 시작 위치 (offset값)
	End        int32 // 종료위치 (사용안함)
}

 

그러고보니 golang 게시판 페이징 유틸이다. 이건.

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함