Skip to content

Commit

Permalink
Update graphql documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Jun 1, 2022
1 parent 897689a commit 9090339
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,36 @@ Docs for the current stable version (3.x) can be found

## Building the schema

The primary API surface of the `silverstripe-graphql` module is the configuration YAML, and
some [procedural configuration](using_procedual_code) as well. It is important to understand
The primary API surface of the `silverstripe/graphql` module is the yaml configuration, along
with some [procedural configuration](using_procedual_code). It is important to understand
that **none of this configuration gets interpreted at runtime**. Loading the schema configuration
at runtime and converting it to executable code has dire effects on performance, making
API requests slower and slower as the schema grows larger.
(which we refer to as the "schema definition") at runtime and converting it to executable code
has dire effects on performance, making API requests slower and slower as the schema grows larger.

To mitigate this problem, the schema that gets executed at runtime is **generated PHP code**.
This code generation happens during a build step, and it is critical to run this build step
whenever the schema changes.

### Running the build

The task that generates the schema code is `build-schema`. It takes a parameter of `schema`, whose value should be the name of the schema you want to build.
The task that generates the schema code is `dev/graphql/build`.

`$ vendor/bin/sake dev/graphql/build schema=default`
`vendor/bin/sake dev/graphql/build`

This task takes an optional `schema` parameter. If you only want to generate a specific schema
(e.g. generate your custom schema, but not the CMS schema), you should pass in the name of the
schema you want to build.

`vendor/bin/sake dev/graphql/build schema=default`

[info]
Most of the time, the name of your custom schema is `default`. If you're editing DataObjects
that are accessed with GraphQL in the CMS, you may have to build the `admin` schema as well.
[/info]

Keep in mind that many of your changes will be in YAML, which also requires a flush.

`$ vendor/bin/sake dev/graphql/build schema=default flush=1`
`vendor/bin/sake dev/graphql/build schema=default flush=1`

[info]
If you do not provide a `schema` parameter, the task will build all schemas.
Expand All @@ -51,7 +62,6 @@ SilverStripe\GraphQL\Extensions\DevBuildExtension:
enabled: false
```
### Caching
Generating code is a pretty expensive process. A large schema with 50 dataobject classes exposing
Expand All @@ -66,7 +76,7 @@ If the type hasn't changed, it doesn't re-render. This reduces build times to **
Normally, we'd use `flush=1` to clear the cache, but since you almost always need to run `flush=1` with the build task, it isn't a good fit. Instead, use `clear=1`.

`$ vendor/bin/sake dev/graphql/build schema=default clear=1`
`vendor/bin/sake dev/graphql/build schema=default clear=1`

If your schema is producing unexpected results, try using `clear=1` to eliminate the possibility
of a caching issue. If the issue is resolved, record exactly what you changed and [create an issue](https://github.com/silverstripe/silverstripe-graphql/issues/new).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ summary: Upgrade your Silverstripe CMS project to use graphQL version 4

# Upgrading to GraphQL v4

[alert]
You are viewing docs for a pre-release version of silverstripe/graphql (4.x).
Help us improve it by joining #graphql on the [Community Slack](https://www.silverstripe.org/blog/community-slack-channel/),
and report any issues at [github.com/silverstripe/silverstripe-graphql](https://github.com/silverstripe/silverstripe-graphql).
Docs for the current stable version (3.x) can be found
[here](https://github.com/silverstripe/silverstripe-graphql/tree/3)
[/alert]

Silverstripe CMS Recipe 4.11 defaults to installing silverstripe/graphql v4. Previous releases installed version 3.

## What does silverstripe/graphql do and why are you changing this?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ The `*` value on `operations` tells the schema to create all available queries a
* `update`
* `delete`

Now that we've changed our schema, we need to build it using the `build-schema` task:
Now that we've changed our schema, we need to build it using the `dev/graphql/build` task:

`$ vendor/bin/sake dev/graphql/build schema=default`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ Docs for the current stable version (3.x) can be found
When you define a query mutation, or any other field on a type, you can opt out of providing
an explicit resolver and allow the system to discover one for you based on naming convention.

Let's start by registering a resolver class(es) where we can define a bunch of these functions.
Let's start by registering a resolver class where we can define a bunch of these methods.

You can register as many classes as makes sense - and each resolver class can have multiple
resolver methods.

**app/_graphql/config.yml**
```yaml
Expand All @@ -42,7 +45,7 @@ public static function getResolverMethod(string $className, ?string $typeName =

#### The default resolver strategy

By default, all schemas use `SilverStripe\GraphQL\Schema\Resolver\DefaultResolverStrategy::getResolerMethod`
By default, all schemas use [`DefaultResolverStrategy::getResolverMethod()`](api:SilverStripe\GraphQL\Schema\Resolver\DefaultResolverStrategy::getResolverMethod())
to discover resolver functions. The logic works like this:

* Does `resolve<TypeName><FieldName>` exist?
Expand Down Expand Up @@ -140,13 +143,14 @@ ground between the rigor of hard coding everything and the opacity of discovery
fields:
name: String
code: String
fieldResolver: [ 'MyProject\MyResolver', 'resolveCountryField' ]
fieldResolver: [ 'MyProject\MyResolver', 'resolveCountryFields' ]
```

You'll need to do explicit checks for the `fieldName` in your resolver to make this work.
In this case the registered resolver method will be used to resolve any number of fields.
You'll need to do explicit checks for the field name in your resolver to make this work.

```php
public static function resolveCountryField($obj, $args, $context, ResolveInfo $info)
public static function resolveCountryFields($obj, $args, $context, ResolveInfo $info)
{
$fieldName = $info->fieldName;
if ($fieldName === 'image') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Docs for the current stable version (3.x) can be found

## Adding a custom model

The only point of contact the `silverstripe-graphql` schema has with
The only point of contact the `silverstripe/graphql` schema has with
Silverstripe specifically is through the `DataObjectModel` adapter
and its associated plugins. This is important, because it means you
can plug in any schema-aware class as a model, and it will be afforded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ a larger process. A key feature of middleware is that it can be used
with other middlewares in sequence and not have to worry about the order
of execution.

In `silverstripe-graphql`, middleware is used for query execution,
but could ostensibly be used elsewhere too if the API ever accommodates
In `silverstripe/graphql`, middleware is used for query execution,
but could ostensibly be used elsewhere too if the API ever accomodates
such an expansion.

[notice]
Expand All @@ -36,14 +36,14 @@ The signature for middleware looks like this:
public function process(Schema $schema, $query, $context, $vars, callable $next)
```

* `$schema`: The underlying [Schema](http://webonyx.github.io/graphql-php/type-system/schema/) object.
Useful to inspect whether types are defined in a schema.
* `$query`: The raw query string.
* `$context`: An arbitrary array which holds information shared between resolvers.
Use implementors of `SilverStripe\GraphQL\Schema\Interfaces\ContextProvider` to get and set
data, rather than relying on the array keys directly.
* `$vars`: An array of (optional) [Query Variables](https://graphql.org/learn/queries/#variables).
* `$next`: A callable referring to the next middleware in the chain
* `$schema`: The underlying [Schema](http://webonyx.github.io/graphql-php/type-system/schema/) object.
Useful to inspect whether types are defined in a schema.
* `$query`: The raw query string.
* `$context`: An arbitrary array which holds information shared between resolvers.
Use implementors of `SilverStripe\GraphQL\Schema\Interfaces\ContextProvider` to get and set
data, rather than relying on the array keys directly.
* `$vars`: An array of (optional) [Query Variables](https://graphql.org/learn/queries/#variables).
* `$next`: A callable referring to the next middleware in the chain

Let's write a simple middleware that logs our queries as they come in.

Expand Down Expand Up @@ -72,12 +72,10 @@ class LoggingMiddleware implements Middleware

Now we can register the middleware with our query handler:


```yaml
SilverStripe\GraphQL\QueryHandler\QueryHandlerInterface.default:
class: SilverStripe\GraphQL\QueryHandler\QueryHandler
properties:
Middlewares:
logging: '%$MyProject\Middleware\LoggingMiddleware'
```
Loading

0 comments on commit 9090339

Please sign in to comment.