ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RestTemplate이란? - RestTemplate Hands On 1
    Spring Framework/RestTemplate 2023. 9. 20. 00:01

    개요

    평소에 RestTemplate이란 기술을 알고 있었지만 FeignClient를 주로 활용하여 활용하곤 했습니다.

     

    그러면 FeignClient를 더 학습하는게 좋을 텐데 굳이 RestTemplate을 학습하는 이유는 무엇일까요?

    • 다른 개발자들은 Feign을 활용하는 대신 RestTemplate을 더 선호할 수 있습니다.
    • RestTemplate을 활용하여 외부호출이 적용된 프로젝트들을 만날 수도 있습니다.

     

    RestTemplate을 활용하는 프로젝트를 만났기 때문에 이를 위해 공부해보고자 합니다.

    이전에 FeignClient, WebClient, RestTemplate에 대해 비교하며 정리한글도 첨부해봅니다.

     

    RestTemplate이란?

    RestTemplate은 spring 3.0부터 등장한 기능입니다.

    매우 간단하게 설명하자면 동기적인 HTTP 외부 요청을 할 때 사용하는 기술입니다.

     

    javadocs의 부분을 해석해 보면 다음과 같습니다.

    Synchorous(동기식) 클라이언트로 HTTP 요청을 수행하며 HttpUrlConnection 또는 HttpComponents 보다 고수준의 직관적인 API를 제공합니다.
    Spring 5.0부터 WebClient가 등장하면서 향후 버전에서는 더 이상 사용되지 않을 예정입니다.
    동시 수정을 지원하지 않아 필요시 서로 다르게 구성된 여러 개의 RestTemplate 인스턴스를 만들 수 있으며, 동일한 클라이언트 리소스를 공유해야 하는 경우 ClientHttpRequestFactory를 활용할 수 있습니다.

     

    이 부분이 잘 이해되지 않았는데 코드로 살펴보겠습니다.

     

    RestTemplate 생성하기

    val restTemplate = RestTemplate()

    Spring을 현재 사용 중이라면 별도의 의존성 없이 바로 선언할 수 있습니다.

    이 경우에는 기본적인 여러 설정들이 내부적으로 세팅됩니다.

     

    ClientHttpRequestFactory를 활용해서 생성할 수도 있습니다.

    	/**
    	 * Create a new instance of the {@link RestTemplate} based on the given {@link ClientHttpRequestFactory}.
    	 * @param requestFactory the HTTP request factory to use
    	 * @see org.springframework.http.client.SimpleClientHttpRequestFactory
    	 * @see org.springframework.http.client.HttpComponentsClientHttpRequestFactory
    	 */
    	public RestTemplate(ClientHttpRequestFactory requestFactory) {
    		this();
    		setRequestFactory(requestFactory);
    	}

    javaDoc을 읽어보면 새로운 RestTemplate 인스턴스를 생성하는데 ClientHttpRequestFactory에 기반하여 생성한다고 합니다.

     

    setRequestFactory 메서드

    //Set the request factory that this accessor uses for obtaining client request handles.
    //The default is a SimpleClientHttpRequestFactory based on the JDK's own HTTP libraries (java.net.HttpURLConnection).
    //Note that the standard JDK HTTP library does not support the HTTP PATCH method. Configure the Apache HttpComponents or OkHttp request factory to enable PATCH.
    	@Override
    	public void setRequestFactory(ClientHttpRequestFactory requestFactory) {
    		super.setRequestFactory(requestFactory);
    		this.interceptingRequestFactory = null;
    	}

    setRequestFactory 메서드는 InterceptingHttpAccessor클래스의 메서드이며 RestTeamplte이 InterceptingHttpAccessor 클래스를 상속받고 있습니다.

    기본적으로는 SimpleClientHttpRequestFactory가 사용된다고 합니다.

     

    SimpleClientHttpRequestFactory에서 기본값을 보면 다음과 같습니다.

    private static final int DEFAULT_CHUNK_SIZE = 4096;
    private boolean bufferRequestBody = true;
    private int chunkSize = DEFAULT_CHUNK_SIZE;
    private int connectTimeout = -1;
    private int readTimeout = -1;
    private boolean outputStreaming = true;

     

    connectTimeout 그리고 readTimeout이 -1으로 세팅되어 있습니다.

     

    prepareConnection을 보면 해당값이 0 이상인 경우에만 timeout 값을 세팅함을 알 수 있습니다.

    protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
    		if (this.connectTimeout >= 0) {
    			connection.setConnectTimeout(this.connectTimeout);
    		}
    		if (this.readTimeout >= 0) {
    			connection.setReadTimeout(this.readTimeout);
    		}
    
    		boolean mayWrite =
    				("POST".equals(httpMethod) || "PUT".equals(httpMethod) ||
    						"PATCH".equals(httpMethod) || "DELETE".equals(httpMethod));
    
    		connection.setDoInput(true);
    		connection.setInstanceFollowRedirects("GET".equals(httpMethod));
    		connection.setDoOutput(mayWrite);
    		connection.setRequestMethod(httpMethod);
    	}

     

     

    RestTemplate 생성 디버깅

    val restTemplate = RestTemplate()
    println(restTemplate.requestFactory)

    restTemplate의 requestFactory를 출력해 보면 SimpleClientHttpRequestFactory를 볼 수 있습니다.

    SimpleClientHttpRequestFactory은 어디서 주입될까 궁금하여 디버깅을 수행해 보았습니다.

     

     

    public RestTemplate() {
    	...
    }
    
    public abstract class HttpAccessor {
    	private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
    }

    RestTemplate을 생성하는 부분에서는 SimpleClientHttpRequestFactory를 찾을 수 없고, HttpAccesor의 필드를 보면 requestFactory의 기본값으로 SimpleClientHttpReqeustFactory를 생성해 주는 것을 볼 수 있습니다.

     

    RestTemplate이 InterceptingHttpAccessor를 상속받고 있으면 InterceptingHttpAccessor는 HttpAccesor를 상속받고 있기 때문에 RestTemplate에서도 requestFactory를 가질 수 있었습니다.

     

    마무리

    RestTemplate의 생성에 대해 알아보았는데 다음에는 조회(GET)에 대해서 알아보겠습니다.

     

     

     

     

     

    참고자료

    https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html

     

    RestTemplate (Spring Framework 6.0.11 API)

    postForLocation Create a new resource by POSTing the given object to the URI template, and returns the value of the Location header. This header typically indicates where the new resource is stored. URI Template variables are expanded using the given URI v

    docs.spring.io

     

    댓글

Designed by Tistory.