Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Lookup Directive. #30

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
48 changes: 31 additions & 17 deletions spec/Section 2 -- Source Schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,75 @@

## Directives

### @entityResolver
### @lookup

The `@lookup` directive is applied to object fields to enable the resolution of entities from a _source schema_ by a stable key. This directive marks a field as capable of performing a lookup operation.

```graphql
directive @entityResolver on FIELD_DEFINITION
directive @lookup on FIELD_DEFINITION
```

Entity resolvers are fields on the query root type of a subgraph that can
resolve an entity by a stable key. The stable key is defined by the arguments of
the field.
Lookup fields allow the composite schema to resolve entities from a source schema by a stable key. The stable key is defined by the arguments of the field. Only fields that are annotated with the `@lookup` directive will be recognized as lookup field.

```graphql example
extend type Query {
version: Int # NOT an entity resolver.
personById(id: ID!): Person @entityResolver
personById(id: ID!): Person @lookup
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
}

extend type Person {
id: ID! # matches the argument of personById
extend type Person @key(fields "id") {
id: ID!
}
```

The arguments of an entity resolver field must match fields of the returning
type.
The arguments of a lookup field must correspond to the fields specified by a `@key` directive annotated on the type returned by the lookup field.

```graphql example
extend type Query {
node(id: ID!): Node @entityResolver
node(id: ID!): Node @lookup
}

interface Node {
interface Node @key(fields "id") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
interface Node @key(fields "id") {
interface Node @key(fields: "id") {

id: ID!
}
```

When an entity resolver returns an interface all implementing types are inferred
as entities.
Lookup fields returning an interface or union type can be used as lookup field for all possible object types.

```graphql example
extend type Query {
entityById(id: ID!, categoryId: Int): Entity @entityResolver
entityById(id: ID!, categoryId: Int): Entity @lookup
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
}

union Entity = Cat | Dog

extend type Dog {
extend type Dog @key(fields "id") {
id: ID!
categoryId: Int
}

extend type Cat {
extend type Cat @key(fields "id") {
id: ID!
categoryId: Int
}
```

Lookup fields must be accessible from the Query type. If not directly on the Query type, they should be accessible via fields that do not require arguments, starting from the Query type.

```graphql example
extend type Query {
lookups: Lookups!
}

type Lookups {
personById(id: ID!): Person @lookup
}

extend type Person @key(fields "id") {
id: ID!
}
```

### @is

```graphql
Expand Down