Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
kamisama-rney
@kamisama-rney
@erikdstock lazy and implicit declarations are common Scala. A lazy variable declaration is one that isn't initialized until it's accessed the first time during runtime. This gets around the compiler errors when a variable declaration isn't found. That's why they are recommending you use lazy on at least one variable when you have a circular reference.
kamisama-rney
@kamisama-rney

@erikdstock As for implicit this declares something that is searchable within package scopes by the compiler. If you're using the deriveObjectType[Context, Object] that's using compiler-time reflection. So if you have nested objects within a parent object you should have code that declares those types above and as implicit

object ParentType {
  def apply[F[_]: Effect]: ObjectType[MasterRepo[F], Parent] = {

    implicit val entryType: ObjectType[MasterRepo[F], Entry] = deriveObjectType[MasterRepo[F], Entry]
    implicit val itemType: ObjectType[MasterRepo[F], Item] = deriveObjectType[MasterRepo[F], Item]

    ObjectType(
      "Parent",
      () =>
        fields[MasterRepo[F], Parent](
          Field(
            "entries",
            ListType(itemType),
            resolve = _.value.entries
          )
        )
    )
  }
}

The implicit items at the top are located by the compiler when the Parent object is realized

Erik
@erikdstock

Thanks @kamisama-rney - i think I understand that much, with the exception of how the implicit keyword actually works. Example: a lazy val is a different object than a val, but implicit is just a flag. Minimal example:

trait CartTypes {
  val itemType: ObjectType[RequestServices, Item]
  lazy val cartType: ObjectType[Unit, Cart] = ObjectType[RequestServices, Cart](
  /* ... */
    fields = Field(
      "items",
      ListType(ItemType),
      resolve = c => c.ctx.getItems(c.value.id)
    )
  )
}

trait ItemTypes {
  implicit val cartType: ObjectType[RequestServices, ShoppingCart]
  lazy val itemType =  deriveObjectType[RequestServices, Item]()
}

case class Schema()(implicit val ec: ExecutionContextExecutor) extends CartTypes with ItemTypes {
  val QueryType = ObjectType(
    "Query",
    fields[RequestServices, Unit]( /* the types are used */ )
  )
}

My impression from the above is that

  • For CartTypes and ItemTypes, the lazy vals are due to interdependence on each other
  • val itemType: ObjectType[RequestServices, Item] means the member is necessary to be implemented in the concrete Schema implementation (straightforward)
  • implicit val cartType: ObjectType[RequestServices, ShoppingCart]does the same but adds an additional flag to the compiler to make this val available within the deriveObjectType macro. This is because we don't refer to it directly as with an ObjectType literal. The ItemTypes is allowed to make its implemented cartType implicit.

Is this all correct? I think part of my confusion was on lazy vs implicit and when the name bound to the variable needs to match (vs just the type). I realize some of this is just scala basics :/

Erik
@erikdstock
I guess maybe there is also an implicit val ec: ExecutionContextExecutor in the CartTypes(in my actual use case due to the our RequestServices implementation)
kamisama-rney
@kamisama-rney
Here's a nice series on Scala implicits - http://baddotrobot.com/blog/2015/07/03/scala-implicit-parameters/
Erik
@erikdstock
yes, i have read many articles on scala implicits but have a lot of holes in my understanding still
is my example above about when lazy vals and implicits are necessary broadly correct?
Jakub Kozłowski
@kubukoz
Hi, is it possible to generate object types for functions in a trait that require some context values? Example coming...
final case class Thing(name: String)
implicit val objectTypeThing = deriveObjectType[SecureContext,Thing]()

trait MyMutationWithContext {
  @GraphQLField
  def createThing(
    // ctx: User,
      name: String
  ): Future[Option[Thing]]
}
val myMutationType =
  deriveContextObjectType[SecureContext, MyMutationWithContext, Unit](_ => (??? : MyMutationWithContext))
this part compiles, but it stops compiling when I uncomment User - I'm new to this and don't really see a way to get that to work (I tried all the derivation methods)
Having SecureContext instead of User in there would be fine too
or should I just give up and write the field for that method manually?
Jakub Kozłowski
@kubukoz
I guess I'm looking for something that'll give me an InputType that takes something from the context...
hmm, maybe I don't need it after all - my MyMutationWithContext will be a field of the context already, which implies I can pass a user (which is a field in the context) at construction time
Rex Sheridan
@rex-sheridan
Looks like https://sangria-graphql.org/ is down
kamisama-rney
@kamisama-rney
Looks like the domain name expired July 28th, 2020
Domain name: sangria-graphql.org
Registry Domain ID: D176971954-LROR
Registrar WHOIS Server: whois.namecheap.com
Registrar URL: http://www.namecheap.com
Updated Date: 2018-09-25T18:52:13.00Z
Creation Date: 2015-07-28T21:48:18.00Z
Registrar Registration Expiration Date: 2020-07-28T21:48:18.00Z
kamisama-rney
@kamisama-rney
@here Anyone that controls the sangria-graphql.org domain monitoring this channel anymore?
James Lawrie
@jlawrienyt
I'm not sure what the latest is, but you can follow this issue for updates I believe: sangria-graphql/sangria-website#74
kamisama-rney
@kamisama-rney
@jlawrienyt thanks for the redirect to the issue in github. Reading the thread it follows what I was theorizing last night while talking to a co-worker. The community is having difficulty getting control over the domain due to Oleg's passing last year. It was really sad reading that news.
Daan Debie
@DonDebonair
Hey folks! I'm building a project with Sangria, and I'm trying to also add cursor-based pagination, but I'm struggling with the following: can I reuse the result of one resolver in the other without getting data from the database twice?
I have the following code:
val QueryType = ObjectType(
    "Query",
    fields[MyContext, Unit](
      Field(
        "CSO",
        ListType(FlightOverviewType),
        arguments = List(
          Argument("showCancelled", BooleanType, defaultValue = false),
          Argument("first", IntType, defaultValue = 9999999), // TODO how to make this optional?
          Argument("before", StringType, defaultValue = "encoded flight leg key"),
          Argument("after", StringType, defaultValue = "encoded flight leg key")
        ),
        resolve = c => {
          c.ctx
            .dao
            .getFlightOverviewWithUserInputs(
              c.arg[Boolean]("showCancelled"),
              Some(c.arg[Int]("first")),
              Some(c.arg[String]("before")),
              Some(c.arg[String]("after"))
            )
            .getOrElse(Future(Seq.empty))
        }
      ),
      Field(
        "pageInfo",
        PageInfoType,
        resolve = c => ??? // want to use the result of getFlightOverviewWithUserInputs
      )
    )
  )
I'm struggling with the resolver for pageInfo. The information needed to construct pageInfo is all there in the CSO
Daan Debie
@DonDebonair
Nevermind, I found the solution already. pageInfo should be part of the CSO field/object
so we need only one resolver
Erik
@erikdstock
Hello folks, I'm back with more questions, this time about creating some relay connection definitions using sangria-relay.
Erik
@erikdstock
In short, I'm wondering if anyone has tips on using the library. The only example I've found for it is the playground file, and it doesn't seem to work for my purposes: https://github.com/sangria-graphql/sangria-relay-playground/blob/master/app/models/SchemaDefinition.scala
Reid Mewborne
@8bitreid
is sangria bring updated anymore ?
Erik
@erikdstock
This message was deleted

is sangria bring updated anymore ?

yes, i believe twitter announced an intent to continue supporting it, and there are folks here as well, but there are still big holes in the docs, sites including the playgrounds have gone down, etc

i figured out my immediate questions above
but am still struggling with how to define a schema that isn't in one gigantic file
Reid Mewborne
@8bitreid
Cool! Thanks!
Erik
@erikdstock
when defining an object, the docs often leave the context type parameter as Unit like ObjectType[Unit, User], but is there any real reason to do this? Perhaps for scalar values that have zero links to other parts of the schema but otherwise it seems like you would always want to give a context.
Erik
@erikdstock
Another question. Adding sangria-relay to my schema, I'd like to keep my ObjectType definitions colocated with their models, but they now require the relay helpers (idFields, nodeInterface etc) so they can be recognized as Node/PossibleNodeType, which uses an implicit conversion. However Node.definition() requires those types as well. Is it possible to define them in separate files, or do I need to give up and combine my objects into a single schema file?
Erik
@erikdstock

x-posting from the scala channel, which is more active and because I think this might just be an issue of how scala implicit conversions work:
In short, I have an ObjectType (from the plain sangria schema) that I need to pass as an arg of type PossibleNodeObject*. The relay PossibleNodeObject uses an implicit conversion, and basically requires that the ObjectType conform to a graphql relay interface. That part is working within the same file/trait but not via trait composition, because my shared relay code requires all of these ObjectTypes be passed to it. I've tried this in my relay types trait:

  type NodeType[C, V] = ObjectType[C, V] with PossibleNodeObject[C, Node]
  val UserType: NodeType[RequestServices, UserId]

which appears to work for that trait, but then when I actually define UserType (extending my RelayTypes) in another file I get "expected ObjectType PossibleNodeObject, found ObjectType". Am I trying to use an implicit conversion where it isn't actually possible?

Erik
@erikdstock
Another way to phrase this might be: Is there a type I can import from sangria-relay that encompasses an ObjectType that conforms to a Node type?
Kyle Florence
@solarmosaic-kflorence
what happened to the website? https://sangria-graphql.org/
Kyle Florence
@solarmosaic-kflorence
:(
Erik
@erikdstock
Domain being down aside, it feels like there is still a lot of work to do to simply document sangria. Is there any ticketed effort to do this?
Gabriel Harris-Rouquette
@gabizou
General question regarding field resolvers: In a cats + ccedi.dtrace + 47deg fetch, we're running into an issue that if a field level resolver throws any exception, we're not actually seeing the exception getting thrown out/bubbled up to the SangriaExecutor where even though the executor is wrapped in an IO and IO.attempt is called to draw it out as an Either, we still don't see the Left of the throwable. I'll be investing some time to make a small reproducible project to see if it's inherent to our setup, or whether it's something insidious in sangria itself, but just curious if any travel knowledge or "gotchas" are known or sound similar. Throwables in mutations are actually still logging and caught as far as I'm aware.
bengraygh
@bengraygh

Another way to phrase this might be: Is there a type I can import from sangria-relay that encompasses an ObjectType that conforms to a Node type?

I also have this problem. If you found a solution, I'm interested to hear it. Without defining everything in the same SchemaDefinition as one file, I get this problem.

André Schmidt
@ASchmidt84
HI. I have a question about a mutator. In the mutator I have an parameter. And if the submitter submit wrong data for the datatype (like two chars only lower case allowed an the submitter sends in uppercase or so) the error is very low like this {"name":"Exception","detail":""}
I have an deriveInputObjectType for my case class ADT. How I can offer a more detailed exception message for wrong parameters?
bengraygh
@bengraygh
Are you relying on the info coming to your client? You could see the exception thrown on the terminal of your JVM couldn't you? Or do you mean that you want more detail in the string given to the client?
André Schmidt
@ASchmidt84
I want a better exception description to the client
bengraygh
@bengraygh

I want a better exception description to the client

Ok, so you could define your own user facing error and pass that through to the client. The docs on the sangria site (which is down with a temporary mirror) show how to do this: https://sangria.netlify.app/learn/#custom-exceptionhandler

fjl716
@fjl716
Don't have access to https://sangria-graphql.org/
André Schmidt
@ASchmidt84
@bengraygh thank you. So i hope the docs will be on near