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
Sangria appears to support Circe's auto derivation functions for marshalling
And just a FYI: I just figured out how to handle the Enum marshalling last Thursday ;)
Erik
@erikdstock
Right. It's definitely working as-is so I am hestitant to make any big changes
but also being driven mad by these interdependent types, the overloaded method signatures and our existing mix of usages - an unimplemented def here, an implicit val there
Erik
@erikdstock
Are there any known, relatively large open-source sangria schemas out there? Things that go beyond conference talk demo projects?
Erik
@erikdstock
Another thing that would be helpful is a concise explanation of when lazy/implicits are necessary, when fields need to be defined as a function, and best practices for breaking up schema definition across multiple files

From the docs:

In order to discover other GraphQL types, the macros use implicits. So if you derive interdependent types, make sure to make them implicitly available in the scope.

Is this in reference to something like a deriveObjectType[RequestService, HasBInside] where, due to the use of the derive macro, there is no reference to the B field in the file?

Erik
@erikdstock

Another case here about circular object types:

In some cases you need to define a GraphQL schema that contains recursive types or has circular references in the object graph. Sangria supports such schemas by allowing you to provide a no-arg function that creates ObjectType fields instead of an eager list of fields. ... In most cases you also need to define (at least one of) these types with lazy val.

Is there some general scala background knowledge here that would hint at why this is necessary? Perhaps something related to forward referencing?

Samuel
@DevFlex
anyone on here have experience with sangria-akka-streams? I cannot seem to get it to work. For that matter I was trying to import sangria.streaming.akkaStreams but akkaStreams implementation isn't even recognized. Is this still supported?
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
:(