# Source: https://grafbase.com/docs/gateway/extensions/specs/grafbase-spec/v2.0.md

# Grafbase Spec

This document defines the directives and types that have special treatment in the Grafbase gateway. They are meant to be used as building blocks for extension directives. The gateway will automatically detect them and inject the right data in their stead.

Here after is the full definition:

```graphql
"""
String specifying a selection set over the arguments which should be provided at runtime.
"""
scalar InputValueSet

"""
String specifying a selection set over the response data which should be provided at runtime.
"""
scalar FieldSet
```

Import me with:

```graphql
extend schema
  @link(url: "https://specs.grafbase.com/grafbase", import: ["FieldSet"])
```

## InputValueSet

```graphql
"""
String specifying a selection set over the arguments which should be provided at runtime.
"""
scalar InputValueSet
```

The `InputValueSet` scalar is used to inject arguments into a directive. It's a `String` that defines a selection set such as `"ids filter { age }"` on the field arguments with a special case `"*"` that will inject all the arguments as shown in the following example:

```graphql
# Extension SDL
directive @myDirective(input: InputValueSet) on FIELD_DEFINITION

# ---
# Subgraph SDL
type Query {
  # Receives all arguments
  users(ids: [ID!], filter: Filter): [User!] @myDirective(input: "*")

  # Which is equivalent to the following
  users(ids: [ID!], filter: Filter): [User!] @myDirective(input: "ids filter")

  # Fine-grained selection
  users(ids: [ID!], filter: Filter): [User!]
    @myDirective(input: "filter { age }")
}

input Filter {
  name: String
  age: Int
}

type User {
  id: ID!
}
```

Contrary to field selection sets used in operations, there is a relaxed rule for leaves: one can select `"filter"` without specifying any sub-selection despite being an input object. The whole `Filter` input object will be provided in that case.

`InputValueSet` can be used in any extension directive definitions, but outside of `FIELD_DEFINITION` location, any non-null `InputValueSet` value will raise an error:

```graphql
# Valid
type User @myDirective {
  id: ID!
}
# Valid
type User @myDirective(input: null) {
  id: ID!
}
# Invalid, will raise an error.
type User @myDirective(input: "*") {
  id: ID!
}
```

## FieldSet

```graphql
"""
String specifying a selection set over the response data which should be provided at runtime.
"""
scalar FieldSet
```

The `FieldSet` scalar is used to inject response data into a directive. It's a `String` that defines a field selection set such as `"id name"` on the _current_ object or interface:

```graphql
# Extension SDL
directive @myDirective(fields: FieldSet) on FIELD_DEFINITION

# ---
# Subgraph SDL
type User {
  id: ID!
  name: String
  pets(limit: Int!): [Pet!]
  catLoverFriends: [User!]
    @myDirective(fields: "id pets(limit: 10) { ... on Cat { id } }")
}

union Pet = Cat | Dog

type Dog {
  id: ID!
}

type Cat {
  id: ID!
}
```

Except named fragments, `FieldSet` accepts any valid field selection set with field arguments or inline fragments. The gateway will do its best to re-use existing operation fields if they match, but will request anything additional.

`FieldSet` can be used in any extension directive definitions, but outside of `FIELD_DEFINITION`, `OBJECT` and `INTERFACE` locations, any non-null `FieldSet` value will raise an error:

```graphql
# Valid
union Pet = Cat | Pet @myDirective
# Valid
union Pet = Cat | Pet @myDirective(fields: null)
# Invalid, will raise an error.
union Pet = Cat | Pet @myDirective(fields: "... on Cat { id }")
```