[quantHelper] 개발 - API

JUJU·2024년 4월 10일
0

프로젝트

목록 보기
5/26

구현 내용

1. KisService 클래스

@Service
@Transactional
@Slf4j
public class KisService {

    private final WebClient webClient;
    private final String baseUrl;
    private final String appKey;
    private final String appSecretKey;

    @Autowired
    public KisService(WebClient webClient, @Value("${spring.kis-api.endpoint-url}") String baseUrl, @Value("${spring.kis-api.app-key}")String appKey, @Value("${spring.kis-api.app-secret-key}") String appSecretKey) {
        this.webClient = webClient;
        this.baseUrl = baseUrl;
        this.appKey = appKey;
        this.appSecretKey = appSecretKey;
    }

	// Controller에서 이 메소드를 호출한다.
    public Mono<String> getApprovalKeyFromKis() {

        Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("grant_type", "client_credentials");
        bodyMap.put("appkey", appKey);
        bodyMap.put("secretkey", appSecretKey);

        String fullUrl = baseUrl + "/oauth2/Approval"; // 호스트와 경로를 조합
        return webClient.post() // post로 요청
                .uri(fullUrl) // 전체 URL을 명시적으로 지정
                .contentType(MediaType.APPLICATION_JSON) // Content-Type: application/json
                .body(BodyInserters.fromValue(bodyMap)) // json 형식으로 변환해서 응답 바디에 넣음
                .retrieve() // 요청하고 응답받음
                .bodyToMono(String.class); // 바디를 MONO 타입으로 변환
    }

}

2. ApprovalKeyController 클래스

클라이언트 쪽에서 "localhost:8080/approval"로 요청을 보내면, KIS에 접근하기 위한 ApprovalKey를 반환하는 컨트롤러이다.

@RestController
@RequestMapping("/approval")
@RequiredArgsConstructor
public class ApprovalKeyController {

    @Autowired
    private final KisService kisService;

    @GetMapping("/")
    @Operation(
            summary = "get Kis Approval Key",
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "Successful operation",
                            content = @Content(
                                    mediaType = "application/json",
                                    schema = @Schema(implementation = SuccessResponse.class)
                            )
                    ),
                    @ApiResponse(
                            responseCode = "400",
                            description = "Bad request",
                            content = @Content(
                                    mediaType = MediaType.APPLICATION_JSON_VALUE,
                                    schema = @Schema(implementation = ErrorResponse.class)
                            )
                    ),
                    @ApiResponse(
                            responseCode = "401",
                            description = "Bad credentials",
                            content = @Content(
                                    mediaType = MediaType.APPLICATION_JSON_VALUE,
                                    schema = @Schema(implementation = ErrorResponse.class)
                            )
                    )
            }
    )
    public ResponseEntity<String> approvalKey() {
        Mono<String> approvalKey = kisService.getApprovalKeyFromKis();
        System.out.println(approvalKey.block());
        return ResponseEntity.ok().body(approvalKey.block());
    }
}

■ 배운것

1. Swagger

Swagger는 API 문서를 자동으로 구성하는 도구이다.
애플리케이션의 모든 End Point를 볼 수 있고, Postman 처럼 요청을 보내고 응답을 수신할 수 있다.

spring boot에서 Swagger를 사용하기 위해서는 다음의 과정을 거쳐야 한다.

  1. 의존성을 추가
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0'

  2. SwaggerConfig 클래스 생성

@Configuration
public class SwaggerConfig {
    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .components(new Components())
                .info(apiInfo());
    }

    private Info apiInfo() {
        return new Info()
                .title("API Test") // API의 제목
                .description("Swagger UI") // API에 대한 설명
                .version("1.0.0"); // API의 버전
    }
}
  1. API를 사용하는 컨트롤러 생성
    여기에 @Operation 어노테이션을 사용하여, 각 API에 대한 설명을 추가할 수 있다.
    @ApiResponses 어노테이션을 사용하면 응답 코드에 대한 정보를 나타낼 수도 있다.

2. git issue

git의 issue는 기능 개발, 버그 수정 등의 상황을 트래킹 하기 위한 장치이다.
이슈마다 번호가 있다.
커밋 로그 마지막에 #이슈번호 를 넣으면 자동으로 git issue에 연동이 된다.


3. application-dev.yml

개발에서만 필요한 환경 설정 정보들이다.
appkey 같이 git에서 트래킹 하지 말아야 할 정보들을 적는다.

application.yml에서 다음과 같이 작성하면 application-dev.yml을 자동으로 설정정보로 추가한다.

spring:
  profiles:
    active: dev

4. webclient

Spring WebClient는 웹으로 API를 호출하기 위해 사용되는 Http Client 모듈 중 하나이다.
Java에서 가장 많이 사용하는 Http Client는 RestTemplate이다. 하지만, Spring이 이제부터 WebClient 쓰라고 권장했다.

RestTemplate과 WebClient의 차이점은 통신방법이 RestTemplate은 Blocking방식이고, WebClient는 Non-Blocking방식이라는거다.

WebClient를 사용하기 위해서는 WebClientConfig 클래스를 작성해야 한다.
그래야 WebClient를 스프링 빈으로 등록해서 사용할 수 있다.

@Configuration
public class WebClientConfig {
    @Bean
    public WebClient webClient(WebClient.Builder builder) {
        return builder
                .build();
    }
}

그리고, 외부 API를 호출해야 하는 로직에서 다음과 같이 작성한다.

		// 요청 바디에 넣을 JSON 형식의 데이터를 저장할 Map
 		Map<String, String> bodyMap = new HashMap<>();
        bodyMap.put("grant_type", "client_credentials");
        bodyMap.put("appkey", appKey);
        bodyMap.put("secretkey", appSecretKey);

        String fullUrl = baseUrl + "/oauth2/Approval"; // 호스트와 경로를 조합
        return webClient.post() // post로 요청
                .uri(fullUrl) // 전체 URL을 명시적으로 지정
                .contentType(MediaType.APPLICATION_JSON) // Content-Type: application/json
                .body(BodyInserters.fromValue(bodyMap)) // json 형식으로 변환해서 응답 바디에 넣음
                .retrieve() // 요청하고 응답받음
                .bodyToMono(String.class); // 바디를 MONO 타입으로 변환

Mono는 Reactor 프로젝트에서 제공하는 Reactor 타입 중 하나로, 비동기 프로그래밍을 위한 단일 결과를 나타내는 클래스이다.
Mono는 한 개의 결과를 갖는데, 이 결과가 나타나면 스트림은 완료된다.
따라서 Mono는 0 또는 1개의 아이템을 발행한다.
Mono는 보통 단일 값이나 비동기 작업을 표현할 때 사용된다.

bodyToMono응답 본문을 주어진 타입의 Mono로 변환한다.
여기서는 문자열로 응답을 받기를 원하기 때문에 String.class를 인자로 전달.


5. @Value

@Value 어노테이션은 Spring Framework에서 주입(Dependency Injection)된 값을 가져오는데 사용된다.
이 어노테이션을 사용하면 Spring의 Environment에서 값을 가져오거나, Spring의 프로퍼티 파일(application.properties 또는 application.yml)에서 값을 읽을 수 있다.

@Autowired
    public KisService(WebClient webClient, @Value("${spring.kis-api.endpoint-url}") String baseUrl, @Value("${spring.kis-api.app-key}")String appKey, @Value("${spring.kis-api.app-secret-key}") String appSecretKey) {
        this.webClient = webClient;
        this.baseUrl = baseUrl;
        this.appKey = appKey;
        this.appSecretKey = appSecretKey;
    }

■ 오류

IllegalStateException

java.lang.IllegalStateException: Cannot resolve parameter names for constructor
오류 발생

해결: DTO에 @NoArgsConstructor 넣기
즉, 기본 생성자를 만들어줌

@ModelAttribute는 기본 생성자로 객체를 만들고 값을 set하는 방식이다.
따라서, DTO에 기본 생성자가 존재해야 @ModelAttribute를 사용할 수 있다.

https://leesungki.github.io/gatsby-java-study/

profile
개발자 지망생

0개의 댓글

관련 채용 정보