Reputation: 1161
imagine I have this as my schema, where people query with a bird Id and if they ask for the location they get everything about the location. Do I still have to define Location in "schema" format? or is there any way to use the case class immediately here?
If you want a bit of background about why I want to this: I got a JSon-schema that is massively nested and it will be very close to impossible to manage every level of it. I am happy with the user requesting a top layer element which will return what ever case class is defined at that stage.
import sangria.schema._
case class Location( lat: String, long: String )
case class Bird( name: String, location: List[Location] )
class BirdRepo {
def get(id: Int ) = {
if( id < 10 ) {
Bird( "Small",
List( Location("1", "2"), Location("3", "4")
))
} else {
Bird( "Big",
List( Location("5", "6"), Location("7", "8")
))
}
}
}
object SchemaDefinition {
val Bird = ObjectType(
"Bird",
"Some Bird",
fields[BirdRepo, Bird] (
Field( "name", StringType, resolve = _.value.name ),
Field( "location", List[Location], resolve = _.value.location)
// ^^ I know this is not possible
)
)
}
Upvotes: 1
Views: 1345
Reputation: 26576
As @Tyler mentioned, you can use deriveObjectType
. The definition for both types will look like this:
implicit val LocationType = deriveObjectType[BirdRepo, Location]()
implicit val BirdType = deriveObjectType[BirdRepo, Bird]()
deriveObjectType
is able to correctly handle List[Location]
as long as you have an implicit instance of ObjectType[BirdRepo, Location]
(LocationType
in your case) defined in scope.
Field( "location", List[Location], resolve = _.value.location)
The right syntax would be:
Field( "location", ListType(LocationType), resolve = _.value.location)
Assuming that you already have defined LocationType
elsewhere.
Upvotes: 4
Reputation: 18177
From the docs, you should check out the section on ObjectType Derivation
Here is the example:
case class User(id: String, permissions: List[String], password: String)
val UserType = deriveObjectType[MyCtx, User](
ObjectTypeName("AuthUser"),
ObjectTypeDescription("A user of the system."),
RenameField("id", "identifier"),
DocumentField("permissions", "User permissions",
deprecationReason = Some("Will not be exposed in future")),
ExcludeFields("password"))
You will notice that you still need to provide the name, and then there are some optional things like the renaming of fields and depreciations.
It will generate an ObjectType which is equivalent to this one:
ObjectType("AuthUser", "A user of the system.", fields[MyCtx, User](
Field("identifier", StringType, resolve = _.value.id),
Field("permissions", ListType(StringType),
description = Some("User permissions"),
deprecationReason = Some("Will not be exposed in future"),
resolve = _.value.permissions)))
Upvotes: 1