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.
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`.")
}
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))
}
}
}
Argument 'manager' has invalid value: At path '/role': error.sealed.trait (line 2, column 55):\n addManager (vendorNumber: $vendorNumber, manager: $manager)
val MutationType = deriveContextObjectType[FulfillerGraphQLSecureContext,FulfillerGraphQLMutation,Unit](_.mutation)
val FulfillerSchema = Schema(Query,Some(MutationType))
@GraphQLField
def addManager(vendorNumber: String,
manager: Manager): Future[FulfillerView]
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
}
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.
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]
sangria-circe
package here: https://github.com/sangria-graphql/sangria-circe and the purpose of the library is only to provide marshalling and unmarshalling of GraphQL types as the schema is being materialized, or input is received.
case class ResultData(resultId: ResultId)
object ResultId {
//Already derived it as a string
//This is a factory for creating ResultId from String
implicit val encoder: Encoder[ResultId] = Encoder.encodeString.contramap(_.id)
implicit val decoder: Decoder[ResultId] = Decoder.decodeString.map(ResultId(_))
//Now I repeat myself
//This is also a factory for creating ResultId from String
implicit val graphQlType = ScalarAlias[ResultId, String](
StringType,
_.id,
id => Right(ResultId(id))
)
}
case class ResultId(id: String) extends AnyVal