Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Oliver Wetterau
@owetterau

Does anybody have an idea, why enums and Circe are failing with an "argument xyzzy has invalid value: CNil" error?

As far as I have followed it up, it seems that a case class containing an enum (whereas the enum has no quotes in GraphQL-JSON) is being read properly (including the enum), then being converted to a new JSON where the enum is treated as a string (with quotes) and it seems that it then shall be converted to a case class where it fails because the enum value is now being read with quotes and cannot be converted to an Enum. Unfortunately I don't know how to change that behavior.

I am using EnumType(...)and deriveInputObjectType[...] to create the schema.

Does it have to do with the issues you have been describing with Circe in the last posts?

Dan Di Spaltro
@dispalt
@nickhudkins well the actual issue is just how it all ties together. Like circe's decoders and encoders are not introspectable. so if you make a custom decoder/encoder in circe because you've renamed a field or something, the derivation for the input object wouldn't reflect that. It's not a bug per se, and nothing really sangria can do about it, it just limits the usefulness
Nick Hudkins
@nickhudkins
Yeah :( I was looking at it now, creating a bit of a test case
@dispalt the question I have is... can deriveInputObjectType, ensure that the proper (encoding / decoding) implicits are in scope along with the graphql type
Nick Hudkins
@nickhudkins
As time has gone on, I know many folks who maybe used to use Sangria, no longer do. I was curious if we could get a quick list of "Companies using Sangria at scale" If anyone here is using it in production at work (and you can share) I'd love to collect a list!
Yann Simon
@yanns
Hi, I gave a talk about GraphQL that you might find interesting: https://www.youtube.com/watch?v=Y4aP-ryulgQ&t=489s
Srepfler Srdan
@schrepfler
as any project, it would be good if there's a leadership with a clear roadmap ahead. What differentiates Sangria from the other implementations, what will keep it relevant in time etc.
Yann Simon
@yanns
@schrepfler I agree with you. As I wrote in https://github.com/sangria-graphql/sangria/issues/446#issuecomment-623075358, I'm not the one who can do it. I don't have enough time for this.
@nickhudkins invested a lot of time recently. Thanks to him! If you want to join, you are welcome.
Tim Rourke
@timrourke
is there a good way to deal with errors in sangria that doesn't involve throwing and catching exceptions? my server uses Either[SomeErrorType, SomeResourceType] to constrain the error channel and keep it typed, and there are some errors i would want to handily lazily instead of eagerly
(also totally unrelated to that, is there a sensible way to provide a query i am executing a database transaction? this would be especially important to me for mutation queries, because i need to treat writes as atomic and roll back a transaction if any one DB operation fails during a write. is this kind of use case even common in graphql-land?)
er, is the thing to do to provide a custom context of some kind?
Tim Rourke
@timrourke
ok, figured both of the above q's out
Tim Rourke
@timrourke
for anyone playing along at home, the solution is to define a custom context object containing whatever DAOs/repositories/thingies that get stuff from the DB. i feel a little icky sticking a live database transaction object into a case class as a field, but it works
and for serializing exceptions, you can implement a custom exception handler to extract relevant data for an exception thrown for a given field. would be nice to avoid throw but not a big deal at this external layer of the application
Nick Hudkins
@nickhudkins
Hey @timrourke you should checkout Alternative Execution Scheme https://sangria-graphql.github.io/learn/#alternative-execution-scheme
DeliveryScheme.Either will allow you to handle QUERY parsing as an Either as well. Hoping this helps point you into the "sangria" way to handle this
Nick Hudkins
@nickhudkins
as for your db question, the pattern I have used is to create an execution and mutation context that i put in... context. the context is created per HTTP request, providing a SHARED read connection for any DB executions and a unique transaction for any mutation. the connection itself is created per HTTP request as well, pulled from a pool. This lets me handle transaction rollback within a wcWrite function provided by a WithWriteConnection trait that wraps all of my DB operations and provides the transaction to be used, with any failures resulting in automatic rollback, or committing on success
Yann Simon
@yanns
Hi all. We will remove support for scala 2.11 and jvm < 1.8: https://github.com/sangria-graphql/sangria/issues/523#issuecomment-739152466
It's still time to react if you are impacted by this plan.
Binh Nguyen
@ngbinh
ok with it. There is not much excuse to not moving away from 2.11
Yann Simon
@yanns
Hi, if you want to help, you can open PR to use github actions instead of travis CI. We need that on all repositories.
I've migrated Sangria (sangria-graphql/sangria#547) and macro-visit (sangria-graphql/macro-visit#28 and https://github.com/sangria-graphql/macro-visit/pull/29)
Sagar Jadhav
@SagarJa07481451_twitter
Is there a way to not use case classes to model object types in sangria. Using Graphql-Java , we can externalize the schema and pass it at runtime. How can we achieve this in graphQL-scala?
Yann Simon
@yanns
It's possible to derive the GraphQL types from case classes, but it is also possible to write the GraphQL types per hand: https://sangria-graphql.github.io/learn/#schema-definition
Sagar Jadhav
@SagarJa07481451_twitter
@yanns I get "Schema was materialized and cannot be used for any queries except introspection queries." error when I parse it and try to execute.
Yann Simon
@yanns
Strange we are using this approach on production without any issues.
Sagar Jadhav
@SagarJa07481451_twitter
@yanns Can you please list down high level steps that you follow. Maybe I am missing some step.
Yann Simon
@yanns
@SagarJa07481451_twitter we are using the Executor.execute, like in https://github.com/sangria-graphql/sangria-akka-http-example/blob/master/src/main/scala/Server.scala#L33
Sagar Jadhav
@SagarJa07481451_twitter
@yanns This does not work for me. Are you also reading the schema from an external schema.graphql file ? In the above link, schema is not read from an external file. It is created through the code.
Dave Handy
@dave-handy
hi @yanns ! I see you are also working on migrating to github actions... have you tried publishing a new signed version yet? I'm having an issue with the action not seeing PGP_SECRET
Yann Simon
@yanns
@SagarJa07481451_twitter no I don't use an external schema file. Sorry I might have misunderstood you. I thought you want to avoid using the macro derivation to generate the GraphQL schema.
@dave-handy the publishing with github actions is disabled for now: sangria-graphql/macro-visit#29
This would requite much more work.
5 replies
Yann Simon
@yanns
https://github.com/sangria-graphql/sangria-slowlog is now using github actions & auto-formatting
Yann Simon
@yanns
same now for https://github.com/sangria-graphql/sangria-msgpack. If you want to help, you can have a look at the changed that were necessary, and apply them to other repositories.
Yann Simon
@yanns
Binh Nguyen
@ngbinh
:clap:
Philipp Zerelles
@pz_mxu_gitlab
Hello, Can someone maybe help me? I create a schema from AST and in the AST I use a custom scalar "DateTime". Now I also created a ScalarType for that type and use ScalarResolver to assign it to the scalar defined in the AST. But for outputs with the custom type, I get an exception that String cannot be cast to LocalDateTime and my custom "coerceOutput" is not called at all. What am I missing?
Yann Simon
@yanns
An example of a ScalarType we are using:
  implicit val DateTimeType = ScalarType[DateTime](
    "DateTime",
    description = Some(
      "DateTime is a scalar value that represents an [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) formatted date and time."),
    coerceOutput = (date, _) => ISODateTimeFormat.dateTime().print(date),
    coerceUserInput = {
      case s: String =>
        parseDateTime(s) match {
          case scala.util.Success(date) => Right(date)
          case scala.util.Failure(_) => Left(DateCoercionViolation)
        }
      case _ => Left(DateCoercionViolation)
    },
    coerceInput = {
      case ast.StringValue(s, _, _, _, _) =>
        parseDateTime(s) match {
          case scala.util.Success(date) => Right(date)
          case scala.util.Failure(_) => Left(DateCoercionViolation)
        }
      case _ => Left(DateCoercionViolation)
    }
  )
abhishekvaidprophecy
@abhishekvaidprophecy

I'm new to Sangria. I need to create an Argument which is of custom object type.

val authorizationContextArg: Argument[DefaultInput] = Argument(
    "authorizationContext",
    InputObjectType(
      "AuthorizationContext",
      "Define the Auhorization Context of the Search",
      fields = List(
        InputField("authEntityKind", StringType, description = "Auth Entity Kind"),
        InputField("authEntityId",   StringType, description = "Auth Entity Id")
      )
    )
  )

Now, in my resolver, I'm accessing this argument like this ?

val arg             = ctx.arg(authorizationContextArg)

My query is as to how do I now access both the authEntityKind and authEntityId from arg ?

macchiatow
@macchiatow
does anyone know why resolve function of DynamicDirectiveResolver never called where directive define on Interface or Type (this is not a case with field), so far I use middleware as workaround.
TrasheRacer
@TrasheRacer

Hi everyone, first time poster but long time Sangria user,

Our team has identified what appears to be a bug in sangria.Schema.

Looks like there is some side-effect causing Schema() to throw an NPE when it calls collectTypes(). We haven't yet figured out where it's coming from - possibly something to do with lazy val usage. Any advice on fixing this would be appreciated!

I can provide a unit test which reproduces the bug on request.
Cheers! Jake

Nick Hudkins
@nickhudkins
Hey @TrasheRacer yes please, a simple test case would be wonderful!
TrasheRacer
@TrasheRacer
Here's the test case:
import org.scalatest.funsuite.AnyFunSuite
import sangria.marshalling.{CoercedScalaResultMarshaller, FromInput, ResultMarshaller}
import sangria.schema.{Argument, Field, InputField, InputObjectType, LongType, ObjectType, Schema, fields}

/**
  * Below are simplified versions of the classes, objects and traits used in the real implementation of our schema,
  * to reproduce the bug with minimal complexity.
  */
object SchemaInitTest {
  case class ProjectData(name: String = "empty_project", activities: Seq[ActivityRef] = Seq.empty)
  case class Project(projectData: ProjectData)
  case class QueryableProject(project: Project)
  object QueryableProject {
    val empty: QueryableProject = QueryableProject(Project(ProjectData()))
  }
  trait ProjectsContext[T <: ProjectsContext[T]]
  trait POWContext extends ProjectsContext[POWContext]
  case class ProjectValue[T](project: QueryableProject, value: T)
  object ProjectValue {
    def ofActivityRef(queryableProject: QueryableProject, activityRef: ActivityRef): ProjectValue[ActivityRef] =
      ProjectValue(queryableProject, activityRef)
  }

  case class ActivityRef(id: Long)
  object ActivityRef {
    implicit val fromInput: FromInput[ActivityRef] = new FromInput[ActivityRef] {
      override val marshaller: ResultMarshaller = CoercedScalaResultMarshaller.default
      override def fromResult(node: marshaller.Node): ActivityRef = ActivityRef(3456L)
    }

    // TODO: FIND OUT WHY OUR BUG DISAPPEARS WHEN THIS IS CHANGED INTO A LAZY VAL
    val arg: Argument[ActivityRef] = Argument("activityRef", inputType)
  }

  val inputType: InputObjectType[ActivityRef] =
    InputObjectType[ActivityRef](
      "ActivityRefInput",
      fields = List(
        InputField("id", LongType)
      )
    )

  // TODO: FIND OUT WHY NPE DISAPPEARS WHEN THIS IS MADE LAZY
  val activityRefArgs = ActivityRef.arg :: Nil
}

class SchemaInitTest extends AnyFunSuite {

  import SchemaInitTest._

  test("ObjectType() and Schema() should not have any kind of weird side effects when sharing an argument") {
    // Do something which (apparently) mutates global state somewhere in sangria
    ObjectType(
      "Activity",
      fields[Unit, QueryableProject](
        Field(
          "activityRef",
          LongType,
          arguments = ActivityRef.arg :: Nil,
          resolve = _ => 123L // The resolve function is irrelevant to this test
        )
      )
    )

    val query =       ObjectType(
      name = "Query",
      fields = fields[POWContext, Unit](
        Field(
          name = "project",
          fieldType = ObjectType[Unit, QueryableProject](
            name = "Project",
            fields = fields[Unit, QueryableProject](
              Field(
                "activityRef",
                LongType,
                arguments = activityRefArgs,
                resolve = _ => 123L // The resolve function is irrelevant to this test
              )
            )
          ),
          resolve = _ => QueryableProject.empty // The resolve function is irrelevant to this test
        )
      )
    )


    // Create a Schema which **shouldn't** access any global mutable state
    Schema(query)

    // No exception should be thrown...
    assert(true)
  }
}
I would have created a Scalafiddle, but it looks like they don't support Sangria as a library...
TrasheRacer
@TrasheRacer
I went ahead and put this test in my fork of the sangria-playground repo
https://github.com/TrasheRacer/sangria-playground/tree/bug-in-schema-init
image.png
TrasheRacer
@TrasheRacer


java.lang.NullPointerException was thrown.
java.lang.NullPointerException
    at sangria.schema.Schema.$anonfun$types$4(Schema.scala:848)
    at scala.collection.LinearSeqOps.foldLeft(LinearSeq.scala:168)
    at scala.collection.LinearSeqOps.foldLeft$(LinearSeq.scala:164)
    at scala.collection.immutable.List.foldLeft(List.scala:79)
    at sangria.schema.Schema.$anonfun$types$3(Schema.scala:847)
    at scala.collection.IterableOnceOps.foldLeft(IterableOnce.scala:638)
    at scala.collection.IterableOnceOps.foldLeft$(IterableOnce.scala:634)
    at scala.collection.AbstractIterable.foldLeft(Iterable.scala:920)
    at sangria.schema.Schema.collectTypes$1(Schema.scala:845)
    at sangria.schema.Schema.$anonfun$types$3(Schema.scala:847)
    at scala.collection.IterableOnceOps.foldLeft(IterableOnce.scala:638)
    at scala.collection.IterableOnceOps.foldLeft$(IterableOnce.scala:634)
    at scala.collection.AbstractIterable.foldLeft(Iterable.scala:920)
    at sangria.schema.Schema.collectTypes$1(Schema.scala:845)
    at sangria.schema.Schema.types$lzycompute(Schema.scala:873)
    at sangria.schema.Schema.types(Schema.scala:787)
    at sangria.schema.Schema.inputTypes$lzycompute(Schema.scala:885)
    at sangria.schema.Schema.inputTypes(Schema.scala:885)
    at sangria.schema.DefaultValuesValidationRule$.validate(SchemaValidationRule.scala:61)
    at sangria.schema.SchemaValidationRule$.$anonfun$validate$1(SchemaValidationRule.scala:37)
    at scala.collection.immutable.List.flatMap(List.scala:293)
    at sangria.schema.SchemaValidationRule$.validate(SchemaValidationRule.scala:37)
    at sangria.schema.SchemaValidationRule$.validateWithException(SchemaValidationRule.scala:40)
    at sangria.schema.Schema.<init>(Schema.scala:939)
    at SchemaSpec.$anonfun$new$4(SchemaSpec.scala:162)
    at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
    at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
    at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
    at org.scalatest.Transformer.apply(Transformer.scala:22)
    at org.scalatest.Transformer.apply(Transformer.scala:20)
    at org.scalatest.wordspec.AnyWordSpecLike$$anon$3.apply(AnyWordSpecLike.scala:1076)
    at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
    at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
    at org.scalatest.wordspec.AnyWordSpec.withFixture(AnyWordSpec.scala:1879)
    at org.scalatest.wordspec.AnyWordSpecLike.invokeWithFixture$1(AnyWordSpecLike.scala:1074)
    at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTest$1(AnyWordSpecLike.scala:1086)
    at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
    at org.scalatest.wordspec.AnyWordSpecLike.runTest(AnyWordSpecLike.scala:1086)
    at org.scalatest.wordspec.AnyWordSpecLike.runTest$(AnyWordSpecLike.scala:1068)
    at org.scalatest.wordspec.AnyWordSpec.runTest(AnyWordSpec.scala:1879)
    at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTests$1(AnyWordSpecLike.scala:1145)
    at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:413)
    at scala.collection.immutable.List.foreach(List.scala:333)
    at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
    at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:390)
    at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:427)
    at scala.collection.immutable.List.foreach(List.scala:333)
    at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
    at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:396)
    at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:475)
    at org.scalatest.wordspec.AnyWordSpecLike.runTests(AnyWordSpecLike.scala:1145)
    at org.scalatest.wordspec.AnyWordSpecLike.runTests$(AnyWordSpecLike.scala:1144)
    at org.scalatest.wordspec.AnyWordSpec.runTests(AnyWordSpec.scala:1879)
    at org.scalatest.Suite.run(Suite.scala:1112)
    at org.scalatest.Suite.run$(Suite.scala:1094)
    at org.scalatest.wordspec.AnyWordSpec.org$scalatest$wordspec$AnyWordSpecLike$$super$run(AnyWordSpec.scala:1879)
    at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$run$1(AnyWordSpecLike.scala:1190)
    at org.scalatest.SuperEngine.runImpl(Engine.scala:535)
    at org.scalatest.wordspec.AnyWordSpecLi
Nick Hudkins
@nickhudkins
@TrasheRacer can you give v2.0.0 of sangria a try? I can take a look at this in a bit, but I just want to quick confirm that it wasn't recently introduced
Nick Hudkins
@nickhudkins
ah nevermind, @TrasheRacer looks like you've got a Scala issue not a Sangria bug... let me quick show you what's going on
// Start writing your ScalaFiddle code here
object SchemaInitTest {
  object ActivityRef {
    val arg = someOtherThing
  }
  // ActivityRef.arg references something that has yet to be initialized.
  println(ActivityRef.arg)

  // Go ahead and make this eager (not lazy), and you'll get `null`
  lazy val someOtherThing = "Foo"
}

val _ = SchemaInitTest