시큐리티를 적용하기 전 데이터베이스를 연결하고 JPA를 활용하여 RestAPI 통신까지 확인해보도록 하자.
설정
DB연결과 API 통신 기능 확인을 위해 간략하게 회원가입 기능을 구현한다.
의존성 추가
dependencies {
... 생략 ...
// Jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// MySQL
runtimeOnly 'com.mysql:mysql-connector-j'
// env
implementation 'io.github.cdimascio:dotenv-java:2.2.0'
... 생략 ...
}
`build.gradle`에 JPA와 데이터베이스, 그리고 미리 env 의존성을 추가해준다.
의존성 추가 등 gradle 파일을 바꿀 경우 위와 같은 아이콘이 뜰텐데 아이콘을 클릭하여 gradle 설정을 한다.
`application.yml`
spring:
application:
name: 프로젝트 이름
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver(사용하는 DB)
url: jdbc:mysql://localhost:3306/(데이터베이스 이름)
username: (DB 계정)
password: (DB 비밀번호)
jpa:
hibernate:
ddl-auto: update
`application.yml`에 데이터베이스 정보와 JPA 설정을 작성한다.
여기서 `application.yml`파일은 git에 업로드 되는 파일이기 때문에 이대로 git에 업로드할 경우 데이터베이스가 노출될 위험이 있다. 이를 방지하기 위해 .env를 이용한다.
resources 경로에 `.env`파일을 생성한다.
중요한 정보가 저장될 .env 파일은 git에 업로드 할 파일이 아니므로 `.gitignore`파일에도 .env를 추가한다.
`.env`
DB_URL=jdbc:mysql://localhost:(DB 포트번호)/(BD 이름)
DB_USERNAME=(DB 계정)
DB_PASSWORD=(DB 암호)
env 파일에 중요 정보들을 위와 같이 작성한 후
`application.yml`
spring:
application:
name: SpringStarter
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
jpa:
hibernate:
ddl-auto: update
`application.yml`파일을 이렇게 업데이트 해주면 된다.
그리고 프로젝트명으로 생성된 `(프로젝트명)Application.java`파일을 연다.
필자의 경우 `SpringStarterApplication.java`파일이다.
// 생략
@EnableJpaAuditing
@SpringBootApplication
public class SpringStarterApplication {
public static void main(String[] args) {
Dotenv dotenv = Dotenv.configure().load();
dotenv.entries().forEach(entry -> System.setProperty(entry.getKey(), entry.getValue()));
SpringApplication.run(SpringStarterApplication.class, args);
}
}
env 변수를 등록하고 JPA를 사용하기 위해 위와같이 `@EnableJpaAuditing` 어노테이션을 추가하고 main에 2문장을 추가한다.
그리고 사용하는 DB에서 데이터 베이스를 생성한다. 데이터베이스의 이름은 위에 작성한 DB와 일치해야한다.
`application.yml` 에서 JPA ddl-auto에서 update라고 설정해뒀기에 데이터베이스만 잘 만들어두면 테이블을 만들 필요는 없다.
데이터 베이스 설정이 끝났다면 회원가입 기능 구현을 할 차례이다.
기능 구현
간단한 회원가입을 구현해본다.
패키지 구조는 도메인별로 나누는 것으로 구현하였다.
Entity
// 생략
@Entity
@Table(name = "`member`")
@Getter
@NoArgsConstructor
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 30, unique = true, updatable = false)
private String loginId;
@Column(nullable = false, length = 100)
private String password;
@Column(nullable = false, length = 10)
private String name;
@Column(nullable = false)
@Temporal(TemporalType.DATE)
private LocalDate birthDate;
@Column(nullable = false, length = 50)
private String email;
@Builder
private Member(Long id, String loginId, String password, String name, LocalDate birthDate, String email) {
this.id = id;
this.loginId = loginId;
this.password = password;
this.name = name;
this.birthDate = birthDate;
this.email = email;
}
}
`@Entity`어노테이션으로 엔티티라 명시했을 경우 PK인 id의 경우 `@Id` 이용해서 명시를 해주어야한다. 각 컬럼별로 속성을 작성하면 서버를 실행했을 때 이대로 테이블이 만들어진다.
`MemberRepository`
//생략
public interface MemberRepository extends JpaRepository<Member, Long> {
Optional<Member> findByLoginId(String loginId);
}
JPA를 상속받고 클래스와 ID를 명시해준다. 로그인 아이디로 회원을 찾는 함수를 나중에 예외처리를 위해 Optional 형식으로 반환하는 형태로 작성만 해준다.
`MemberService`
@Service
@Transactional
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
/**
* 회원 가입
*/
public String signUp(MemberRegisterRequest request) {
Optional<Member> findMember = memberRepository.findByLoginId(request.getLoginId());
if (findMember.isPresent()) {
return "중복된 ID 입니다.";
}
Member member = Member.builder()
.loginId(request.getLoginId())
.password(request.getPassword())
.name(request.getName())
.birthDate(request.getBirthDate())
.email(request.getEmail())
.build();
memberRepository.save(member);
return "가입되었습니다.";
}
}
서비스도 간단하게 ID 중복체크만 진행하여 가입을 하도록 작성하였다.
`MemberRegisterRequest`
//생략
@Data
public class MemberRegisterRequest {
private String loginId;
private String password;
private String email;
private String name;
private LocalDate birthDate;
}
Post요청으로 받을 Request를 작성.
`MemberController`
@RestController
@RequestMapping("/api/member")
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@PostMapping("/signup")
public String signup(@RequestBody MemberRegisterRequest request) {
return memberService.signUp(request);
}
}
RestController를 작성하여 구현을 마무리하고 제대로 통신이 되는지 확인해본다.
API 통신 확인(회원가입 확인)
서버를 실행시키고 데이터베이스를 조회해보면 테이블이 자동으로 만들어졌음을 확인할 수 있다.
서버로 요청을 보냈을 경우 제대로 가입이 되어 '가입되었습니다.'라는 문자열을 받았고 데이터베이스에도 제대로 들어갔음을 확인할 수 있다.
같은 아이디로 가입 요청을 했을 경우에도 올바르게 처리되어 반환됨을 알 수 있다.
다음 포스팅에서는 Validation을 추가하고 예외처리를 핸들링하는법, Response형태를 통일화 시키는 부분을 진행한다.