사이먼's 코딩노트
[SpringBoot] REST API (2) 본문
[REST API 적용]
- 앞선 포스팅 'REST API (1)'에서는 개념 소개를 했다면, 이번에는 실제로 REST API를 적용하기 위해 코드에 적용해봅시다.
- 구현된 코드는 저번 JWT 토큰 발급때 진행했던 리포지터리에서 작업을 이어갈 예정이기 때문에 전체 코드는 해당 리포지터리 주소를 통해 참고 부탁드립니다.
- 리포지터리 URL 주소 : https://github.com/psm817/jwt_review
[기본 세팅]
- 먼저 REST API 적용을 하기 위해 build.gradle에 아래와 같이 시큐리티, 유효성체크, DB와 관련된 라이브러리를 추가해준다.
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
runtimeOnly 'com.h2database:h2'
- 기존에 application.yml에 작성한 임의의 secret key를 application-secret.yml이라는 파일을 새로 생성하여 옮겨준다.
- 필자는 application-secret.yml을 보안상 secret key가 유출되지 않도록 깃허브로 push되는 것을 gitignore를 통해 막아놓기 때문에 리포지터리에서는 보이지 않는다.
custom:
jwt:
secretKey: alskdjvocijioq23450lckjvclxzk3430415lkzdlkjacv043121235lkjdazdflv3papopw
- 다음은 application.yml를 아래와 같이 작성한다.
- 아래 세팅은 프로그램 실행과 동시에 application-dev.yml이 활성화되고 application-secret.yml를 포함한다는 의미를 가지며, DB는 3306 포트에 rest_api_dev라는 데이터베이스와 연결된다는 의미를 가진다.
spring:
profiles:
active: dev
include: secret
datasource:
driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://127.0.0.1:3306/rest_api_dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul
username: root
password:
jpa:
hibernate:
ddl-auto: create
properties:
hibernate:
show_sql: true
format_sql: true
use_sql_comments: true
logging:
level:
root: INFO
com.ll.rest_api: DEBUG
org.hibernate.orm.jdbc.bind: TRACE
org.hibernate.orm.jdbc.extract: TRACE
custom:
site:
baseUrl: http://localhost
- 마지막으로 테스트 환경에서 적용되는 설정을 위해 application-test.yml 파일을 생성하여 아래와 같이 작성한다.
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:test;
username: sa
password:
[Spring Security 설정]
- 현재 세팅이 된 상태로 회원의 로그인 테스트를 하기엔 시큐리티가 적용되어 있기 때문에 진행을 할 수 없다.
- 그래서 Spring Security에 관한 설정 SecurityConfig.java 클래스를 생성한 뒤 아래와 같이 코드를 작성한다.
- 해당 코드를 작성하게 되면 시큐리티에 의해 생성된 폼 로그인 방식이 꺼지게 되면서 커스텀이 가능하게 된다.
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors().disable() // 타 도메인에서 API 호출 가능
.csrf().disable() // CSRF 토큰 끄기
.httpBasic().disable() // httpBaic 로그인 방식 끄기
.formLogin().disable() // 폼 로그인 방식 끄기
.sessionManagement(sessionManagement ->
sessionManagement.sessionCreationPolicy(STATELESS)
); // 세션끄기
return http.build();
}
}
[MemberController 생성]
- /member/login POST 전달을 구현하기 위해서 MemberController.java 클래스를 생성하고 아래와 같이 코드를 작성한다.
- 기존과 다르게 어노테이션을 @Controller가 아닌 @RestController를 작성해주면 return 값에 String 문자열을 @ResponseBody 없이 작성해도 문제가 없다.
@RestController
@RequestMapping("/member")
public class MemberController {
@PostMapping("/login")
public String login() {
return "성공";
}
}
- 테스트 환경에서도 MemberController.java 클래스를 동일하게 만들어 MockMvc 라이브러리를 통해 웹 애플리케이션을 테스트 해본다.
- 아래와 같이 코드를 작성하면 /member/login으로 데이터를 보내는데, 해당 데이터는 content에 작성된 username, password를 UTF-8형태의 JSON화 시켜서 보낸다.
- 테스트를 실행하면 실제 위에서 MemberController.java에 구현한 /member/login로 해당 데이터가 전달되고, 전달에 잘 됐다면 테스트 창의 body에 "성공"이라는 문자가 표시된다.
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
@ActiveProfiles("test")
class MemberControllerTest {
@Autowired
private MockMvc mvc;
@Test
@DisplayName("POST /member/login 은 로그인 처리 URL 이다.")
void t1() throws Exception {
// When
ResultActions resultActions = mvc
.perform(
post("/member/login")
.content("""
{
"username": "user1",
"password": "1234"
}
""".stripIndent())
.contentType(new MediaType(MediaType.APPLICATION_JSON, StandardCharsets.UTF_8))
)
.andDo(print());
// Then
resultActions
.andExpect(status().is2xxSuccessful());
}
}
[테스트용 Member 생성]
- member에 관련된 기본 패키징은 리포지터리를 통해 참고 부탁드리며, 모든 구성이 완료되었다면 initData 패키지 내의 NotProd.java 클래스를 생성하여 테스트 회원 데이터를 2명 만들어준다.
- 아래와 같이 코드를 작성하면 프로그램 시작과 동시에 DB에 회원 데이터 2명이 생성된다.
- 해당 코드가 정상적으로 실행되려면 MemberService.java에 join() 메서드가 작성되어 있어야한다.
@Configuration
@Profile({"dev", "test"})
public class NotProd {
@Bean
CommandLineRunner initData(MemberService memberService, PasswordEncoder passwordEncoder) {
String password = passwordEncoder.encode("1234");
return args -> {
Member member1 = memberService.join("user1", password, "user1@test.com");
Member member2 = memberService.join("user2", password, "user2@test.com");
};
}
}
반응형
'Java > SpringBoot' 카테고리의 다른 글
[SpringBoot] REST API (4) (0) | 2024.06.19 |
---|---|
[SpringBoot] REST API (3) (0) | 2024.06.16 |
[SpringBoot] REST API (1) (0) | 2024.06.16 |
[SpringBoot] JWT 토큰 발급 (0) | 2024.06.15 |
[SpringBoot] Cookie / Session / JWT (2) | 2024.06.15 |