다음으로 만들어 볼 것은 Redis를 활용한 RestfulAPI CRUD 이다.
인메모리 데이터베이스란 컴퓨터의 주 메모리에 데이터를 저장하는 DB를 의미한다.
보조기억 장치가 아닌 주 메모리에 데이터를 저장하기 때문에 데이터 처리가 다른 DB에 비해 월등히 빠르다는 장점을 갖고 있다.
Redis란 키-값 기반의 인메모리 데이터 저장소이다. 키-값 기반이라는 점에서 Java의 Map 자료구조와 비슷하게 데이터가 저장 및 관리된다.
인메모리 데이터베이스의 특성상 빠른 입출력 속도를 가지며, 비단 데이터의 저장 뿐 아니라 메시지 큐로써 동작할 수도 있다.
일단 외부에서 Redis에 진입할 수 있도록 설정하자.
설정은 /etc/redis/redis.conf 파일을 다음과 같이 수정하면 된다.
이후 systemctl restart redis 명령어를 통해 redis를 재실행하면 기존의 127.0.0.1 이 0.0.0.0 으로 바뀌어있다.
그렇다면 일단 application.properties에서 redis의 주소를 입력.
Redis를 다루는 법은 지금까지 한 것처럼 JPA를 사용하는 방법을 사용할 수 있지만,
일반 Map을 사용하듯 사용하는 방법도 존재한다.
Map 처럼 사용하는 방법은 다음 포스팅에 기재하였으며, 현 포스팅에서는 JPA를 기반으로 사용하는 방법을 포스팅한다.
그리고 이전에 만든 것과 마찬가지로 복사-붙여넣기를 통해 도메인부터 컨트롤러를 제작하자.
Domain의 경우 @RedisHash 어노테이션을 사용한다.
RedisDomain.java
package kr.co.opensource.redis;
import javax.persistence.Id;
import org.springframework.data.redis.core.RedisHash;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@RedisHash("test")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class RedisDomain {
@Id
String id;
String val;
String val2;
}
RedisRepository.java
package kr.co.opensource.redis;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface RedisRepository extends CrudRepository<RedisDomain, String>{
}
RedisService.java
package kr.co.opensource.redis;
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 RedisService {
@Autowired RedisRepository repo;
// @Resource(name="redisTemplate") ValueOperations valueOps;
public RedisDomain find(String id) {
log.info("RedisService.find init : {}", id);
return repo.findById(id).orElse(null);
}
public int save(RedisDomain domain) {
log.info("RedisService.save init : {}", domain.toString());
if(repo.findById(domain.getId()).orElse(null) != null) {
//이미 존재하는 데이터
log.info("RedisService.save data already exists : {}", domain.getId());
return CommonCode.EXCEPTION;
}
try {
repo.save(domain);
}
catch (Exception e) {
log.error("RedisService.save some internal error occured : {}", e.getMessage());
return CommonCode.ERROR;
}
return CommonCode.SUCCESS;
}
public int update(RedisDomain domain) {
log.info("RedisService.update init : {}", domain.toString());
if(repo.findById(domain.getId()).orElse(null) == null) {
//존재하지 않는 데이터
log.info("RedisService.update data not exists : {}", domain.getId());
return CommonCode.EXCEPTION;
}
try {
repo.save(domain);
}
catch (Exception e) {
//쿼리 과정 중 에러 발생
log.error("RedisService.update some internal error occured : {}", e.getMessage());
return CommonCode.ERROR;
}
return CommonCode.SUCCESS;
}
public int delete(String id) {
log.info("RedisService.delete init : {}", id);
if(repo.findById(id) == null) {
//존재하지 않는 데이터
log.info("RedisService.delete data not exists : {}", id);
return CommonCode.EXCEPTION;
}
try {
repo.deleteById(id);
}
catch (Exception e) {
log.error("RedisService.delete some internal error occured : {}", e.getMessage());
return CommonCode.ERROR;
}
return CommonCode.SUCCESS;
}
public List<RedisDomain> findAll() {
log.info("RedisService.findAll init");
Iterator<RedisDomain> domainItr = repo.findAll().iterator();
List<RedisDomain> domainList = new ArrayList();
while(domainItr.hasNext()) {
domainList.add(domainItr.next());
}
return domainList;
}
}
RedisRestController.java
package kr.co.opensource.redis;
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.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 org.springframework.web.bind.annotation.RestController;
import kr.co.opensource.CommonCode;
import kr.co.opensource.ResponseMessage;
import kr.co.opensource.ResponseVO;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class RedisRestController {
@Autowired RedisService service;
@RequestMapping(value={"/redis","/redis/{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) RedisDomain domain) {
log.info("RedisRestController.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("RedisRestController.controller get all data");
List<RedisDomain> redisDomainList = service.findAll();
msg.setStatus(HttpStatus.OK);
msg.setMessage(ResponseMessage.OK);
msg.setData(redisDomainList);
return new ResponseEntity<ResponseVO>(msg, headers, HttpStatus.OK);
}
log.info("RedisRestController.controller get one data : {}", key);
RedisDomain returnDomain = service.find(key);
if(returnDomain == null) {
log.warn("RedisRestController.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("RedisRestController.controller save data : {}", domain);
if(domain == null) {
log.error("RedisRestController.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("RedisRestController.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("RedisRestController.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("RedisRestController.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("RedisRestController.controller update data : {}", key);
if(key == null) {
log.warn("RedisRestController.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("RedisRestController.controller not exists data : {}", domain);
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("RedisRestController.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("RedisRestController.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("RedisRestController.controller update data : {}", key);
if(key == null) {
log.warn("RedisRestController.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("RedisRestController.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("RedisRestController.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("RedisRestController.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) 삭제
'실습 > 리눅스 서버 + 스프링 부트' 카테고리의 다른 글
07. Kafka_Pub&Con (0) | 2021.05.30 |
---|---|
06. RabbitMQ_Con&Pro (0) | 2021.05.30 |
04. RestfulAPI_MongoDB (0) | 2021.05.23 |
03. RestfulAPI_MariaDB (0) | 2021.05.19 |
02. 윈도우 세팅 및 프로젝트 생성 (0) | 2021.05.19 |