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

Source Schema Chapter #30

Open
wants to merge 45 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
14badaf
Introduce Lookup Directive.
michaelstaib Apr 11, 2024
f54f24a
Added more examples
michaelstaib Apr 11, 2024
dc499eb
edits
michaelstaib Apr 11, 2024
5c9d4a1
edits
michaelstaib Apr 11, 2024
9cef444
edits
michaelstaib Apr 11, 2024
8771136
edits
michaelstaib Apr 11, 2024
2798146
edits
michaelstaib Apr 11, 2024
a75d22a
edits
michaelstaib Apr 11, 2024
5766888
format
michaelstaib Apr 11, 2024
a5d8a5e
Remove extend keyword to make examples less confusing.
michaelstaib May 2, 2024
025718a
Reworked lookup proposal.
michaelstaib May 23, 2024
cbd4a36
Added patch
michaelstaib May 23, 2024
e51f92a
Reworked require
michaelstaib May 23, 2024
07daa8b
Reverted changes
michaelstaib Jun 6, 2024
039f588
Reworked require
michaelstaib Jun 6, 2024
5c0fd5c
Removed Schema Coordinate
michaelstaib Jun 6, 2024
b9b6aa2
Format
michaelstaib Jun 6, 2024
628592c
Added Patch
michaelstaib Jun 6, 2024
864b1fa
Removed Patch
michaelstaib Jun 6, 2024
b5266d4
Reworked Example
michaelstaib Jun 13, 2024
91048bc
Update spec/Section 2 -- Source Schema.md
michaelstaib Jun 17, 2024
5e9a84c
edits
michaelstaib Jun 20, 2024
42572df
wip
michaelstaib Jun 27, 2024
f7052eb
wip
michaelstaib Jun 27, 2024
80b7d89
wip
michaelstaib Jun 27, 2024
dcb9825
wip
michaelstaib Jun 27, 2024
e81aa9a
wip
michaelstaib Jun 27, 2024
772a852
more updates
michaelstaib Jul 11, 2024
860e627
more updates
michaelstaib Jul 11, 2024
674fdc3
more updates
michaelstaib Jul 11, 2024
22c2858
more updates
michaelstaib Jul 11, 2024
3b74f17
Edits
michaelstaib Jul 25, 2024
0c1b4ac
edits
michaelstaib Jul 25, 2024
031bebf
edits
michaelstaib Jul 25, 2024
2218ed0
Update spec/Section 2 -- Source Schema.md
michaelstaib Aug 1, 2024
38647c3
Update spec/Section 2 -- Source Schema.md
michaelstaib Aug 1, 2024
17506c5
Update spec/Section 2 -- Source Schema.md
michaelstaib Aug 1, 2024
f38c4e2
Update spec/Section 2 -- Source Schema.md
michaelstaib Aug 1, 2024
f5e5e55
Update spec/Section 2 -- Source Schema.md
michaelstaib Aug 1, 2024
ed4e2ce
Update spec/Section 2 -- Source Schema.md
michaelstaib Aug 1, 2024
bd2d2ef
Update spec/Section 2 -- Source Schema.md
michaelstaib Aug 1, 2024
c45f7eb
wip
michaelstaib Aug 1, 2024
c0fac34
edits
michaelstaib Sep 26, 2024
1b34ada
edits
michaelstaib Sep 26, 2024
09dd376
Merge branch 'main' into mst/lookup
michaelstaib Oct 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 72 additions & 49 deletions spec/Section 2 -- Source Schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@
directive @lookup on FIELD_DEFINITION
```

The `@lookup` directive is used within a _source schema_ to specify object
The `@lookup` directive is used within a _source schema_ to specify output
fields that can be used by the _distributed GraphQL executor_ to resolve an
entity 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.
annotated with the `@lookup` directive will be recognized as lookup fields.

Source schemas can provide multiple lookup fields for the same entity with
different keys.
different sets of keys.

In this example the source schema specifies that the `Person` entity can be
resolved with the `personById` field or the `personByName` field on the `Query`
In this example, the source schema specifies that the `Product` entity can be
resolved with the `productById` field or the `productByName` field on the `Query`
type. Both fields can resolve the same entity but do so with different keys.

```graphql example
type Query {
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
version: Int # NOT a lookup field.
personById(id: ID!): Person @lookup
personByName(name: String!): Person @lookup
productById(id: ID!): Product @lookup
productByName(name: String!): Product @lookup
}

type Person @key(fields: "id") @key(fields: "name") {
type Product @key(fields: "id") @key(fields: "name") {
id: ID!
name: String!
}
Expand All @@ -48,51 +48,64 @@ interface Node @key(fields: "id") {
}
```

Lookup fields may return object, interface or union types. In case a lookup
field returns an interface or union type all possible object types are
Lookup fields may return object, interface, or union types. In case a lookup
field returns an interface or union type, all possible object types are
considered entities and must have keys that correspond with the fields argument
signature.

```graphql example
type Query {
entityById(id: ID!, categoryId: Int): Entity @lookup
product(id: ID!, categoryId: Int): Product @lookup
}

union Entity = Cat | Dog
union Product = Electronics | Clothing

type Dog @key(fields: "id categoryId") {
type Electronics @key(fields: "id categoryId") {
id: ID!
categoryId: Int
name: String
brand: String
price: Float
}

type Cat @key(fields: "id categoryId") {
type Clothing @key(fields: "id categoryId") {
id: ID!
categoryId: Int
name: String
size: String
price: Float
}
```

The following example shows an invalid lookup field as the `Cat` type does not
declare a key that corresponds with the lookup fields argument signature.
The following example shows an invalid lookup field as the `Clothing` type does not
declare a key that corresponds with the lookup field's argument signature.

```graphql counter-example
type Query {
entityById(id: ID!, categoryId: Int): Entity @lookup
product(id: ID!, categoryId: Int): Product @lookup

Choose a reason for hiding this comment

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

as discussed during last meeting I believe this is actually valid?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes ... I am gonna rewrite this part.

}

union Entity = Cat | Dog
union Product = Electronics | Clothing

type Dog @key(fields: "id categoryId") {
type Electronics @key(fields: "id categoryId") {
id: ID!
categoryId: Int
name: String
brand: String
price: Float
}

type Cat @key(fields: "id") {
type Clothing @key(fields: "id") {
id: ID!
categoryId: Int
name: String
size: String
price: Float
}
```

If the lookup returns an interface in particular the interface must also be
annotated with a `@key` directive.
If the lookup returns an interface, the interface must also be annotated with a
`@key` directive.

```graphql example
interface Node @key(fields: "id") {
Expand All @@ -110,41 +123,61 @@ type Query {
}

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

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

Lookups can also be nested if they can be reached through other lookups.
### @internal

```graphql
directive @internal on FIELD_DEFINITION
```

The `@internal` directive signals to the composition process that annotated
field definitions are not intended to be part of the public schema. Internal
field definitions can still be used by the distributed GraphQL executor to
resolve data.

```graphql example
type Query {
organization(id: ID!): Ogranization @lookup
type Product @key(fields: "_internalId") {
_internalId: String @internal
}
```

type Ogranization {
repository(name: String!): Repository @lookup
}
The `@internal` directive in combination with the `@lookup` directive allows
defining lookup directives that are not used as global fields in the public
schema and this are not used as entry points.
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved

type Repository @key(fields: "id organization { id }") {
name: String!
organization: Ogranization
```graphql example
type Query {
# lookup field and possible entry point
reviewById(id: ID!): Review @lookup

# internal lookup field
productById(id: ID!): Product @lookup @internal
}
```

This provides control over which source schemas are used to resolve entities and
which merely provide data to entities. It also allows hiding "technical" lookup
fields from the public schema.

### @is

```graphql
directive @is(
field: FieldSelection
coordinate: Schemacoordinate
) on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION
field: FieldSelectionMap!
) on ARGUMENT_DEFINITION
```

The `@is` directive is utilized to establish semantic equivalence between
The `@is` directive is utilized in a lookup field to establish how the


semantic equivalence between
michaelstaib marked this conversation as resolved.
Show resolved Hide resolved
disparate type system members across distinct subgraphs, which the schema
composition uses to connect types.

Expand All @@ -159,15 +192,15 @@ extend type Query {
}
```

The `@is` directive also allows to refer to nested fields relative to `Person`.
The `@is` directive also allows referring to nested fields relative to `Person`.

```graphql example
extend type Query {
personByAddressId(id: ID! @is(field: "address.id")): Person
}
```

The `@is` directive not limited to a single argument.
The `@is` directive is not limited to a single argument.

```graphql example
extend type Query {
Expand Down Expand Up @@ -290,13 +323,3 @@ directive @override(from: String!) on FIELD_DEFINITION
```

The `@override` directive allows to migrate fields from one subgraph to another.

### @internal

```graphql
directive @internal on OBJECT | INTERFACE | FIELD_DEFINITION | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCALAR
```

The `@internal` directive signals to the composition process that annotated type
system members shall not be included into the public schema but still can be
used by the executor to build resolvers.
30 changes: 30 additions & 0 deletions spec/temp.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,33 @@ systems to agree on a common way of identifying a particular type of entity. The
composite schemas spec therefore allows multiple keys to be defined for each
entity type, and each subgraph defines the particular keys that it is able to
support.

Lookups can also be nested if they can be reached through other lookups.

```graphql example
type Query {
organization(id: ID!): Ogranization @lookup
}

type Ogranization {
repository(name: String!): Repository @lookup
}

type Repository @key(fields: "id organization { id }") {
name: String!
organization: Ogranization
}
```

The arguments of a lookup field must correspond to fields specified by a `@key`
directive annotated on the return type of the lookup field.

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

interface Node @key(fields: "id") {
id: ID!
}
```
Loading