Dgs Graphql 의 DgsDataFetchingEvniroment로 "type"이라는 필드명의 Enum 타입인 쿼리 인자를 받아오던 중이었다.
Any 타입으로 들어오게 되며 이를 String 타입으로 형변환 시키려고 했다.
val type = environment.parseRequest("type", String::class.java)
위의 parseRequest메소드 내부에는 아래 로직을 구현시켜 놓았다.
ObjectMapper를 이용하였고 type 필드가 String 타입에 속하는것을 사전에 디버깅하여 확인했기 때문에 아래 로직을 탈 것이라고 생각했다.
val mapper = getObjectMapper(strategy)
return when (this) {
is String -> mapper.readValue(this, javaClass)
...
}
그리고 내뿜는 에러
Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'RETAIL': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (String)"RETAIL"; line: 1, column: 7]
"type" 필드 이외에 "id"라는 필드도 DgsDataFetchingEvniroment로 받아 Int 타입으로 변환하는 것에 성공하였는데 "type"필드 형변환시에만 에러가 났다.
에러 전문을 다시 읽어보고 해석하면 다음과 같다.
... was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
JSON String, Number, Array, Object or null, boolean 값만 허용한다는 뜻인 듯 하다.
즉, ObjectMapper의 readValue 메서드는 JSON형식의 String만 변환이 가능하고 그냥 String은 인자로 넣을 경우 에러가 발생한다.
따라서 아래처럼 해당 인자를 JSON 형식으로 변환해주면 ObjectMapper.readValue 메소드를 사용할 수 있다.
근데 그러면 왜 동일하게 String 타입에 속하던 "id"필드는 JSON 형식으로 변환하지 않아도 ObjectMapper.readValue 메서드를 탈 수 있었을까?
해당 로직을 찾는데는 실패했지만 예상컨데, "id" 필드는 값이 "11" 이었기 때문에 ObejctMapper.readValue() 메서드 내에서 Number로 자동 형변환 하여 처리하는 것이 아닐까 싶다.
결론: String 타입인 객체는 ObjectMapper의 readValue를 사용할 수 없다. 대신 JSON String 형식으로 변환시켜주면 사용이 가능하다. 그리고 String 타입이더라도 "11" 처럼 실제 내용이 숫자인 경우는 예외로 readValue 사용이 가능하다.
대만 놀러왔는데 졸려 죽겠다..
'개발' 카테고리의 다른 글
Terraform의 init/plan/apply (0) | 2023.12.12 |
---|---|
GraphQL 라이브러리 비교(kickstart/netflix-dgs/graphql-kotlin) (0) | 2022.08.11 |