이번 프로젝트에서는 Java + SpringBoot + Mongo DB 로 구현할 예정입니다.
각각 사용할 버전은 다음과 같습니다.
- Java 8 (오라클jdk가 상용목적으로는 유료화되어 추후 코틀린으로 변경하는 프로젝트를 진행해봐야겠네요)
- Springboot 2.4.0 (20년 11월 현재 최신버전)
- Mongo DB 4.4.2 Community Server (20년 11월 현재 최신버전)
몽고디비 설치 관련해서는 몽고DB 최신버전 설치하기 포스팅을 참고하시면 됩니다.
설치 후 사용자 계정 생성 및 데이터 베이스 생성 관련해서는 [몽고DB] 기본명령어 포스팅을 참고해주세요.
이제 그래들 자바 프로젝트를 하나 생성하여 Blog > 다이어리 메뉴에서 사용할 CRUD를 순서대로 작성해보겠습니다.
가장 먼저 프로젝트 구성을 한번 살펴보겠습니다.
우선 build.gralde파일을 아래와 같이 작성했습니다.
plugins {
id "org.springframework.boot" version "2.4.0"
id 'java'
}
group 'com.keichee'
version '1.0-SNAPSHOT'
sourceCompatibility = "1.8"
repositories {
jcenter()
}
ext {
springVersion = '2.4.0'
}
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.12'
implementation 'org.mongodb:mongodb-driver-sync:4.1.1'
testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
implementation "org.springframework.boot:spring-boot-starter-web:$springVersion"
testImplementation("org.springframework.boot:spring-boot-starter-test:$springVersion") {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
testCompileOnly 'org.projectlombok:lombok:1.18.16'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.16'
implementation "io.springfox:springfox-boot-starter:3.0.0"
implementation 'io.springfox:springfox-swagger-ui:3.0.0'
implementation 'com.google.guava:guava:30.0-jre'
}
test {
useJUnitPlatform()
}
mongodb-driver 는 sync 4.1.1 을 사용했습니다.
로깅을 위해서 logback-classic을 추가했고
api 를 쉽게 만들 수 있도록 spring-boot-starter-web을 추가
getter, setter 등의 어노테이션 사용을 위해 lombok 라이브러리를 추가하였고
스웨거 문서를 사용하려고 springfox 라이브러리들도 추가했습니다.
이제 몽고DB와 연결을 위한 설정을 아래와 같이 해줍니다.
@Configuration
public class MongoConfig {
private static final String host = "localhost";
private static final int port = 27017;
private static final String database = "blogapp";
@Bean
public MongoDatabase blogAppDatabase() {
MongoClient client = MongoClients.create(
MongoClientSettings.builder()
.applyToClusterSettings(builder ->
builder.hosts(Collections.singletonList(new ServerAddress(host, port))))
.build());
return client.getDatabase(database);
}
}
컨트롤러에는 딱 4개의 Restful API를 만들었습니다.
@Slf4j
@RestController
@RequestMapping("/diary/life")
@AllArgsConstructor
public class DiaryLifeController {
private final DiaryLifeService diaryLifeService;
@ApiOperation("전체 목록 조회")
@GetMapping
public Response<List<Post>> getPosts() {
log.info("전체 목록 조회");
return new Response<>(diaryLifeService.getPosts(null));
}
@ApiOperation("다이어리 포스팅 신규생성")
@PostMapping
public Response<Void> savePost(@RequestBody Post post) {
validatePostInput(post);
diaryLifeService.createPost(post);
return new Response<>();
}
@ApiOperation("다이어리 포스팅 업데이트")
@PutMapping
public Response<Void> updatePost(@RequestBody Post post) {
validatePostInput(post);
diaryLifeService.updatePost(post);
return new Response<>();
}
@ApiOperation("다이어리 포스팅 삭제")
@DeleteMapping
public Response<Void> deletePost(@RequestParam String _id) {
diaryLifeService.deletePost(_id);
return new Response<>();
}
private void validatePostInput(Post post) {
if (ObjectUtils.isEmpty(post.getTitle())) {
throw new BadRequestException("No TITLE exists.");
}
if (ObjectUtils.isEmpty(post.getContent())) {
throw new BadRequestException("No CONTENT exists.");
}
}
@ExceptionHandler
public ResponseEntity<Response<String>> badRequest(BadRequestException e) {
log.error("Bad request.., e-msg:{}", e.getMessage(), e);
return ResponseEntity.badRequest().body(new Response<>(e.getMessage()));
}
}
스웨거로 보면 다음처럼 나오게 됩니다.
스웨거를 이용해서 기능 테스트를 한번 해보겠습니다.
현재 구현된 기능은 모두 정상적으로 동작하는 것 까지 확인했습니다.
여기까지 작업하면서 쉽게 풀리지 않았던 부분은 몽고DB를 처음 사용하다보니 몽고DB 클라이언트를 이용한 CRUD만드는 부분이었습니다. 기존 RDS와는 다르게 ObjectID 로 핸들링을 해야하는 부분이 있었고, auto increment pk 설정을 따로 할 수 없었습니다. 만약 게시글의 번호가 필요하다면 어떻게 데이터를 저장해야할지 고민이 좀 되는 부분입니다. 각 게시글마다 시퀀스값을 넣어줘야하는데 구글링해서 나오는 것들은 synchronized 가 안될 것 처럼 보여서 테스트도 좀 해봐야 할 것 같습니다.
여기까지 백엔드의 기본적인 구현을 완료했습니다.
다음 포스팅에서는 프론트와 백엔드를 연결하는 부분에 대해서 올리겠습니다.
[GitHub] git clone, push시 Invalid username or password 오류 (0) | 2023.12.11 |
---|---|
[블로그 만들기 - 3] reactjs 프론트와 java 백엔드 연동 (0) | 2020.11.27 |
[블로그 만들기 - 1] 레이아웃 기획 (0) | 2020.11.21 |
[블로그 만들기] 개인프로젝트 시작 (개인블로그 만들기) (0) | 2020.11.19 |