ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Ktor] tailcard로 URL 파라미터 수집하기
    Ktor 2023. 1. 25. 22:53

    오브젝트 스토리지 api를 개발하면서 슬래시가 포함된 URL 경로를 하나의 파라미터로 수집해야 하는 상황이 생겼다.

     

    버킷 내 폴더(실제로 폴더는 아니지만 path형식으로 구분하므로 이 글에서만 폴더라고 지칭)가 있는 경우, path형식의 오브젝트 키를 파라미터로 수집해서 넘겨야하는데, 보통 URL 파라미터는 슬래시로 구분되어 path parameter를 사용해도 해당 엔드포인트에 매칭이 되지 않았다.

     

     

    예를들어 오브젝트 키가 one/two/three인 경우,

    get("/{objectKey}") {
        val objectKey = call.parameters["objectKey"]
    }

    그냥 path parameter를 쓸 경우 매칭되는 URL을 찾지 못해 예외가 발생한다.

     

     

    Ktor에서는 이런 상황을 해결하기 위해 tailcard문자를 지원한다.

    가변인자를 a... 이라고 표시하는 것과 비슷하게, tailcard문자를 쓰면 나머지 경로들까지 모두 해당 파라미터로 수집할 수 있다.

     

     

    사용예시는 다음과 같다.

    get("/{objectKey...}") {
    	val objectKey = call.parameters.getAll["objectKey"]
    }
    // objectKey: List<String>?

    objectKey뒤에 ...을 붙여서 나머지 모든 URL 경로를 수집한다.

    이 때는 call.parameters.getAll로 수집하고, 타입은 문자열 리스트가 된다.

    물론 인자가 한 개여도 정상 수집된다.

     

    그러나 내 경우, 수집해온 파라미터들을 다시 하나의 완성된 문자열로 만들어야 한다.

    여기까지만 하면 objectKey는 one, two, three가 담긴 리스트인데, 내가 원하는 결과는 one/two/three 문자열이다.

     

    따라서 다시 path형식으로 합쳐주는 과정이 필요하다. 코틀린의 문자열 메소드를 사용했다.

    get("/{objectKey...}") {
        val objectKeyList = call.parameters.getAll["objectKey"]
        val objectKey = objectKeyList.joinToString("/")
    }
    // result: one/two/three

    joinToString은 배열을 하나의 문자열로 합칠 때 사용하고, seperator, prefix, suffix를 지정할 수 있다.

    구분자에 슬래시를 지정했다.

     

    이렇게 하면 스토리지의 폴더구조에 상관없이 요청으로부터 오브젝트 키를 정확히 수집할 수 있다.

     


     

    추가로, 테일카드만 단독으로 쓸 경우 나머지 path에 관계없이 직전의 URL에 매칭시켜준다.

    예를들어 /user/{...} 은 /user, 그리고 /user/other/theOther 모두에 매칭된다.

     

    이는 와일드카드문자(*)과 미묘한 차이가 있다. 와일드카드를 쓸 경우

    /user/*은 /user/other/theOther과 매칭되지만 /user에는 매치되지 않는다.

    댓글

Designed by Tistory.