Skip to content

Commit

Permalink
DOC Update react injector GraphQL example for CMS 5
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Apr 18, 2023
1 parent ff15a00 commit a343a9e
Showing 1 changed file with 10 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ Here's what that might look like:
```js
import React from 'react';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';
import { graphql } from '@apollo/client/react/hoc';

export const Notes = ({ notes }) => (
<ul className="notes">
Expand Down Expand Up @@ -869,8 +869,6 @@ export default NotesWithData;

Next we'll expose the model to GraphQL:

#### Graphql v4 {#build-extensible-gql-app-v4}

**my-module/_config/graphql.yml**

```yml
Expand All @@ -896,29 +894,6 @@ App\Model\Note:
paginateList: false
```
#### Graphql v3 {#build-extensible-gql-app-v3}
**my-module/_config/graphql.yml**
```yml
# Tell graphql how to scaffold the schema for our model inside the admin schema
SilverStripe\GraphQL\Manager:
schemas:
admin:
scaffolding:
types:
App\Model\Note:
fields: [ id, content ]
operations:
read:
paginate: false
name: readNotes
```
[hint]
Graphql v3 uses the first part of the model class's namespace in the default query/mutation names - so with a class `App\Model\Note` the default read operation would be `readAppNotes`. The example above has overridden the default name to keep it consistent with Graphql v4 behaviour.
[/hint]

#### Define the app
Finally, let's make a really simple container app which holds a header and our notes component, and inject it into the DOM using entwine.
Expand All @@ -943,7 +918,7 @@ export default App;
```js
import ReactDOM from 'react-dom';
import React from 'react';
import { ApolloProvider } from 'react-apollo';
import { ApolloProvider } from '@apollo/client';
import Injector from 'lib/Injector';
import App from './App';

Expand All @@ -968,6 +943,10 @@ Injector.ready(() => {
});
```

[info]
`this[0]` is how we get the underlying pure javascript node that the jQuery object is wrapping. We can't pass `this` directly into the `ReactDOM.render` function because react doesn't know how to deal with a jQuery object wrapper.
[/info]

The `silverstripe/admin` module provides `apolloClient` and `store` objects in the global namespace to be shared by other modules. We'll make use of those, and create our own app wrapped in `<ApolloProvider />`.

We register a callback with `Injector.ready()` because the `apolloClient` and `store` are ultimately coming from the injector, so we need to make sure those are ready before mounting our component.
Expand Down Expand Up @@ -1164,7 +1143,7 @@ Since almost everything is in `Injector` now, we need to update our mounting log
import ReactDOM from 'react-dom';
import React from 'react';
import registerDependencies from './boot/registerDependencies';
import { ApolloProvider } from 'react-apollo';
import { ApolloProvider } from '@apollo/client';
import Injector, { provideInjector } from 'lib/Injector';
import App from './App';

Expand Down Expand Up @@ -1215,8 +1194,6 @@ App\Model\Note:
- MyOtherApp\Extension\NoteExtension
```
##### Graphql 4 {#applying-extensions-gql-v4}

Remember, this example is in a project which is customising the schema from the previous example, so we still have to tell graphql where to find our schema modifications.
If you're following along, you could declare a different folder than before within the same project so you can see how the schema definitions merge together into a single schema.
Expand All @@ -1239,20 +1216,6 @@ App\Model\Note:
priority: true
```
##### Graphql 3 {#applying-extensions-gql-v3}

**app/_config/graphql.yml**

```yml
SilverStripe\GraphQL\Manager:
schemas:
admin:
scaffolding:
types:
App\Model\Note:
fields: [ priority ]
```

#### Creating transforms
Let's first update the `NotesListItem` to contain our new field.
Expand Down Expand Up @@ -1431,7 +1394,7 @@ const mutation = {
mutate({
variables: {
input: {
content, // For graphql v3 this needs to start with a capital letter, i.e. Content: content
content,
}
}
});
Expand All @@ -1440,7 +1403,7 @@ const mutation = {
}
},
templateName: CREATE,
singularName: 'Note', // For graphql v3 this needs to be "AppNote"
singularName: 'Note',
pagination: false,
fields: [
'content',
Expand All @@ -1451,16 +1414,10 @@ const mutation = {
export default mutation;
```

[notice]
With graphql v3, the field names in the input object have to start with capital letters, and the input _type_ can't easily be overridden - it's always the first part of your namespace, then the class name, then "CreateInputType". So assuming your model's fully qualified classname is `App\Model\Note`, the input type is `AppNoteCreateInputType`.
[/notice]

It looks like a lot of code, but if you're familiar with Apollo mutations, this is pretty standard. The supplied `mutate()` function gets mapped to a prop - in this case `onAdd`, which the `AddForm` component is configured to invoke. We've also supplied the `singularName` as well as the template `CREATE` for the `createNote` scaffolded mutation.

And make sure we're exposing the mutation in our graphql schema:

#### Graphql 4 {#extensible-mutations-gql-v4}

**my-module/_graphql/models.yml**

```yml
Expand All @@ -1471,27 +1428,6 @@ App\Model\Note:
create: true
```
#### Graphql 3 {#extensible-mutations-gql-v3}
**my-module/_config/graphql.yml**
```yml
SilverStripe\GraphQL\Manager:
schemas:
admin:
scaffolding:
types:
App\Model\Note:
#...
operations:
#...
create: true
```
[notice]
Unlike with the read query, the injector isn't able to handle mutations with custom names.
[/notice]
Lastly, let's just register all this with `Injector`.

**my-module/client/src/boot/registerDependencies.js**
Expand Down Expand Up @@ -1566,7 +1502,7 @@ const transformCreateNote = (manager) => {
variables: {
input: {
// Don't forget to keep the content variable in here!
content, // In GraphQL v3 these must both start with capital letters (i.e. `Content: content` and `Priority: priority`)
content,
priority,
}
}
Expand Down

0 comments on commit a343a9e

Please sign in to comment.