-
Spring Boot + Kotlin + MongoDB로 CRUD 해보기프로젝트/mongoDB 2024. 2. 12. 00:01
개요
Spring Boot + Kotlin + MongoDB를 활용하여 CRUD를 수행해보고자 합니다.
만약 MongoDB에 대해 잘 모르겠다면 "MongoDB란?"이라는 글을 참고하시고 오셔도 좋을 것 같습니다.
실제 코드는 github을 참고해 주세요.
환경
- Spring Boot 3.1
- JDK 17
- MongoDB with Docker
Gradle 의존성 추가
implementation("org.springframework.boot:spring-boot-starter-web") implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
web와 mongodb에 대한 의존성을 추가해 줍니다.
docker-compose.yml
version: '3' services: mongodb: image: mongo container_name: mongodb-container ports: - "27017:27017" environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: password
mongoDB에 대한 docker compose 파일을 작성하였습니다.
docker-compose up -d 명령어로 백그라운드에서 mongoDB를 실행할 수 있습니다.
application.yml
spring: data: mongodb: uri: mongodb://root:password@localhost:27017/mongodb-container?authSource=admin
docker compose 파일에 적힌 대로 uri를 명시해 주며 인증을 위해 authSource=admin을 쿼리파라미터로 붙여주었습니다.
Member Entity 만들기
@Document data class Member( @Id var id: String? = null, @Field("histories") val histories: MutableMap<String, String> ) { fun addHistories(additionalHistories: List<String>) { additionalHistories.forEach { histories[it] = it } } }
@Document, @Field 어노테이션을 활용하여 mongoDB에 영속될 수 있는 객체로 만들어냅니다.
MemberRepository
interface MemberRepository: MongoRepository<Member, String> { }
MongoRepository를 상속받습니다.
MemberService
@Service @Transactional(readOnly = true) class MemberService( private val memberRepository: MemberRepository, ){ fun findUserBy(id: String): Member { return memberRepository.findByIdOrNull(id) ?: throw IllegalArgumentException("${id}로 회원을 조회할 수 없습니다") } @Transactional fun signUp(memberHistories: List<String>): String{ val histories = memberHistories.map { it to it }.toMap().toMutableMap() val member = Member(histories = histories) return memberRepository.save(member).id!! } @Transactional fun addMemberHistories(id: String, additionalHistories: List<String>): Member{ val member = memberRepository.findByIdOrNull(id) ?: throw IllegalArgumentException("${id}로 회원을 조회할 수 없습니다") member.addHistories(additionalHistories) return memberRepository.save(member) } @Transactional fun withdraw(id: String){ memberRepository.deleteById(id) } }
memberRepository를 활용하여 CRUD를 수행하였습니다.
MemberController
@RestController @RequestMapping("/members") class MemberController( private val memberService: MemberService, ) { @GetMapping("/{id}") fun getMemberById(@PathVariable id: String): ResponseEntity<Member> { val member = memberService.findUserBy(id) return ResponseEntity.ok(member) } @PostMapping fun signUp(@RequestBody signUpRequest: SignUpRequest): ResponseEntity<String> { val id = memberService.signUp(signUpRequest.histories) return ResponseEntity.ok(id) } @PutMapping("/{id}/history") fun addMemberHistories( @PathVariable id: String, @RequestBody addHistoryRequest: AddHistoryRequest, ): ResponseEntity<Member> { val member = memberService.addMemberHistories(id = id, additionalHistories = addHistoryRequest.histories) return ResponseEntity.ok(member) } @DeleteMapping("/{id}") fun withdraw(@PathVariable id: String): ResponseEntity<Unit> { memberService.withdraw(id = id) return ResponseEntity.noContent().build() } }
REST API를 활용하여 CRUD를 구현하였습니다.
기타 DTO들
data class AddHistoryRequest( val histories: List<String>, ) data class SignUpRequest( val histories: List<String>, )
실제 API 호출을 통한 테스트 - curl
회원 가입
curl --location 'http://localhost:8080/members' \ --header 'Content-Type: application/json' \ --data '{ "histories": [ "wakeup", "eat", "study" ] }'
회원 조회
curl --location 'http://localhost:8080/members/6589c650554cf81aee139c3c'
회원 이력 수정
curl --location --request PUT 'http://localhost:8080/members/6589c650554cf81aee139c3c/history' \ --header 'Content-Type: application/json' \ --data '{ "histories": [ "drink","sleep" ] }'
회원 탈퇴
curl --location --request DELETE 'http://localhost:8080/members/1'
마무리
이 글을 작성하기 전에 JPA로 JSON Column CRUD 해보기라는 글을 작성해 보았습니다.
데이터베이스가 MySQL에서 MongoDB로 변환되었지만 Spring에서 지원하는 추상화 덕분에 이전에 작성했던 코드를 재사용하여 최소한의 수정으로 MongoDB CRUD 튜토리얼을 수행해 볼 수 있었습니다.
Spring의 추상화의 강력함을 다시 한번 느끼게 되는 것 같습니다.
참고자료
https://docs.spring.io/spring-data/mongodb/docs/current-SNAPSHOT/reference/html/#mongodb-connectors
https://medium.com/@sumanzadeakhil/spring-boot-mongodb-rest-api-crud-with-kotlin-227d296bbbef
https://www.mongodb.com/compatibility/spring-boot
https://www.baeldung.com/spring-data-mongodb-connection
'프로젝트 > mongoDB' 카테고리의 다른 글
MongoDB 인덱스 운영법 (0) 2024.02.22 MongoDB 인덱스란? (0) 2024.02.15 MongoDB 동시성 제어 (0) 2024.02.11 MongoDB Data Modeling (0) 2024.02.06 MongoDB Aggregation Operations (0) 2024.02.05