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
@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
@DandyDev
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
@DandyDev
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
Erik
@erikdstock
So sangria's generated schema.graphql does not include the declaration scalar Long even though a special Long type is built in to the library. This breaks stitching into other schemas without manually adding a scalar Long after the fact. Is there a way to make sure this is included? I tried ham-fistedly adding it as a public member in my schema definition with simply val ImportedLong = sangria.schema.LongType but this doesn't change the output.
Erik
@erikdstock
My current approach is to do this in my writeSchema task:
object SchemaWriter extends App {
  implicit val ec = scala.concurrent.ExecutionContext.global

  val renderedStr = SchemaRenderer.renderSchema(SchemaDefinition().schema)
  val fileName = "src/main/resources/rendered.graphql"
  val pw = new PrintWriter(new File(fileName))
  pw.write("""
      |# Type not included by sangria's SchemaRenderer
      |scalar Long
      |
      |""".stripMargin)
  pw.write(renderedStr)
  pw.close()

  println(s"GraphQL SDL file written to `$fileName`.")
}
mynameistechie
@mynameistechie

Hiring Alert

Hey All,
We're hiring for Java Developer with GraphQL at Dallas,TX.If you're interested do connect with me to know more about this opportunity https://www.linkedin.com/in/karnala-harish-harry/ ASAP
(Sorry if this post not allowed but i want to help jobseekers)
André Schmidt
@ASchmidt84

I have a problem with en Enum (by enumeratum) and the graphql EnumType. The problem is on a mutation query. An Argument is a class Manager with contains an Enum. Always get an error:

Argument 'manager' has invalid value: At path '/role': error.sealed.trait (line 2, column 55):\n    addManager (vendorNumber: $vendorNumber, manager: $manager)

At role the Enum DefaultRoles is sitting.
I have an encode and a decoder:

implicit val ChargeTypeEncoder: Encoder[DefaultRoles] = new Encoder[DefaultRoles] {
    override def apply(enum: DefaultRoles): Json = stringEncoder.apply(enum.entryName)
  }

  implicit val ChargeTypeDecoder: Decoder[DefaultRoles] = new Decoder[DefaultRoles] {
    final def apply(c: HCursor): Result[DefaultRoles] = stringDecoder.apply(c).flatMap { s =>
      val maybeMember = DefaultRoles.withNameOption(s)
      maybeMember match {
        case Some(member) => Right(member)
        case _ => Left(DecodingFailure(s"$s' is not a member of enum $DefaultRolesType", c.history))
      }
    }
  }
André Schmidt
@ASchmidt84
I found out the problem is not at the marshalling. I have a mutation trait with an argument Manager. But I getting still this error: Argument 'manager' has invalid value: At path '/role': error.sealed.trait (line 2, column 55):\n addManager (vendorNumber: $vendorNumber, manager: $manager)
Encoding and decoding works fine!
val MutationType = deriveContextObjectType[FulfillerGraphQLSecureContext,FulfillerGraphQLMutation,Unit](_.mutation)

  val FulfillerSchema = Schema(Query,Some(MutationType))
This ist my schema and my trait has this method: @GraphQLField def addManager(vendorNumber: String, manager: Manager): Future[FulfillerView]
André Schmidt
@ASchmidt84
It seemes that the enumtype is not recognize as valid inputtype
André Schmidt
@ASchmidt84
Okay for all who running in same issue. The problem is very simple. It is the JSON dervied.oformat() which makes a object. But in graphql it is a string. To correct this, refactor it and create a dedicated way with JSON and graphql convertig let works fine.
implicit val defaultRolesWrites: Writes[DefaultRoles] = {r => Json.toJson(r.name) }
  implicit val defaultRolesReads: Reads[DefaultRoles] = Reads{
    case JsString(j) =>
      DefaultRoles.withNameInsensitiveOption(j).map{r => JsSuccess(r)}.getOrElse(JsError("String value not accepted"))
    case _ => JsError("String value expected")
  }
  implicit val defaultRolesFormat: Format[DefaultRoles] = Format(defaultRolesReads,defaultRolesWrites)
  implicit val DefaultRolesType = new schema.EnumType[DefaultRoles](
    name = "DefaultRoles",
    description = Some("A enum role type. Describes a special role"),
    values = List(
      schema.EnumValue[DefaultRoles](
        name = "FulfillerPresidentRole",
        description = Some("Fulfiller president role - means owner of the fulfiller"),
        value = DefaultRoles.FulfillerPresidentRole
      ),
      schema.EnumValue(
        name = "FulfillerCEOManagerRole",
        description = Some("Fulfiller CEO role"),
        value = DefaultRoles.FulfillerCEOManagerRole
      ),
      schema.EnumValue(
        name = "FulfillerArticleManagerRole",
        description = Some("Fulfiller article manager role - only responsible for articles of the fulfiller"),
        value = DefaultRoles.FulfillerArticleManagerRole
      ),
      schema.EnumValue(
        name = "FulfillerInvoiceManagerRole",
        description = Some("Fulfiller invoice manager role - only responsible for invoice and all relating topics"),
        value = DefaultRoles.FulfillerInvoiceManagerRole
      ),
      schema.EnumValue(
        name = "UserRole",
        description = Some("Simple user role"),
        value = DefaultRoles.UserRole
      )
    )
  ){
    override def coerceUserInput(value: Any): Either[Violation, (DefaultRoles, Boolean)] = value match {
      case valueName: String =>
        DefaultRoles.values
          .find(_.getClass.getSimpleName.startsWith(valueName))
          .map(r => Right(r -> false))
          .getOrElse(
            DefaultRoles
              .withNameInsensitiveOption(valueName)
              .map(r => Right(r -> false))
              .getOrElse( Left(EnumValueCoercionViolation(valueName, name, values.map(_.name)) ) )
          )

      //        Right(FulfillerCEOManagerRole -> false)
      //        DefaultRoles.withNameInsensitiveOption(valueName).map(r => Right(r -> false)).getOrElse( Left(EnumValueCoercionViolation(valueName, name, values.map(_.name)) ) )
      //      case v if byValue exists (_._1 == v) => Right(v.asInstanceOf[T] -> byValue(v.asInstanceOf[T]).deprecationReason.isDefined)
      case _ => Left(EnumCoercionViolation)
    }

    override def coerceInput(value: ast.Value): Either[Violation, (DefaultRoles, Boolean)] = value match {
      case ast.EnumValue(valueName, _, _) =>
        DefaultRoles.values
          .find(_.getClass.getSimpleName.startsWith(valueName))
          .map(r => Right(r -> false))
          .getOrElse(
            DefaultRoles
              .withNameInsensitiveOption(valueName)
              .map(r => Right(r -> false))
              .getOrElse( Left(EnumValueCoercionViolation(valueName, name, values.map(_.name)) ) )
          )
      case _ => Left(EnumCoercionViolation)
    }

    override def coerceOutput(value: DefaultRoles): String = value.name
  }
Anas H. Albarghouthy (Anas Barg)
@anasbarg

Hi, I have this code

val sangriaSchema =
    Schema.buildFromAst(apiSchemaGenerator.buildApiSchemaAsDocument)

val violations = QueryValidator.default
      .validateQuery(sangriaSchema, query)
      .toList

The problem is that violation is always an empty list, even when there are violations in the query.

Dan Di Spaltro
@dispalt
@schleumer did you ever figure out that bug with PossibleObject in 2.13?
Horacio
@krabbit93
Hello, I have tried to create a custom NonEmptyListInputType, but i can't yet. I tried using a custom ValidationRule, How can make that?
Pawel
@odwrotnie
Hello!
Are you able to connect Sangria to existing database with auto schema generation?
Ririshi
@Ririshi
Hi everyone, I'm totally new to both Scala and Sangria, and I'm using Sangria in a Play application to create a GraphQL API for our frontend to interface with. I'm using MongoDB as our data storage and am a bit stuck on creating relationships between different models. I currently have a Story case class and an Author case class, and created simple queries for both models to add, find, and update some documents in the MongoDB database. My issue now is with the ability to subquery the author of a story, or the stories written by an author...
Ririshi
@Ririshi

I tried following this tutorial:
https://medium.com/@toxicafunk/graphql-subqueries-with-sangria-735b13b0cfff

But the ids.flatMap(id => ctx.execution.course(id)) part gives me an error that the overloaded flatMap cannot be resolved. I'm using reactivemongo.api.bson.BSONObjectID as Id type, and it seems like there is no flatMap available for a Seq[BSONObjectID]

Greg Fisher
@gnfisher
Hello, it appears that deriveObjectType would convert a Left(error) into a 500 response? Is that accurate?