Skip to content

Instantly share code, notes, and snippets.

@seoh
Created July 2, 2021 12:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seoh/1665ce2e4b7221bc6e4d55ec67a0fbaa to your computer and use it in GitHub Desktop.
Save seoh/1665ce2e4b7221bc6e4d55ec67a0fbaa to your computer and use it in GitHub Desktop.
http4s 컴파일 에러

튜토리얼에 있는대로 간단하게 Ok(result.asJson)만 썼는데도 뭘 고쳐도 계속 에러가 나는 경우가 있다. 이 에러들 중 대부분은 value Ok in trait Statuses does not take parameters라는 메시지일텐데, http4s 튜토리얼을 따라하다보면 자주 만나는 에러 중 하나다. 상태(status)에 정보(body)만 담아서 클라이언트에게 반환을 하려는 경우에 이런 문제가 왜 생기는지 짚어보자.

이렇게 Ok()처럼 상태를 생성하고 싶을 때는 Status.apply가 호출될 것 같지만, 이런저런 변환을 통해 Entity를 생성하는 로직으로 흐르게 되고 그 과정에서 생성하기 위한 인코더(EntityEncoder) 정보를 필요로 하게 된다. 여기까지가 간단한 이유였고 소스를 살펴보자.

Entity를 생성하는 경우는 3가지가 있다.

// case 1.
apply(implicit F: Applicative[F]): F[Response[G]]

// case 2.
apply[A](body: A, headers: Header.ToRaw*)(implicit F: Applicative[F], w: EntityEncoder[G, A])

// case 3.
apply[A](body: G[A](implicit F: Monad[F],  w: EntityEncoder[G, A])

간단히 말해 반환할 바디가 없는 경우, 바디만 있는 경우, 바디와 헤더를 동시에 생성하는 경우이다. Entity를 생성하기 위해서 EntityEncoder라는 객체가 필요한데, 현재 컨텍스트에 없을 경우에 당연히 case 1로 가게 된다. 이 경우는 묵시적인 인자 외엔 받지 않는데 사용자가 정보를 넘겨줬으니 "인자를 받지 않습니다"라는 에러가 발생하게 된다. 보통은 서버에서 주고받는 정보의 단위는 JSON이며 http4s와 함께 JSON 라이브러리로 circe를 쓴다면 http4s-circe를 의존성에 추가하고 import org.http4s.circe._를 추가하면 EntityEncoder를 찾을 수 있게 되어 첫번째 문제가 해결된다.

튜토리얼대로 잘 따라했다면 다음 문제는 발생하지 않을 수 있지만 아니라면 .asJson이 result의 멤버가 아니라는 에러를 보게 된다. .asJson 자체가 circe에서 제공하는 편의기능이고 메소드를 통해 JSON 인코딩을 하게 되는 것이라 http4s와 직접적인 관계가 없어서 circe의 문서를 봐야하는데 http4s로 검색하다 발견하지 못하는 경우가 있다. circe의 기능이므로 import io.circe.syntax._를 추가하면 해결된다.

마지막으로 EntityEncoder를 찾아서 바디를 인코딩하려고 했고, 인코딩 방법은 JSON이라 .asJSON을 통해 circe로 인코딩하게까지는 해결이 되었는데 no implicit argument of type io.circe.Encoder[...]라는 에러가 발생할 수 있다. result의 타입이 어떻게 JSON으로 인코딩될지에 대한 방법이 컨텍스트에 없어서 생기는 문제라 Encoder를 선언해주면 된다. 직접 만들어주는 방법도 있지만, 간단한 데이터의 경우에는 import io.circe.generic.auto._를 통해 자동으로 Encoder를 생성하도록 만들어줄 수 있다.

@seoh
Copy link
Author

seoh commented Jul 2, 2021

위에서 언급된 ResponseResponseGenerator의 경우 현재 최신인 1.0.0-M23 기준으로 작성했습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment