Spring-boot, MyBatis 로 구성된 REST API 개발
Spring-boot 프로젝트를 진행 한지도 거의 2년이 흘렀더니, 전혀 새로운 언어를 접하는 것과 같은 느낌을 받았다.
이대로는 안될 것 같아 하드코딩으로 되어 있던 개인 홈페이지를 리소스를 연동하는 RESTful API를 이용하여 구성되는 구조 변경 개인 프로젝트를 진행하기로 하였다.
웹서버는 React를 공부 하며 변경할 예정이고, 콘텐츠를 관리하는 CMS는 기존에 만들고 있던 PHP, Codeigniter를 사용, API서버는 JAVA, Spring-boot, MyBatis로 구성할 예정이다.
이번 프로젝트는 모두 github와 jenkins를 이용하여 버전 관리 및 배포하고, 개발 TOOL은 JetBrains 사의 intelliJ, PhpStrom, WebStorm을 사용할 예정이며, 개발되는 과정은 블로그를 통하여 남기기로 결심하였다.
첫 단계로는 API 서버부터 구성한다.
개인 홈페이지는 내 개인의 정보 및 경력, 프로젝트 이력, SKILL SET 등의 정보를 제공하는 기능을 가지고 있고, API 서버는 나의 이력을 조회하는 public기능과 해당 정보를 관리하는 private 기능 두 가지를 모두 제공할 예정이다.
private 정보의 인증방식은 oauth2.0을 사용할 예정이다.
1. 프로젝트부터 생성한다.
최대한 공부하는 마음으로 접근 중이기 때문에 default 설정들을 그대로 사용한다.
Spring Initializr 를 선택한다.
2. 프로젝트 정보 입력
Gradle을 사용한다. xml보다는 간결하고 가독성이 좋다고 생각한다.
프로젝트 정보를 입력한다.
3. 기본 dependencies를 선택한다.
dependency는 언제든지 추가 할 수 있다. Web과 MyBatis만 우선 선택한다.
Web dependency 선택 MyBatis 선택 완료
4. Gradle 모듈 추가
default를 그대로 사용하였다.
Gradle module 추가
프로젝트가 생성되었다.
5. Gradle에 정보에 dependencies 추가. ( build.gradle )
개인 홈페이지는 MariaDB를 사용하기 때문에 mariaDB 드라이버 org.mariadb.jdbc:mariadb-java-client를 추가하였다.
plugins { id 'org.springframework.boot' version '2.1.5.RELEASE' id 'java' } apply plugin: 'io.spring.dependency-management' group = 'ycpark.api' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.0.1' compile('org.mariadb.jdbc:mariadb-java-client') <--- mariadb 추가 testImplementation 'org.springframework.boot:spring-boot-starter-test' }
6. Server 정보 입력 ( application.properties )
Spring-boot는 Tomcat 서버를 내장하고 있어서 매우 편리하다.
몇몇 mybatis용 추가 옵션도 추가하였다.
server.port=8080 mybatis.type-aliases-package=ycpark.api.entity mybatis.mapper-locations=mapper/*.xml mybatis.configuration.map-underscore-to-camel-case=true spring.datasource.driver-class-name=org.mariadb.jdbc.Driver spring.datasource.url=jdbc:mariadb://{db서버정보:포트}/{데이터베이스명}?characterEncoding=UTF-8 spring.datasource.username={접속계정} spring.datasource.password={비밀번호}
이제 설정이 완료되었다.
7. 서비스 구동 테스트
8. 디렉터리 구조 설계
- controller
- service
- dao
- entity
디렉터리는 최대한 일반적으로 사용되는 형태를 유지하려고 한다.
일반적이라는 표현은 나의 주관적인 생각이다.
mapper 파일은 /resource/mapper로 분리하였다.
9.Entity calss 파일 생성
package ycpark.api.entity; import java.util.List; public class Company { int companyNo; String companyName; String startDate; String endDate; List departmentList; public int getCompanyNo() { return companyNo; } public void setCompanyNo(int companyNo) { this.companyNo = companyNo; } public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public String getStartDate() { return startDate; } public void setStartDate(String startDate) { this.startDate = startDate; } public String getEndDate() { return endDate; } public void setEndDate(String endDate) { this.endDate = endDate; } public List getDepartmentList() { return departmentList; } public void setDepartmentList(List departmentList) { this.departmentList = departmentList; } }
package ycpark.api.entity; public class Department { int departmentNo; int companyNo; String department; public int getDepartmentNo() { return departmentNo; } public void setDepartmentNo(int departmentNo) { this.departmentNo = departmentNo; } public int getCompanyNo() { return companyNo; } public void setCompanyNo(int companyNo) { this.companyNo = companyNo; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } }
10. Controller 파일
package ycpark.api.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import ycpark.api.service.CompanyService; import java.util.HashMap; @RestController @RequestMapping(value="/companies") public class CompanyController { @Autowired CompanyService companyService; @RequestMapping(value="", method=RequestMethod.GET) public ResponseEntity getCompanyList(){ HashMap result = new HashMap<>(); result.put("data", companyService.getCompanyList()); return new ResponseEntity<>(result, HttpStatus.OK); } }
11. Service 파일
서비스는 습관처럼 사용하던 implements를 사용하여 추상화하던 방식을 사용하지 않기로 하였다. 현재까지는 불필요하다고 생각하기 때문이다.
package ycpark.api.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import ycpark.api.dao.CompanyDao; import ycpark.api.dao.DepartmentDao; import ycpark.api.entity.Company; import ycpark.api.entity.Department; import java.util.List; @Service public class CompanyService { @Autowired CompanyDao companyDao; @Autowired DepartmentDao departmentDao; public List getCompanyList() { List companyList = companyDao.getCompanyList(); for (Company company : companyList) { Department department = new Department(); department.setCompanyNo(company.getCompanyNo()); List departmentList = departmentDao.getDepartmentList(department); company.setDepartmentList(departmentList); } return companyList; } }
12. DAO 파일
package ycpark.api.dao; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import ycpark.api.entity.Company; import java.util.List; @Repository @Mapper public interface CompanyDao { List getCompanyList(); }
package ycpark.api.dao; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import ycpark.api.entity.Company; import ycpark.api.entity.Department; import java.util.List; @Repository @Mapper public interface DepartmentDao { List getDepartmentList(Department department); }
13. Mapper 파일
SELECT company_no , company_name , start_date , end_date FROM company ORDER BY company_no DESC
SELECT department_no , company_no , department FROM department WHERE 1=1 AND company_no = #{companyNo} ORDER BY department_no DESC
테스트를 통해 이상 없이 동작하는 것을 확인하였다.
기본적인 동작은 완성되었고, 추가 기능 및 벨리데이션, oauth를 구현 예정이다.
https://github.com/yoonchulpark/api.ycpark.net
from http://blog.ycpark.net/101 by ccl(A) rewrite - 2020-03-07 06:21:34
댓글
댓글 쓰기