Description
Hi!
For now caliban checks what entity resolvers are defined and lists them in union _Entity
.
However, if entity resolver is not defined for some type, then it does not mark it as resolvable: false
.
I think it should be done automatically.
Consider the following example:
import caliban.*
import caliban.federation.EntityResolver
import caliban.schema.Schema.auto.*
import caliban.schema.ArgBuilder.auto.*
import caliban.quick.*
import caliban.federation.v2_3.*
import zio.query.ZQuery
@GQLKey("id")
case class User(
id: String)
@GQLKey("id", resolvable = false)
case class Product(
id: String,
size: Int)
case class ProductArgs(id: String)
case class Queries(
myProduct: Product,
myUser: User)
val queries = Queries(Product("1", 1), User("1"))
val api = graphQL(RootResolver(queries))
val withFederation = federated(
EntityResolver[Any, ProductArgs, Product](args =>
ZQuery.succeed(Some(Product(args.id, 42)))
),
)
val federatedSchema = api @@ withFederation
@main def main = {
println(federatedSchema.render)
}
Output
schema {
query: Queries
}
scalar _Any
union _Entity = Product
type Product @key(fields: "id", resolvable: false) {
id: String!
size: Int!
}
type Queries {
_entities(representations: [_Any!]!): [_Entity]!
_service: _Service!
myProduct: Product!
myUser: User!
}
type User @key(fields: "id") {
id: String!
}
type _Service {
sdl: String!
}
Since caliban can automatically deduce members of union _Entity
, then it can automatically set resolvable: false
for entities that do not have entity resolver defined in federated(...)
.
It can be helpful since the process that composes supergraph takes into account only resolvable
flag, not union _Entity
.
The following compiles:
# Subgraph A
schema {
query: Queries
}
scalar _Any
union _Entity = Product
type Product @key(fields: "id") {
id: String!
size: Int!
user: User!
}
type Queries {
_entities(representations: [_Any!]!): [_Entity]!
_service: _Service!
myProduct: Product!
myUser: User!
}
type User @key(fields: "id") {
id: String!
extraField: String!
}
type _Service {
sdl: String!
}
# Subgraph B
schema {
query: Queries
}
scalar _Any
union _Entity = User
type Queries {
_entities(representations: [_Any!]!): [_Entity]!
_service: _Service!
anotherUser: User!
}
type User @key(fields: "id") {
id: String!
name: String!
}
type _Service {
sdl: String!
}
In subgraph A the only resolvable entity (according to union _Entity
) is Product
; User
also (implicitly) has resolvable: true
.
However, this schema is invalid because query { anotherUser { extraField } }
will fail at runtime.
If you add resolvable: false
for User
in subgraph A, then schema cannot be composed (via rover cli).