Where communities thrive

  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
Repo info
@yanns Update: I created a workaround to the sangria-circe issues in 905, by engaging in some "ImplicitLaundering" by grabbing the implicit in another class which has the import of io.circe.generic.auto and then using that implicit in another class. The bug still persists, but I was able to unblock myself on that front. I essentially have the following code .... but replace fiA with about 100 or so FromInputs for actual GraphQL classes.
case class A(text: String)
object A{
  implicit val _it: InputObjectType[A] = deriveInputObjectType[A]()
// This is a hack to workaround https://github.com/sangria-graphql/sangria/issues/905
object ImplicitLaundering{
  // grab the implicits from `io.circe.generic.auto`
  object Generate {
    import io.circe.generic.auto.*
    def getFI[T]()(implicit t:FromInput[T]): FromInput[T] = t

    def fiA = getFI[A]()

  // Make implicits available with `import ImplicitLaundering.Implicits.*` but without `import io.circe.generic.auto.*`
  object Implicits {
    import Generate.*
    implicit val _fiA: FromInput[A] = fiA

My server now:
1) SUCCESS: starts, and successfully returns the Schema (introspection).
2) SUCCESS: Processes input, runs my backend code, and then...
3) FAIL: Fails to generate the output on several endpoints, using various ObjectTypes.

"class scala.concurrent.impl.Promise$DefaultPromise cannot be cast to class ai.tagr.graphql.tagr.schema.types.UserGql (scala.concurrent.impl.Promise$DefaultPromise and ai.tagr.graphql.tagr.schema.types.UserGql are in unnamed module of loader 'app') 
java.lang.ClassCastException: class scala.concurrent.impl.Promise$DefaultPromise cannot be cast to class ai.tagr.graphql.tagr.schema.types.UserGql (scala.concurrent.impl.Promise$DefaultPromise and ai.tagr.graphql.tagr.schema.types.UserGql are in unnamed module of loader 'app') 

I'm not really sure what this error means. However, in this example, UserGql is a fairly basic return/output ObjectType and I get the same error on my other endpoints.

Same error, with a very simplified endpoint:
    def ping(in: String): Future[String] = {
      implicit val ec: scala.concurrent.ExecutionContext = scala.concurrent.ExecutionContext.global
I created a ticket for the above:
Yann Simon
yes it looks like the issue I had on https://github.com/sangria-graphql/sangria/issues/905#issuecomment-1229833443 where the wrong implicit is searched for.

Issue 905 and 906 look very different. 905 is an implicit resolution issue or conflict with io.circe , which causes compiler errors. 906 appears to be Sangria getting confused about how to render a Future[???] even with simple types like String

(Although as someone not familiar with the code, I guess it's technically possible they could be related, just seems unlikely)

I decided to do a workaround for #906, swapping all endpoints returning Future[T] to just return T instead. I don't know what the performance difference is, but I'm still months away from dealing with any notable traffic. Once 905 and 906 are fixed, I'll remove my workarounds. Anyway, I appear to have a working GraphQL server in Scala 3, and will use the Scala 3 branch as "master." I'll report any other bugs I run into if any.
Yann Simon
thanks for your patience, and congrats about being the 1st one to use AFAIK!
Thanks! I'm currently not blocked, and rolling forward with other feature development. I'll revisit cleanup of the workarounds on my project later, after 905 and 906 are fixed. There were a couple other minor issues I ran into around io.circe but they were easy to workaround and not caused by Sangria.
Guillaume Forgeon

Hi everybody!
I am facing a "problem" with Sangria (I'm new to it AND to Scala so maybe my problem is due to my lack of knowledge !).
If someone can help me... i'm kinda despesperated :)

So here it is:

  • I have a fetcher 'A' which returns a list of ids
  • I have another fetcher 'B' which needs the list of ids returned by the fetcher 'A' and returns a list of 'EntityB'
  • I have a field whose type id a Option[Connection[EntityB]]
  • Then, for now I have something like this in my resolver:
              .map(entitiesFromA => {
                ).map {
                  case Nil => None
                  case entitiesB =>
                        SliceInfo(sliceStart = offet, size = offset + entitesB.size)

Of course, it doesn't work. Compiler needs a Option[Connection[EntityB]] and it gets a DeferredValue[Nothing, Option[Connection[EntityB]]].
I think my problem comes from the nested fetcher calls + Connection stuff. I don't really know how to do.
If someone has an idea, do not hesitate to tell me.
Thank you!

Yann Simon

From what I understand:

  • FetcherA takes one ID and returns a list of IDs
  • FetcherB can return a list of EntityB based on the previous list of IDs

I'm not very used to use Fetchers, but I think that fetcherA could be a Relation[..., ID] and used like:

Fetchers.fetcherB.deferRelSeq(Fetchers.fetcherA, ctx.value.id)
Yann Simon
If people have interest using a sangria server with GraphQL federation: https://sangria-graphql.github.io/learn/#graphql-federation
Yann Simon
Sangria now officially supports GraphQL Federation: https://github.com/apollographql/apollo-federation-subgraph-compatibility#scala
Alexandre Lebrun

I would like to upgrade a project to Sangria 3, and this project uses sangria-relay module.
By looking at https://github.com/sangria-graphql/sangria-relay, I can see that the project is regularly updated (e.g. scala-steward updates).
However, I don't see any new release in Maven or GitHub. I am missing something ?

Thanks in advance :)

Yann Simon
Hi @xela85 . You should still be able to upgrade the sangria version.
But I'll cut a release soon to have all dep updated.
Yann Simon
Do you need scala 3 support?
Marty Phee

Looking for some direction. Learning and haven't seen examples.

I'm prototyping a GraphQL service for our platform data.
gRPC to Platform Services returngin Protobuf -> mapping to case classes -> serving over GraphQL

I tried deriveObjectType directly with the Protobuf and that had its own challenges.

So now I'm trying to mapping to case classes and I have a number of case classes with a bunch of Option fields


case class Policy(
    policyId: UUID,
    cancelEffectiveTime: Option[Instant] = None,
    cancelledBy: Option[PolicyAction] = None,
    carrier: Option[Carrier] = None,
    renewal: Option[Renewal] = None,
    underwritingCriteria: Option[UnderwritingCriteria] = None

I'm wondering the best way to define these for the schema

I've done

private val policyType = deriveObjectType[PlatformRepo, Policy]()

But get errors like

Can't find suitable GraphQL output type for Option[zego.controlpanel.domain.Renewal]. If you have defined it already, please consider making it implicit and ensure that it's available in the scope.

Which I'm then trying

  private val policyType = deriveObjectType[PlatformRepo, Policy](
        resolve = ctx => ctx.value.carrier

Is this the proper/best way to define Option(s) the schema? It works.
I'm going to have a number of case classes with Option fields and want to find the most efficient way of mapping them.

Yann Simon
no, you can keep private val policyType = deriveObjectType[PlatformRepo, Policy]()
and add some implicits, like private implicit val carrierType: ObjectType[PlatformRepo, Carrier] = ... so that deriveObjectType[PlatformRepo, Policy]() can use it.
otherwise deriveObjectType[PlatformRepo, Policy]() does not know how to expose your domain classes (like Carrier, PolicyAction...) to the GraphQL schema.
Yann Simon
I hope this helps.
Marty Phee
Thank you. That's what I kind of suspected. Just wanted to know if I was missing something. Thank you
Paul Sayre
I've been working with Fetcher and Deferred's. Is there something similar to what Future has with Await.result() for getting a value out of a Deferred? I'm not talking about DeferredValue().map(), because that still wraps the transformed results with a Deferred. More like Option().get, which gives you the value.
Yann Simon
Not that I know. Do you need that for testing purposes?
If this API would exist, it would be blocking, and users might use it on production code, leading the scalability issues.
The DeferredResolver returns Future that you can await. Does this help?
Paul Sayre
That could work. I have a DeferredResolver from DeferredResolver.fetchers(). But it looks like the .resolve() needs a queryState, which is an Any, but is converted to a FetcherCache. I can't figure out where to get that cache from. From what I can tell, FetcherConfig can give an empty cache, but not one that has been populated by previous fetches.
Hey, noticed that the sangria-federated project is getting some more frequent updates. Is the community looking at achieving Federation 2.x level support so it can work with the Apollo Router? Was concern moving to Caliban was required for us to start supporting the router.
Yann Simon
@pauls-ai2 Can you maybe give more info about what you are trying to do? Is it for testing?
@rney-lookout yes, we are actively working on it, and we want to go to production with that. You're welcome to join the fun, and provide any feedback on the library.
We're also working closely with Apollo, leading to https://github.com/apollographql/apollo-federation-subgraph-compatibility#scala
In our prototype, we can use sangria for a Federation v2 subgraph that we use from the router.
Paul Sayre

@yanns, no, it's not for testing. This is for production.

My project is for an Academic Research website (think Google Scholar). At the core, we have Paper's and Author's. A Paper can have many Author's, and an Author can have many Paper's.

In one place, I'm trying to return a Connection[Author] for a Paper. To do this, I need to:
0) Look up a Paper from a Fetcher (sets value of context.value)
1) Fetch the author IDs for the Paper (returns a Future)
2) Take a slice of those author IDs to create a page of IDs
3) Fetch the Author's with those IDs from a Fetcher (returns a Deferred)
4) Return a Connection[Author] (or Future[*], Deferred[*]...don't care since sangria can handle either)

So I have a mix of Future's and Deferred's. Since my team has experience in Future's, I was trying to get the code to rely more on those than on Deferred (which would be unique to this part of the code). Ideally, I'd like to be able to reuse the Fetcher's such that I can get records as intermediaries, and still have them cache (think CoAuthors using a Paper as an edge in the graph).

Yann Simon
My approach: I try to code everything with Future. I keep the sangria code very thin, only calling other implementations.
I don't see Deferred as Future. Deferred is a marker for a value that should be resolved by a Fetcher or DeferredResolver.
Using a Deferred does not do anything unless it's resolved.
Using a Future triggers the computation of the value (with side-effect). So it's quite different.
Hi, is it possible for sangria to derive an ADT (sum type) ? i can't find anything in the docs
Yann Simon
not sure about this. deriveEnumType seems to support ADT: https://github.com/sangria-graphql/sangria/blob/main/modules/derivation/src/test/scala/sangria/macros/derive/DeriveEnumTypeMacroSpec.scala but I'm not sure if it's what you are looking for.
Josh Kapple
Does Sangria limit the size of the request body? If so, how would one increase that limit to allow for larger objects to be sent?
Yann Simon
Sangria does not take care of serializing/deserializing the HTTP request body. Depending on the http library you are using, you should be able to configure that limit with it.
Yurii Vasylenko
Hi, does Sangria have an option to build type safe graphql queries and send them to "other project" api or any integrations with existing http clients?
Yann Simon
Are you looking for something like https://github.com/muuki88/sbt-graphql ?
Yurii Vasylenko