diff --git a/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/03_building_the_schema.md b/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/03_building_the_schema.md index acd11ef68f2..a5befe119df 100644 --- a/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/03_building_the_schema.md +++ b/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/03_building_the_schema.md @@ -17,11 +17,11 @@ 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 @@ -29,13 +29,24 @@ 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. @@ -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 @@ -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). diff --git a/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/05_WIP.md b/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/05_WIP.md index b6563e08052..9582b9e42ba 100644 --- a/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/05_WIP.md +++ b/docs/en/02_Developer_Guides/19_GraphQL/01_getting_started/05_WIP.md @@ -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? diff --git a/docs/en/02_Developer_Guides/19_GraphQL/02_working_with_dataobjects/01_adding_dataobjects_to_the_schema.md b/docs/en/02_Developer_Guides/19_GraphQL/02_working_with_dataobjects/01_adding_dataobjects_to_the_schema.md index b639356526a..49baa649196 100644 --- a/docs/en/02_Developer_Guides/19_GraphQL/02_working_with_dataobjects/01_adding_dataobjects_to_the_schema.md +++ b/docs/en/02_Developer_Guides/19_GraphQL/02_working_with_dataobjects/01_adding_dataobjects_to_the_schema.md @@ -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` diff --git a/docs/en/02_Developer_Guides/19_GraphQL/03_working_with_generic_types/03_resolver_discovery.md b/docs/en/02_Developer_Guides/19_GraphQL/03_working_with_generic_types/03_resolver_discovery.md index 38a0b61e1ac..4e8c89907ba 100644 --- a/docs/en/02_Developer_Guides/19_GraphQL/03_working_with_generic_types/03_resolver_discovery.md +++ b/docs/en/02_Developer_Guides/19_GraphQL/03_working_with_generic_types/03_resolver_discovery.md @@ -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 @@ -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` exist? @@ -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') { diff --git a/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_a_custom_model.md b/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_a_custom_model.md index 66b5d003b3b..cee20c66a41 100644 --- a/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_a_custom_model.md +++ b/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_a_custom_model.md @@ -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 diff --git a/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_middleware.md b/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_middleware.md index e7e3e97114f..01bb22f2168 100644 --- a/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_middleware.md +++ b/docs/en/02_Developer_Guides/19_GraphQL/06_extending/adding_middleware.md @@ -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] @@ -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. @@ -72,7 +72,6 @@ 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 @@ -80,4 +79,3 @@ Now we can register the middleware with our query handler: Middlewares: logging: '%$MyProject\Middleware\LoggingMiddleware' ``` - diff --git a/docs/en/03_Upgrading/05_Upgrading_to_GrapgQL_4.md b/docs/en/03_Upgrading/06_Upgrading_to_GraphQL_4.md similarity index 59% rename from docs/en/03_Upgrading/05_Upgrading_to_GrapgQL_4.md rename to docs/en/03_Upgrading/06_Upgrading_to_GraphQL_4.md index 8d9a68dbdca..d8b1d83ca52 100644 --- a/docs/en/03_Upgrading/05_Upgrading_to_GrapgQL_4.md +++ b/docs/en/03_Upgrading/06_Upgrading_to_GraphQL_4.md @@ -1,6 +1,6 @@ --- title: Upgrading to GraphQL 4 -summary: A high-level view of what you'll need to change when upgrading to GraphQL 4 +summary: Upgrade your Silverstripe CMS project to use graphQL version 4 --- # Upgrading to GraphQL 4 @@ -13,47 +13,39 @@ Docs for the current stable version (3.x) can be found [here](https://github.com/silverstripe/silverstripe-graphql/tree/3) [/alert] -The 4.0 release of `silverstripe-graphql` underwent a massive set of changes representing an +The 4.0 release of `silverstripe/graphql` underwent a massive set of changes representing an entire rewrite of the module. This was done as part of a year-long plan to improve performance. While there is no specific upgrade path, there are some key things to look out for and general guidelines on how to adapt your code from the 3.x release to 4.x. +Note that this document is aimed towards developers who have a custom graphql schema. If you are updating from graphql +3 to 4 but do not have a custom schema, you should familiarise yourself with the +[building the schema](/developer_guides/graphql/getting_started/building_the_schema) documentation, but you do not need to read this document. + In this section, we'll cover each of these upgrade issues in order of impact. ## GraphQL schemas require a build step The most critical change moving from 3.x to 4.x affects the developer experience. The key to improving performance in GraphQL requests was eliminating the overhead of generating the schema at -runtime. This didn't scale. As the GraphQL schema grew, API response latency increase. +runtime. This didn't scale. As the GraphQL schema grew, API response latency increased. To eliminate this overhead, the GraphQL API relies on **generated code** for the schema. You need to run a task to build it. -To run the task, use: - -`$ vendor/bin/sake dev/graphql/build schema=mySchema` - -You can also run the task in the browser: +`vendor/bin/sake dev/graphql/build schema=default` -`http://example.com/dev/graphql/build?schema=mySchema` +Check the [building the schema](/developer_guides/graphql/getting_started/building_the_schema) documentation to learn about the +different ways to build your schema. -[info] -Most of the time, the name of your 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] +## The `Manager` class, the godfather of GraphQL 3, is gone -This build process is a larger topic with a few more things to be aware of. -Check the [building the schema](getting_started/building_the_schema) documentation to learn more. +`silverstripe/graphql` 3.x relied heavily on the `Manager` class. This became a catch-all that handled +scaffolding, registration of types, running queries and middleware, error handling, and more. This +class has been broken up into two separate concerns: - -## The Manager class, the godfather of GraphQL 3, is gone - -`silverstripe-graphql` 3.x relied heavily on the `Manager` class. This became a catch-all that handled -registration of types, execution of scaffolding, running queries and middleware, error handling, and more. This -class has been broken up into separate concerns: - -* `Schema` <- register your stuff here -* `QueryHandlerInterface` <- Handles GraphQL queries, applies middlewares and context. +* [`Schema`](api:SilverStripe\GraphQL\Schema\Schema) <- register your stuff here +* [`QueryHandlerInterface`](api:SilverSTripe\GraphQL\QueryHandler\QueryHandlerInterface) <- Handles GraphQL queries, applies middlewares and context. You'll probably never have to touch it. ### Upgrading @@ -78,7 +70,7 @@ SilverStripe\GraphQL\Schema\Schema: ``` Add the appropriate yaml files to the directory. For more information on this pattern, see -the [configuring your schema](01_getting_started/02_configuring_your_schema) section. +the [configuring your schema](/developer_guides/graphql/getting_started/configuring_your_schema) section. ``` app/_graphql @@ -91,15 +83,14 @@ app/_graphql unions.yml ``` -## TypeCreator, QueryCreator, and MutationCreator are gone +## `TypeCreator`, `QueryCreator`, and `MutationCreator` are gone A thorough look at how these classes were being used revealed that they were really just functioning -as value objects that basically just created configuration in a static context. That is, they had no +as value objects that effectively created configuration in a static context. That is, they had no real reason to be instance-based. Most of the time, they can easily be ported to configuration. ### Upgrading - **before** ```php class GroupTypeCreator extends TypeCreator @@ -133,8 +124,9 @@ group: Description: String ``` -That's a simple type, and obviously there's a lot more to it than that, but have a look at the -[working with generic types](getting_started/working_with_generic_types) section of the documentation. +That's a simple type, and obviously there's a lot more to it than that. Have a look at the +[working with generic types](/developer_guides/graphql/getting_started/working_with_generic_types) section of the documentation +to learn more. ## Resolvers must be static callables @@ -144,7 +136,9 @@ and moved into a class. ### Upgrading -Move your resolvers into one or many classes, and register them. +Move your resolvers into one or many classes, and register them. Notice that the name of the method +determines what is being resolved, where previously that would be the name of a resolver class. Now, +multiple resolver methods can exist within a single resolver class. **before** ```php @@ -162,12 +156,12 @@ class LatestPostResolver implements OperationResolver **app/_graphql/config.yml** ```yaml resolvers: - - MyProject\Resolvers\MyResolverA - - MyProject\Resolvers\MyResolverB + - MyProject\Resolvers\MyResolverClassA + - MyProject\Resolvers\MyResolverClassB ``` ```php -class MyResolverA +class MyResolverClassA { public static function resolveLatestPost($object, array $args, $context, ResolveInfo $info) { @@ -176,22 +170,23 @@ class MyResolverA } ``` -This method relies on [resolver discovery](getting_started/working_with_generic_types/resolver_discovery), +This method relies on [resolver discovery](/developer_guides/graphql/getting_started/working_with_generic_types/resolver_discovery), which you can learn more about in the documentation. -Alternatively, you can hardcode the resolver into your config: +Alternatively, you can [hardcode the resolver into your config](/developer_guides/graphql/getting_started/working_with_generic_types/resolver_discovery#field-resolvers). **app/_graphql/queries.yml** ```yaml latestPost: type: Post - resolver: ['MyResolvers', 'latestPost' ] + resolver: ['MyApp\Resolvers\MyResolvers', 'latestPost'] ``` -## ScaffoldingProviders are now SchemaUpdaters +## `ScaffoldingProvider`s are now `SchemaUpdater`s -If you were updating your schema with procedural code, you'll need to change your `ScaffoldingProvider` -interface to `SchemaUpdater`, and use the `updateSchema(Schema $schema): void` function. +The `ScaffoldingProvider` interface has been replaced with [`SchemaUpdater`](api:SilverStripe\GraphQL\Schema\Interfaces\SchemaUpdater). +If you were updating your schema with procedural code, you'll need to implement `SchemaUpdater` +and implement the [`updateSchema()`](api:SilverStripe\GraphQL\Schema\Interfaces\SchemaUpdater::updateSchema()) method. ### Upgrading @@ -235,21 +230,23 @@ class MyProvider implements SchemaUpdater } ``` +[alert] The API for procedural code has been **completely rewritten**. You'll need to rewrite all of the code in these classes. For more information on working with procedural code, read the -[using procedural code](getting_started/using_procedual_code) documentation. +[using procedural code](/developer_guides/graphql/getting_started/using_procedural_code) documentation. +[/alert] -## Goodbye, scaffolding, hello models +## Goodbye scaffolding, hello models -In the 3.x release, a massive footprint of the codebase was dedicated to a DataObject-specific API called -"scaffolding" that was used to generate types, queries, fields, and more from the ORM. In 4.x, that -approach has been moved to concept called **model types**. +In `silverstripe/graphql` 3.x, a massive footprint of the codebase was dedicated to a `DataObject`-specific API +called "scaffolding" that was used to generate types, queries, fields, and more from the ORM. In 4.x, that +approach has been replaced with a concept called **model types**. -A model type is just a type that is backed by a class that express awareness of its schema (like a DataObject!). +A model type is just a type that is backed by a class that has awareness of its schema (like a `DataObject`!). At a high-level, it needs to answer questions like: * Do you have field X? - What type is field Y? +* What type is field Y? * What are all the fields you offer? * What operations do you provide? * Do you require any extra types to be added to the schema? @@ -257,7 +254,7 @@ At a high-level, it needs to answer questions like: ### Upgrading The 4.x release ships with a model type implementation specifically for DataObjects, which you can use -a lot like the old scaffolding API. +a lot like the old scaffolding API. It's largely the same syntax, but a lot easier to read. **before** ```yaml @@ -285,6 +282,7 @@ SilverStripe\GraphQL\Manager: SilverStripe\Security\Member: fields: '*' operations: '*' + SilverStripe\CMS\Model\SiteTree: fields: title: true @@ -293,12 +291,12 @@ SilverStripe\CMS\Model\SiteTree: read: true ``` -## DataObject field names are lowerCamelCase by default +## `DataObject` GraphQL field names are lowerCamelCase by default The 3.x release of the module embraced an anti-pattern of using **UpperCamelCase** field names so that they could -map to the conventions of the ORM. This makes frontend code look awkward, and there's no great -reason for the Silverstripe CMS graphql server to break convention. In this major release, -the **lowerCamelCase** approach is encouraged. +map directly to the conventions of the ORM. This makes frontend code look awkward, and there's no great reason +for the Silverstripe CMS GraphQL server to break convention. In this major release, the **lowerCamelCase** +approach is encouraged. ### Upgrading @@ -343,11 +341,10 @@ query readPages { } ``` - -## DataObject type names are simpler +## `DataObject` type names are simpler To avoid naming collisions, the 3.x release of the module used a pretty aggressive approach to ensuring -uniqueness when converting a DataObject class name to a GraphQL type name, which was ``. +uniqueness when converting a `DataObject` class name to a GraphQL type name, which was ``. In the 4.x release, the typename is just the `shortName` by default, which is based on the assumption that most of what you'll be exposing is in your own app code, so collisions aren't that likely. @@ -362,46 +359,49 @@ Change any references to DataObject type names in your queries **after** `query SiteTrees {}` +[info] If this new pattern is not compatible with your set up (e.g. if you use feature-based namespacing), you have full -control over how types are named. You can use the `type_formatter` and `type_prefix` on `DataObjectModel` to -influence the naming computation. Read more about this in the [DataObject model type](getting_started/working_with_dataobjects/dataobject_model_type#customising-the-type-name) docs. +control over how types are named. You can use the `type_formatter` and `type_prefix` on +[`DataObjectModel`](api:SilverStripe\GraphQL\Schema\DataObject\DataObjectModel) to influence the naming computation. +Read more about this in the [DataObject model type](/developer_guides/graphql/getting_started/working_with_dataobjects/dataobject_model_type#customising-the-type-name) +docs. +[/info] -## The Connection class has been moved to plugins +## The `Connection` class has been replaced with plugins In the 3.x release, you could wrap a query in the `Connection` class to add pagination features. In 4.x, these features are provided via the new [plugin system](extending/plugins). -The good news is that all DataObject queries are paginated by default, and you shouldn't have to worry about -this, but if you are writing a custom query and want it paginated, check out the section on -[adding pagination to a custom query](getting_started/working_with_generic_types/adding_pagination). +The good news is that all `DataObject` queries are paginated by default, and you shouldn't have to worry about +this. But if you are writing a custom query and want it paginated, check out the section on +[adding pagination to a custom query](/developer_guides/graphql/getting_started/working_with_generic_types/adding_pagination). Additionally, the sorting features that were provided by `Connection` have been moved to a plugin dedicated to -`SS_List` results. Again, this plugin is applied to all DataObjects by default, and will include all of their -sortable fields by default. This is configurable, however. See the -[query plugins](getting_started/working_with_dataobjects/query_plugins) section for more information. - +`SS_List` results. Again, this plugin is applied to all `DataObject` classes by default, and will include all of their +sortable fields by default - though this is configurable. See the [query plugins](/developer_guides/graphql/getting_started/working_with_dataobjects/query_plugins) +section for more information. ### Upgrading There isn't much you have to do here to maintain compatibility. If you prefer to have a lot of control over what your sort fields are, check out the linked documentation above. -## Query filtering has been moved to a plugin +## Query filtering has been replaced with a plugin The previous `QueryFilter` API has been vastly simplified in a new plugin. Filtering is provided to all -read queries by default, and should include all filterable fields, including nested relationships. -This is configurable, however. See the -[query plugins](getting_started/working_with_dataobjects/query_plugins) section for more information. +read queries by default, and should include all filterable fields including nested relationships - though +this is configurable. See the [query plugins](/developer_guides/graphql/getting_started/working_with_dataobjects/query_plugins) +section for more information. ### Upgrading There isn't much you have to do here to maintain compatibility. If you prefer to have a lot of control over what your filter fields are, check out the linked documentation above. -## Query permissions have been moved to a plugin +## Query permissions have been replaced with a plugin -This was mostly an internal API, and shouldn't be affected in an upgrade, but if you want more information -on how it works, you can [read the permissions documentation](getting_started/working_with_dataobjects/permissions). +This was mostly an internal API, and shouldn't be affected in an upgrade - but if you want more information +on how it works you can [read the permissions documentation](/developer_guides/graphql/getting_started/working_with_dataobjects/permissions). ## Enums are first-class citizens @@ -421,3 +421,6 @@ Status: CANCELLED: Cancelled PENDING: Pending ``` + +See the [Enums, unions, and interfaces](/developer_guides/graphql/working_with_generic_types/enums_unions_and_interfaces/#enum-types) +documentation for more information. diff --git a/docs/en/04_Changelogs/4.11.0.md b/docs/en/04_Changelogs/4.11.0.md index 9e33813be68..aa8c84ad29f 100644 --- a/docs/en/04_Changelogs/4.11.0.md +++ b/docs/en/04_Changelogs/4.11.0.md @@ -8,6 +8,7 @@ title: 4.11.0 (unreleased) - [Regression test and Security audit](#audit) - [Dropping support for PHP 7.3](#phpeol) +- [GraphQL v4 major release](#graphqlv4) - [Features and enhancements](#features-and-enhancements) - [Upload and use WebP images in the CMS](#webp) - [Preview any DataObject in any admin section](#cms-preview) @@ -28,6 +29,62 @@ While it is still advised that you perform your own due diligence when upgrading In accordance with our [PHP support policy](/Getting_Started/Server_Requirements), Silverstripe CMS Recipe release 4.11.0 drops support for PHP 7.3. We expect to drop support for PHP 7 altogether around January 2023. +## GraphQL 4 major release {#graphqlv4} + +Silverstripe CMS Recipe 4.11 defaults to installing `silverstripe/graphql` version 4, which has just has a stable major release. Previous releases installed version 3. + +### What does `silverstripe/graphql` do and why are you changing this? + +GraphQL is a query language for APIs. It was initially designed by Facebook but it is now used widely across the internet by all sorts of organisations including GitHub, AirBnB, Lyft, PayPal, Shopify and Silverstripe CMS … to name just a few. + +`silverstripe/graphql` is an implementation of GraphQL specific to Silverstripe CMS. It is used to power some aspects of the CMS UI. It can also be used by developers to create APIs that other web services can use to read or update data in your CMS sites. This opens a lot of use cases like using Silverstripe CMS as “headless” CMS. + +Up until CMS Recipe 4.11, Silverstripe CMS would default to using `silverstripe/graphql` version 3. While `silverstripe/graphql` v3 was sufficient to support the basic CMS use cases it was being used for, it was not performant enough to build more complex applications. + +`silverstripe/graphql` v4 is a complete rewrite and provides substantial performance improvements. + +`silverstripe/graphql` v4 provides developers a first class tool for building APIs and allowing third party services to integrate with their Silverstripe CMS websites. + +### What do I need to know to get started? + +If you do not have a custom schema, all you need to know is: + +- There is a new `.graphql-generated` folder that your web server user will need write access to. + - By default this sits directly in your project root. If your project root is not currently writable, you will need to create the new folder yourself and set the appropriate permissions for it. +- The GraphQL schema for the CMS will need to be generated. For the most common hosting scenarios you will be fine letting this happen during dev/build, but read the [building the schema](/developer_guides/graphql/getting_started/building_the_schema) documentation to know what your options are - especially if you have a multi-server hosting solution. + +If you were already using GraphQL v3 for your own custom schema and queries and want to upgrade to v4, read the [Upgrading to GraphQL 4](/upgrading/upgrading_to_graphql_4) documentation. + +### That sounds risky, do I absolutely have to use version 4? + +Silverstripe CMS has been shipping with dual support for `silverstripe/graphql` v3 and v4 since the 4.8 release. Until now `silverstripe/graphql` v4 had been in alpha and you had to explicitly opt-in to get it. At Silverstripe, we are already using `silverstripe/graphql` v4 in production on several projects. + +All the supported Silverstripe CMS modules that use `silverstripe/graphql` have dual-support. If you wish to stay on `silverstripe/graphql` v3, you can do so and it will not block you from upgrading to Silverstripe CMS 4.11. + +#### Opting out of `silverstripe/graphql` version 4 and sticking to version 3 + +If your project composer.json file already explicitly requires silverstripe/graphql, you don’t need to do anything. + +If your project uses silverstripe/recipe-cms, it will install silverstripe/graphql:^4.0 when you upgrade to the 4.11 release. To stay on silverstripe/graphql:^3, you'll need to "inline" the `silverstripe/recipe-cms` requirements in your root composer.json and change `silverstripe/graphql` to `^3`. + +You can inline `silverstripe/recipe-cms` by running this command: + +``` +composer update-recipe silverstripe/recipe-cms +``` + +If your project does not directly require `silverstripe/recipe-cms` or `silverstripe/graphql`, you may still be getting `silverstripe/graphql` installed if you require other modules that depend on it. To fix your `silverstripe/graphql` to version 3, run this composer command: + +`composer require silverstripe/graphql:^3` + +To validate which version of `silverstripe/graphql` your project is using, run this composer command: + +`composer show silverstripe/graphql` + +To view which dependencies require `silverstripe/graphql`, run this composer command: + +`composer why silverstripe/graphql` + ## Features and enhancements {#features-and-enhancements} ### Upload and use WebP images {#webp}