2carrot84
by 2carrot84
2 min read

Categories

  • development

Tags

  • spring
  • uri

회사에서 작업 중 URI 를 Map 의 Key, Value 로 동적으로 구성하는 코드를 작성하게 되었습니다.

별 생각없이 String 또는 StringBuffer 를 이용하여 코드를 작성 하였으나, 동료 개발자분의 코드 리뷰 후 깔끔해진 제 코드를 보고

내가 모르는 다양한 클래스들이 유용한 기능을 제공 해주고 있다는걸 또 한번 깨닫고 되도록 기록하기 위해 포스팅을 올립니다.

먼저 들어가기 앞서 간략하게 URI 란 무엇인지? 더 자주 접하는 용어인 URL 은 무엇인지 알아보도록 하겠습니다.

URI (Uniform Resource Identifier) 이란?

통합 자원 식별자는 인터넷에 있는 자원을 나타내는 유일한 주소이다.
URI 의 존재는 인터넷에서 요구되는 기본조건으로서 인터넷 프로토콜에 항상 붙어 다닌다. URI 의 하위개념으로 URL, URN 이 있다.

URL (Uniform Resource Locator)

네트워크 상에서 자원이 어디 있는지를 알려주기 위한 규약이다.
즉, 컴퓨터 네트워크와 검색 메커니즘에서의 위치를 지정하는, 웹 리소스에 대한 참조이다.
흔히 웹 사이트 주소로 알고 있지만, URL 은 웹 사이트 주소뿐만 아니라 컴퓨터 네트워크상의 자원을 모두 나타낼 수 있다.
그 주소에 접속하려면 해당 URL 에 맞는 프로토콜을 알아야 하고, 그와 동일한 프로토콜로 접속해야 한다.

URI 와 URL 의 차이에 대해서는 아래 그림과 링크를 보시면 이해에 도움이 될 것이라고 생각됩니다.

참고링크

참고그림

UriComponentBuilder

UriComponentBuilder 는 Spring Framework 5.3.14 API 부터 사용되었으며, URI 를 만드는데 약간의 편리함과 명확함을 제공해 준다고 생각됩니다.

기존에 제가 작성한 코드와 UriComponentBuilder 를 사용한 코드를 예로 들어 간략히 설명해 보겠습니다.

AS-IS 코드

    public String makeQueryString(Map parameterMap) {
        StringBuilder sb = new StringBuilder(this.httpUrl + "?1=1");
        parameterMap.forEach((k, v) -> sb.append("&").append(k).append("=").append(v));
        return sb.toString();
    }

TO-BE 코드

    public String makeQueryString(Map parameterMap) {
        UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(this.httpUrl);
        queryParameterMap.forEach((key, value) -> {uriComponentsBuilder.queryParam(key,value)});
        return uriComponentsBuilder.encode().toUriString();
    }

소스 양으로 봤을때 크게 차이가 없지만, 동적으로 Query String 을 만들때 제일 번거로운 ? 와 & 에 대한 고민을 하지 않아도 되는 점이 인상적이였습니다.

?, & 처리를 위한 불필요한 소스 없이 깔끔한 모습일 볼 수 있습니다.

추가로 타 블로그에서 본 예제 소스를 통해 명확성에 대한 장점을 보도록 하겠습니다.

AS-IS 코드

    @RequestMapping("/login/kakao")
    public void kakao(HttpServletResponse httpServletResponse) throws IOException {

        // 1안 String 사용
        String kakaoAuthUri = "https://kauth.kakao.com/oauth/authorize?client_id=insertYourId&redirect_uri=http://localhost:8080/oauth&response_type=code";
    
		// 2안 StringBuilder 사용
        StringBuilder sb = new StringBuilder();
        sb.append("https://");
        sb.append("kauth.kakao.com");
        sb.append("/oauth/authorize?");
        sb.append("client_id=insertYourId");
        sb.append("&");
        sb.append("redirect_uri=http://localhost:8080/oauth");
        sb.append("&");
        sb.append("response_type=code");
    
        httpServletResponse.sendRedirect(sb.toString());
    }

TO-BE 코드

    @RequestMapping("/login/kakao")
    public void kakao(HttpServletResponse httpServletResponse) throws IOException {

        UriComponents uriComponents = UriComponentsBuilder.newInstance()
        .scheme("https")
        .host("kauth.kakao.com")
        .path("/oauth/authorize")
        .queryParam("client_id", "Insert your Id")
        .queryParam("redirect_uri", "http://localhost:8080/oauth")
        .queryParam("response_type", "code")
        .build(true);
    
        httpServletResponse.sendRedirect(uriComponents.toString());
    }

URI 구성 요소

위와 같이 URI 구성 요소(위 이미지)에 대해 좀 더 명확하게 코드로 구분 지을 수 있고, 불필요한 기호들(://, ?, &, = 등)을 사용하지 않아도 되는 장점이 눈에 보입니다.

코드에 대한 고민이 점점 많아지면서 다른 사람이 봤을 때 명확하고, 깔끔하게 의도를 이해할 수 있는 코드가 좋은 코드가 아닐까 싶습니다.

그런 코드를 위해 이런 클래스를 찾아보고 사용하는 것도 좋은 방법이지 않나 생각한 하루였습니다.

그럼 이만. 🥕👋🏼🖐🏼

참고자료

https://velog.io/@jch9537/URI-URL https://mygumi.tistory.com/139
https://www.baeldung.com/spring-uricomponentsbuilder https://youngwonhan-family.tistory.com/71