Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client implementation errror "Cannot deduce decoder" #10

Open
MichaelHornung opened this issue Jul 24, 2019 · 3 comments
Open

Client implementation errror "Cannot deduce decoder" #10

MichaelHornung opened this issue Jul 24, 2019 · 3 comments

Comments

@MichaelHornung
Copy link

MichaelHornung commented Jul 24, 2019

Hi,

i implemented this client:

package com.github.jarlakxen.drunk
import com.github.jarlakxen.drunk.GraphQLClient.GraphQLResponse
import org.scalatest.FlatSpec
import com.github.jarlakxen.drunk.circe.deriveByTypenameDecoder
import com.typesafe.scalalogging.LazyLogging
import de.salt.d4s.model.entities.{Delivery, DeliveryItem}
import io.circe._
import io.circe.generic.semiauto._
import sangria.macros._
import java.util.concurrent.TimeUnit.MILLISECONDS

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, ExecutionContext, Future, duration}


class GraphQLSoDelClientSpec extends FlatSpec with LazyLogging {

  implicit val deliveryDecoder: Decoder[Delivery] = deriveDecoder
  implicit val deliveryItemDecoder: Decoder[DeliveryItem] = deriveDecoder
  val duration = Duration(4000, MILLISECONDS)

  //case class DeliveryQuery(delivery: Delivery)
  type DeliveryQuery = Map[String, List[Delivery]]
  case class Pagination(offset: Int, size: Int)

  implicit val deliveryQueryDecoder: Decoder[DeliveryQuery] = deriveByTypenameDecoder()

  implicit val pagniationEncoder: Encoder[Pagination] = deriveEncoder
  val client = GraphQLClient(s"http://delivery-generator-mho.d4s.salt-solutions.de/graphql")
  implicit val ec = ExecutionContext.global

  "server" should "respond correctly to deliveryQuery" in {

    val query =
      graphql"""
               query{delivery( id: "4727")
               {
               docid
               docType
               system
               status
               items{itemid product quantity unit date}}
               }
    """

    val page1: GraphQLCursor[DeliveryQuery, Pagination] = client.query(query, Pagination(0, 10))
    val data: Future[GraphQLResponse[DeliveryQuery]] = page1.result

    val result = Await.result(data, duration)

    logger.debug(result.toString)
  }
}

Running i get this error:

Cannot deduce decoder. Missing __typename: DownField(data)
DecodingFailure(Cannot deduce decoder. Missing __typename, List(DownField(data)))

Can anyone help me to fix it?

@MichaelHornung
Copy link
Author

Any ideas? Would be happy to get this solved.

@remimi
Copy link

remimi commented Oct 1, 2019

Hello 👋

I know that i had this issue when my query order did not match my case class definition order.
For example :

query{delivery( id: "4727"){
    docid
    docType
    system
    status
}

The case class should be

case class Delivery(
    docid: String,
    docType: String,
    system: String,
    status: String
)

In the same exact order as you querying. At least i had this issue using drunk with auto decoder from circe.
Don't know if it can solve your problem

@paulpdaniels
Copy link

@MichaelHornung I'm assuming you have either found your answer or moved on but the issue is likely that you don't have anything declared for the discriminators. The implementation looks like this:

  /**
    * This a special [[io.circe.Decoder]] for decode a polymorphic JSON response using the __typename field.
    */
  def deriveByTypenameDecoder[T](discriminators: (String, Decoder[_ <: T])*) = new Decoder[T] {
    val discriminatorsMap = discriminators.toMap
    override def apply(c: HCursor) = c.downField(ast.TypenameFieldName).as[String] match {
      case Right(tpe) if discriminatorsMap.contains(tpe) =>
        discriminatorsMap(tpe)(c)
      case Right(tpe) =>
        Left(DecodingFailure(s"Cannot deduce decoder $tpe for ${ast.TypenameFieldName}", c.history))
      case _ =>
        Left(DecodingFailure(s"Cannot deduce decoder. Missing ${ast.TypenameFieldName}", c.history))
    }
  }

Meaning you need to supply the list of discriminators in order for it to be able to resolve which subtype you want

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants