1. 글을 작성하게 된 계기
분기문으로 개발 환경을 구분하는 것은 좋은 방법인가? 에 대해 생각을 정리하기 위해 글을 작성하게 되었습니다.
1
2
3
4
5
6
7
8
9
10
11
12
@Service
@RequiredArgsConstructor
public class ExampleService {
private final String env;
public void method() {
if ("dev".equals(env)) {
}
}
}
2. 무슨 말일까?
분기문으로 개발 환경을 구분하는 것 이 무슨 말인지 안 와닿을 수 있습니다. 예를 들어, 회원 가입을 할 때, Github로 부터 회원 정보를 받아와 데이터베이스에 저장한다고 가정해 보겠습니다. 이 경우, 다음과 같은 순서로 회원 가입이 진행될 것입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@FacadeLayer
@RequiredArgsConstructor
public class UserFacade {
......
public DailygeToken login(final String code) {
// 1. Github에서 인증 및 회원 정보 조회
final GithubUserInfoResponse response = githubOAuthManager.getUserInfo(code);
// 2. 회원 정보 저장
final User newUser = userService.upsert(response.getEmail());
// 3. 토큰 발행 및 저장
final DailygeToken token = tokenProvider.createToken(userId, response.getEmail());
tokenManager.saveRefreshToken(userId, token.refreshToken());
return token;
}
......
}
이때, 회원 정보를 받아오는 부분은 Github api를 호출 해야 하는데, 이 부분을 개발 환경에 따라 다르게 처리 하는 것이죠. 운영 환경이라면 Github api를 호출하며, 개발 또는 테스트 환경이라면 목 데이터를 반환하는 형태로요.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@ExternalLayer
public class GoogleOAuthManager {
private final String env;
......
// Github api를 호출해서 인증 토큰과 사용자 정보를 받아온다.
public GithubUserInfoResponse getUserInfo(final String code) {
// 개발 환경에 따라 api 호출 여부를 결정한다.
if (!"prod".equals(env)) {
return returnMockUserInfo();
}
final GithubAuthorizationResponse response = getAccessToken(code);
return getUserInfo(response);
}
private GithubUserInfoResponse returnMockUserInfo() {
final String email = UUID.randomUUID().toString().replace("-", "");
final String emailFormat = email + "@gmail.com";
final String imageUrl = "https://shorturl.at/dejs2";
return new GithubUserInfoResponse(emailFormat, imageUrl, true);
}
......
3. 그래서, 좋은 방법일까?
개인적으로 괜찮은 방법이라고 생각합니다. 개발 환경에 따라 코드가 다르게 동작하게 하면, 상황에 따라 유연하게 대처 할 수 있기 때문입니다. 특히 테스트 환경 에서는 실제 api 호출 없이도 필요한 검증을 할 수 있습니다.
개인적 의견이기 때문에 다르게 생각한다면 편하게 알려주세요.
예를 들어, 회원가입 부하 테스트를 할 때, 외부 시스템이 중간에 끼어 있다면 우리 시스템의 정확한 성능을 측정할 수 없습니다. 이 경우, 목 데이터를 사용해 외부 의존성을 격리 시켜야 합니다. 분기문으로 환경을 구분하고 적절한 데이터를 반환하면, 외부 의존성은 격리하고 우리 시스템의 정확한 성능을 측정할 수 있겠죠?
이전 회사에서 배송을 처리할 때, 택배사의 api를 호출 하는 로직이 있었습니다. 이 부분을 처리하는 것이 정말 까다로웠는데요, 배송 처리를 위해서는 택배사에 전화 를 해서 배송 처리를 부탁해야 했기 때문입니다. 따라서 개발 환경에서는 목 데이터를 반환해 빠르게 개발하고, 실제 동작 유무를 확인할 때만 api 호출이 되도록 처리했습니다.
기능의 실제 동작 유무를 테스트하는 것이 아니라면, 개발 시에는 목 데이터를 반환하고 빠르게 개발하면 되겠죠?
하지만 모든 경우 이 방법이 좋을 수는 없습니다. 성능이 중요한 경우, 이런 사소한 부분까지도 영향을 받을 수 있기 때문입니다. 또한 테스트 코드 가 많아질 수도 있고요. 따라서 자신의 상황에 맞게 이를 적용하는 것이 좋습니다.
- 성능이 중요한 경우 사용하기 힘들 수 있다.
- 테스트 코드를 더 작성해야 할 수도 있다.
4. 정리
프로그램의 사소한 부분까지 개발자가 코드로 제어할 수 있는 것 이 좋은 프로그램 이라고 생각합니다. 이렇게 되면 기능을 유연하게 추가 할 수 있고, 유지보수 가 쉬워지니까요. 따라서 분기문을 두고 상황에 따라 유연하게 컨트롤할 수 있는 것은 꽤 좋은 방법이지 않을까 싶습니다.
이전에는 불필요한 분기문을 만든다고 이 방법에 부정적이었는데, 시간이 지나면서 생각이 바뀌네요. 😶