본문 바로가기
실습/리눅스 서버 + 스프링 부트

04. RestfulAPI_MongoDB

by 이민우 2021. 5. 23.
728x90
반응형

이번에 만들 것은 MongoDB를 활용한 CRUD RestfulAPI이다.

 

몽고DBNoSQL DB의 한 종류로, humongous의 줄임말이다. 직역하면 매우 큰 DB 라는 뜻이다.

 

몽고DB는 NoSQL 중 Document DB 타입의 데이터베이스로, 그냥 간단하게 설명하면 데이터가 JSON/XML 같은 형태로 저장되는 DB라는 의미이다.

예시를 보자면 아래와 같이 저장된다고 볼 수 있다.

 

몽고디비의 데이터는 Document라고 부르고, 이 Document의 집합 즉 테이블을 Collection이라고 부른다. Collection의 집합은 DB로, 이 부분은 RDB와 같다.


NoSQL 답게 몽고디비는 RDB보다 훨씬 빠르지만, 일관성을 유지하기에는 힘이 들 수 있다.

 

그러면 이제 개발을 시작할 것인데, 사실 전체적인 틀은 MariaDB와 별반 다를 바 없다.

일단 application.properties이다.

 

프로그램 형태도 마찬가지로 Domain-Repository-Service-Controller 순으로 작성한다.

데이터베이스, 작동 방식도 사실 MariaDB의 코드를 그대로 복사해와 변수명, 함수명 정도만 바꾸어주었다.

 

다만 Domain의 경우 MariaDB는 @Table 어노테이션을 사용했지만 MongoDB는 @Document 어노테이션을 사용했다.

그리고 MongoDB의 PK는 id라는 이름으로 사용되어야 하며, 타입은 원래는 ObjectID여야 하지만 실습에서는 편의상 String으로 대체했다.

 

MongoDomain.java

package kr.co.opensource.mongo;

import javax.persistence.Entity;
import javax.persistence.Id;

import org.springframework.data.mongodb.core.mapping.Document;

import com.fasterxml.jackson.annotation.JsonInclude;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Document(collection="test_col")
@JsonInclude(JsonInclude.Include.NON_NULL)
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class MongoDomain {
	@Id
	private String id;
	
	private String val;
}

 

Repository는 MongoDB 전용 Repository를 사용해야 한다.

 

MongoRepositories.java

package kr.co.opensource.mongo;

import java.util.Optional;

import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@EnableMongoRepositories
public interface MongoRepositories extends MongoRepository<MongoDomain, ObjectId>{
	public Optional<MongoDomain> findById(String id);
	public void deleteById(String id);
}

 

Service와 Controller는 MariaDB와 완전히 동일하다.

 

MongoService.java

package kr.co.opensource.mongo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kr.co.opensource.CommonCode;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class MongoService {
	
	@Autowired MongoRepositories repo;
	
	public int save(MongoDomain domain) {
		log.info("MongoService.save init : {}", domain.toString());
		
		if(repo.findById(domain.getId()).orElse(null) != null) {
			//이미 존재하는 데이터
			log.info("MongoService.save data already exists : {}", domain.getId());
			
			return CommonCode.EXCEPTION;
		}
		
		try {
			repo.save(domain);
		}
		catch(Exception e) {
			//쿼리 과정 중 에러 발생
			log.error("MongoService.save some internal error occured : {}", e.getMessage());
			
			return CommonCode.ERROR;
		}
		
		return CommonCode.SUCCESS;
	}
	
	public int update(MongoDomain domain) {
		log.info("MongoService.update init : {}", domain.toString());
		
		MongoDomain tmpDomain = repo.findById(domain.getId()).orElse(null);
		
		if(tmpDomain == null) {
			//존재하지 않는 데이터
			log.info("MongoService.update data not exists : {}", domain.getId());
			
			return CommonCode.EXCEPTION;
		}
		
		try {
			tmpDomain.setVal(domain.getVal());
			repo.save(tmpDomain);
		}
		catch(Exception e) {
			//쿼리 과정 중 에러 발생
			log.error("MongoService.update some internal error occured : {}", e.getMessage());
			
			return CommonCode.ERROR;
		}
		
		return CommonCode.SUCCESS;
	}
	
	public int delete(String key) {
		log.info("MongoService.delete init : {}", key);
		
		if(repo.findById(key).orElse(null) == null) {
			//존재하지 않는 데이터
			log.info("MongoService.delete data not exists : {}", key);
			
			return CommonCode.EXCEPTION;
		}
		
		try {
			repo.deleteById(key);
		}
		catch(Exception e) {
			log.error("MongoService.delete some internal error occured : {}", e.getMessage());
			
			return CommonCode.ERROR;
		}
		return CommonCode.SUCCESS;
	}
	
	public MongoDomain find(String key) {
		log.info("MongoService.find init : {}", key);
		
		return repo.findById(key).orElse(null);
	}

	public List<MongoDomain> findAll() {
		log.info("MongoService.findAll init");
		
		Iterator<MongoDomain> domainItr = repo.findAll().iterator();
		List<MongoDomain> domainList = new ArrayList();
		
		while(domainItr.hasNext()) {
			domainList.add(domainItr.next());
		}
		
		return domainList;
	}
}

 

MongoRestController.java

package kr.co.opensource.mongo;

import java.nio.charset.Charset;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import kr.co.opensource.CommonCode;
import kr.co.opensource.ResponseMessage;
import kr.co.opensource.ResponseVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class MongoRestController {
	@Autowired MongoService service;
	
	@RequestMapping(value={"/mongo","/mongo/{key}"}, method= {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
	public @ResponseBody ResponseEntity<ResponseVO> controller(HttpServletRequest req,
													  @PathVariable(value="key", required=false) String key,
													  @RequestBody(required=false) MongoDomain domain) {

		log.info("MongoRestController.controller init http: {}", req.getMethod());
		
		ResponseVO msg = new ResponseVO();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
		
		String method = req.getMethod();
		
		if(method.equals("GET")) {
			if(key == null) {
				
				log.info("MongoRestController.controller get all data");
				
				List<MongoDomain> mongoDomainList = service.findAll();
				
				msg.setStatus(HttpStatus.OK);
				msg.setMessage(ResponseMessage.OK);
				msg.setData(mongoDomainList);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
			}

			log.info("MongoRestController.controller get one data : {}", key);
			MongoDomain returnDomain = service.find(key);
			
			if(returnDomain == null) {
				log.warn("MongoRestController.controller not exists data : {}", key);
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.NOT_EXISTS);
				msg.setData(null);

				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			
			msg.setStatus(HttpStatus.OK);
			msg.setMessage(ResponseMessage.OK);
			msg.setData(returnDomain);
			return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
		}
		else if(method.equals("POST")) {
			log.info("MongoRestController.controller save data : {}", domain);
			if(domain == null) {
				log.error("MongoRestController.controller required parameter not exists");
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.NOT_EXISTS_BODY);
				msg.setData(null);

				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			
			int result = service.save(domain);
			
			if(result == CommonCode.EXCEPTION) {
				//이미 존재하는 데이터
				log.warn("MongoRestController.controller already exist data : {}", domain);
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.EXISTS);
				msg.setData(null);

				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			else if(result == CommonCode.ERROR) {
				//쿼리 실패
				log.warn("MongoRestController.controller some interner error exists");
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.INTERNAL_ERROR);
				msg.setData(null);

				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			else {
				//성공
				log.info("MongoRestController.controller successfully saved data : {}", domain);
				
				msg.setStatus(HttpStatus.CREATED);
				msg.setMessage(ResponseMessage.CREATED);
				msg.setData(domain);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.CREATED);
			}
		}
		else if(method.equals("PUT")) {
			log.info("MongoRestController.controller update data : {}", key);
			
			if(key == null) {
				log.warn("MongoRestController.controller required parameter not exists");
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.NOT_EXISTS_KEY);
				msg.setData(null);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			
			
			int result = service.update(domain);
			
			if(result == CommonCode.EXCEPTION) {
				log.info("MongoRestController.controller not exists data : {}", domain);
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.EXISTS);
				msg.setData(null);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			else if(result == CommonCode.ERROR) {
				//쿼리 실패
				log.warn("MongoRestController.controller some interner error exists");
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.INTERNAL_ERROR);
				msg.setData(null);

				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			else {
				//성공
				log.info("MongoRestController.controller successfully updated data : {}", key);
				
				msg.setStatus(HttpStatus.OK);
				msg.setMessage(ResponseMessage.OK);
				msg.setData(domain);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
			}
			
		}
		else if(method.equals("DELETE")) {
			log.info("MongoRestController.controller update data : {}", key);
			
			if(key == null) {
				log.warn("MongoRestController.controller required parameter not exists");
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.NOT_EXISTS_KEY);
				msg.setData(null);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}

			int result = service.delete(key);
			
			if(result == CommonCode.EXCEPTION) {
				log.warn("MongoRestController.controller not exists data : {}", key);
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.NOT_EXISTS);
				msg.setData(null);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			else if(result == CommonCode.ERROR) {
				log.warn("MongoRestController.controller some interner error exists");
				
				msg.setStatus(HttpStatus.BAD_REQUEST);
				msg.setMessage(ResponseMessage.INTERNAL_ERROR);
				msg.setData(null);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.BAD_REQUEST);
			}
			else {
				//성공
				log.info("MongoRestController.controller successfully deleted data : {}", key);
				
				msg.setStatus(HttpStatus.OK);
				msg.setMessage(ResponseMessage.OK);
				msg.setData(null);
				
				return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
			}
			
		}
		
		//여기까지 올일은 사실상 없음.
		//그냥 return null 하기 싫어서 기재.
		msg.setStatus(HttpStatus.METHOD_NOT_ALLOWED);
		msg.setMessage(ResponseMessage.NOT_ALLOWED_METHD);
		msg.setData(null);
		return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.METHOD_NOT_ALLOWED);
	}
	
}

 

 

 

 

이렇게 코딩을 끝마치고 마찬가지로 포스트맨을 사용하면 테스트를 해볼 수 있다.

 

1) 등록

2) 수정

3) 조회

4) 삭제

728x90
반응형

'실습 > 리눅스 서버 + 스프링 부트' 카테고리의 다른 글

06. RabbitMQ_Con&Pro  (0) 2021.05.30
05. RestfulAPI_Redis CRUD  (0) 2021.05.23
03. RestfulAPI_MariaDB  (0) 2021.05.19
02. 윈도우 세팅 및 프로젝트 생성  (0) 2021.05.19
01. 리눅스 서버 세팅  (0) 2021.05.05