Go로 CRUD REST API 만들기 (3) - Bolt DB 연결

2023. 7. 10. 17:10· Go Lang/Study
목차
  1. Go Lang으로 간단하게 CRUD REST API 만들기 3편 - Bolt DB 연결
  2. 1.  개요
  3. 2. 코드

Go Lang으로 간단하게 CRUD REST API 만들기 3편 - Bolt DB 연결

1.  개요

이번 포스트로 DB Bolt에 CRUD 작업을 할 수 있습니다.

1편과 2편이 존재합니다, 아래 링크를 먼저 봐주세요

  • Go로 CRUD REST API 만들기 (1)
  • Go로 CRUD REST API 만들기 (2)

이전 포스트에서는 DB를 사용하지 않고 메모리에 담아두고 진행했었습니다

그렇기에 재시작시 데이터가 유지되지 않았습니다, 이번에는 DB를 추가하여 데이터가 유지되게 수정합시다.

 

Bolt

이번에 사용하는 Bolt는 단순하게 Key/Value 형태로 값을 저장하는 고를 위한 내장 데이터베이스 모듈입니다. 

Bolt는 GitHub에서 13.6K의 스타를 받았고 오랫동안 여러 사람들이 사용하면서 안정성이 인증된 모듈입니다.

MySQL과 같은 RDBMS도 연결할 수 있지만 간단하게 하는 것이 목적이기에 Bolt를 선택했습니다.

 

2. 코드

의존성 추가 

아래 명령어로 Bolt를 설치해줍시다.

go get github.com/boltdb/bolt

 

Utils 생성

먼저 반복되는 작업은 처리할 함수들을 모아둔 utils.go를 만들어줍시다.

utils/utils.go

package utils

import (
	"encoding/binary"
	"log"
)

// HandleErr : 에러 발생시 Panic 으로 Log 출력
func HandleErr(err error) {
	if err != nil {
		log.Panic(err)
	}
}

// IntToBytes : int 타입을 []byte 타입으로 변경 후 반환
func IntToBytes(integer int) []byte {
	bytes := make([]byte, 8)
	binary.BigEndian.PutUint64(bytes, uint64(integer))
	return bytes
}

// BytesToInt : []byte 타입을 int 타입으로 변경 후 반환
func BytesToInt(bytes []byte) int {
	return int(binary.BigEndian.Uint64(bytes))
}

 

Bolt DB 연결

프로젝트 폴더에서 db 폴더를 만드신 후 안에 db.go 파일도 생성해 줍시다.

db/db.go

package db

import (
	"github.com/boltdb/bolt"
	"rest-api.com/utils"
)

// dbName : DB 명으로 해당 이름으로 파일이 생성됩니다
// championBucket : Bucket 은 RDBMS 의 테이블과 같은 역할을 합니다.
const (
	dbName          = "champion.db"
	championsBucket = "champion"
)

var db *bolt.DB

// DB : db 커넥션
func DB() *bolt.DB {
	if db == nil {
		// bolt.Open : dbName 으로 데이터베이스 열기, 뒤에 0600 은 파일 권한
		dbPointer, err := bolt.Open(dbName, 0600, nil)
		db = dbPointer
		utils.HandleErr(err)

		// Update : 읽기-쓰기 트랜잭션 실행
		err = db.Update(func(tx *bolt.Tx) error {
			// CreateBucketIfNotExists : 해당 버켓명이 없으면 버켓 생성
			_, err := tx.CreateBucketIfNotExists([]byte(championsBucket))
			utils.HandleErr(err)
			return err
		})
		utils.HandleErr(err)
	}
	return db
}


// Close : db connection 종료
func Close() {
	DB().Close()
}

이제 DB()를 실행하면 프로젝트에 champions.db가 생성됩니다.

 

Bolt CRUD 생성

이제 db/db.go에 마저 CRUD 로직을 추가합니다.

// SaveChampion : 챔피언을 DB에 추가
func SaveChampion(name string) {
	utils.HandleErr(DB().Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte(championsBucket))

		// championBucket 의 다음 값 가져오기
		id, _ := bucket.NextSequence()
		// 저장
		err := bucket.Put(utils.IntToBytes(int(id)), []byte(name))
		return err
	}))
}

// ReadChampions : DB에 전체 챔피언 가져오기
func ReadChampions() map[int]string {
	m := make(map[int]string)
	utils.HandleErr(DB().View(func(tx *bolt.Tx) error {
		// Assume bucket exists and has keys
		bucket := tx.Bucket([]byte(championsBucket))
		cursor := bucket.Cursor()
		// 커서로 bucket 내부를 돌며 map 에 저장
		for key, value := cursor.First(); key != nil; key, value = cursor.Next() {
			m[utils.BytesToInt(key)] = string(value)
		}
		return nil
	}))
	return m
}

// UpdateChampion : DB에 특정 아이디 이름 업데이트
func UpdateChampion(id int, name string) {
	utils.HandleErr(DB().Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte(championsBucket))
		// id가 존재하는 값이면 값 덮어씌우기 
		err := bucket.Put(utils.IntToBytes(id), []byte(name))
		return err
	}))
}

// DeleteChampion : DB에 특정 아이디로 데이터 삭제
func DeleteChampion(id int) {
	utils.HandleErr(DB().Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte(championsBucket))
		// id로 데이터 삭제
		err := bucket.Delete(utils.IntToBytes(id))
		return err
	}))
}

 

main.go 수정

이제 champion 구조체와 슬라이스, newID 함수는 이제 사용하지 않으니 지워줍시다.

// 아래 내용들 지우기
type champion struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

var champions []*champion

func newID() int {
	if len(champions) > 0 {
		return champions[len(champions)-1].ID + 1
	} else {
		return 1
	}
}

func main()에는 가장 defer db.close()를 위에 추가합니다.

func main() {
	defer db.Close()
	...
}

defer는 프로세스 종료 시 실행됩니니다, 이걸로 프로세스 종료시 자동으로 bolt connection을 종료합니다.

 

db.go 연결

db/db.go에 만들어둔 함수들을 main.go의 getChampions, postChampions, patchChampions, deleteChampions를 각각 연결합니다.

func getChampions(rw http.ResponseWriter, r *http.Request) {
	// 데이터 가져오기
	json.NewEncoder(rw).Encode(db.ReadChampions())
}

func postChampions(rw http.ResponseWriter, r *http.Request) {
	// request 값을 받을 구조체 변수 선언
	var requestBody requestBody
	utils.HandleErr(json.NewDecoder(r.Body).Decode(&requestBody))

	// 데이터 생성
	db.SaveChampion(requestBody.Name)

	// 생성 완료 후 Http code 201 created 로 response 해더 설정
	rw.WriteHeader(http.StatusCreated)
	return
}

func patchChampions(rw http.ResponseWriter, r *http.Request) {
	// request 값을 받을 구조체 변수 선언 및 할당
	var requestBody requestBody
	json.NewDecoder(r.Body).Decode(&requestBody)

	// Router 에서 id로 정의 한 값은 mux 를 통해 받을 수 있음
	vars := mux.Vars(r)
	id, _ := strconv.Atoi(vars["id"])

	// 데이터 업데이트
	db.UpdateChampion(id, requestBody.Name)

	rw.WriteHeader(http.StatusOK)
	return
}

func deleteChampions(rw http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id, _ := strconv.Atoi(vars["id"])

	// 데이터 삭제
	db.DeleteChampion(id)

	rw.WriteHeader(http.StatusOK)
	return
}

 

결과

bolt db 연결

 

의문점 문의 및 오타 피드백은 언제나 환영입니다.

반응형

'Go Lang > Study' 카테고리의 다른 글

[GoLang] 자료형을 초과한 큰 수를 계산해보자  (0) 2023.09.01
[GoLang] 정규식으로 URL 분석기 만들기  (0) 2023.08.30
GoLang으로 느낌 있게 채팅 방 만들어보자  (0) 2023.08.27
Go로 CRUD REST API 만들기 (2)  (0) 2023.07.06
Go로 CRUD REST API 만들기 (1)  (0) 2023.07.05
  1. Go Lang으로 간단하게 CRUD REST API 만들기 3편 - Bolt DB 연결
  2. 1.  개요
  3. 2. 코드
'Go Lang/Study' 카테고리의 다른 글
  • [GoLang] 정규식으로 URL 분석기 만들기
  • GoLang으로 느낌 있게 채팅 방 만들어보자
  • Go로 CRUD REST API 만들기 (2)
  • Go로 CRUD REST API 만들기 (1)
DSeung
DSeung
DSeung
Dev log
DSeung
  • 분류 전체보기 (192)
    • PHP (62)
      • Laravel (31)
      • Error (5)
      • Setting (11)
      • Modern PHP (15)
    • Go Lang (51)
      • Study (30)
      • Algorithm (17)
      • Setting (1)
      • Error (3)
    • Java (11)
      • Spring (3)
      • JSP (0)
      • Error (2)
      • Setting (2)
      • 단축키 (2)
    • JavaScript (6)
      • Modern JavaScript (4)
      • Node (1)
    • Android Kotlin (5)
      • Study (4)
      • Error (1)
    • 컴퓨팅 기술 (12)
      • 데이터베이스시스템 (4)
      • Docker (2)
      • 크롤링 & 스크래핑 (1)
      • API (1)
      • 클라우드 (1)
      • 네트워크 (1)
    • MySQL (7)
    • AWS (1)
    • Git (5)
      • GItLab (1)
      • GitHub (4)
    • 도메인 (2)
      • 안과 (2)
    • 자격증 (7)
      • SQLD (1)
      • 정보처리기사 (6)
    • Mac os (1)
    • 나머지 (13)
      • tistory (1)
      • 기타 (9)
      • 일기 (3)
    • 독서 (9)

인기 글

최근 글

블로그 메뉴

  • 홈
  • 태그
전체
오늘
어제
hELLO · Designed By 정상우.v4.2.0
DSeung
Go로 CRUD REST API 만들기 (3) - Bolt DB 연결
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.