silverstripe-framework/docs/en/02_Developer_Guides/19_GraphQL/02_working_with_dataobjects/02_query_plugins.md

311 lines
6.4 KiB
Markdown

---
title: DataObject query plugins
summary: Learn about some of the useful goodies that come pre-packaged with DataObject queries
---
# Working with DataObjects
[CHILDREN asList]
[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]
## DataObject query plugins
This module has a [plugin system](../plugins) that affords extensibility to queries, mutations,
types, fields, and just about every other thread of the schema. Model types can define default
plugins to include, and for DataObject queries, these include:
* filter
* sort
* paginateList
* inheritance
* canView (read, readOne)
* firstResult (readOne)
When the `silverstripe/cms` module is installed, a plugin known as `getByLink` is also added.
Other modules, such as `silverstripe-versioned` may augment that list with even more.
### The pagination plugin
The pagination plugin augments your queries in two main ways:
* Adding `limit` and `offset` arguments
* Wrapping the return type in a "connection" type with the following fields:
* `nodes: '[YourType]'`
* `edges: '[{ node: YourType }]'`
* `pageInfo: '{ hasNextPage: Boolean, hasPreviousPage: Boolean: totalCount: Int }'`
Let's test it out:
```graphql
query {
readPages(limit: 10, offset: 20) {
nodes {
title
}
edges {
node {
title
}
}
pageInfo {
totalCount
hasNextPage
hasPrevPage
}
}
```
[notice]
If you're not familiar with the jargon of `edges` and `node`, don't worry too much about it
for now. It's just a pretty well-established convention for pagination in GraphQL, mostly owing
to its frequent use with [cursor-based pagination](https://graphql.org/learn/pagination/), which
isn't something we do in Silverstripe CMS.
[/notice]
#### Disabling pagination
Just set it to `false` in the configuration.
*app/_graphql/models.yml*
```yaml
MyProject\Models\ProductCategory:
operations:
read:
plugins:
paginateList: false
```
To disable pagination globally, use `modelConfig`:
*app/_graphql/modelConfig.yml*
```yaml
DataObject:
operations:
read:
plugins:
paginateList: false
```
### The filter plugin
The filter plugin (`SilverStripe\GraphQL\Schema\DataObject\Plugin\QueryFilter`) adds a
special `filter` argument to the `read` and `readOne` operations.
```yaml
query {
readPages(
filter: { title: { eq: "Blog" } }
) {
nodes {
title
created
}
}
```
In the above example, the `eq` is known as a *comparator*. There are several of these
included with the the module, including:
* `eq` (exact match)
* `ne` (not equal)
* `contains` (fuzzy match)
* `gt` (greater than)
* `lt` (less than)
* `gte` (greater than or equal)
* `lte` (less than or equal)
* `in` (in a given list)
* `startswith` (starts with)
* `endswith` (ends with)
Example:
```graphql
query {
readPages (
filter: {
title: { ne: "Home" },
created: { gt: "2020-06-01", lte: "2020-09-01" }
}
) {
nodes {
title
created
}
}
```
[notice]
While it is possible to filter using multiple comparators, segmenting them into
disjunctive groups (e.g. "OR" and "AND" clauses) is not yet supported.
[/notice]
Nested fields are supported by default:
```graphql
query {
readProductCategories(
filter: {
products: {
reviews: {
rating: { gt: 3 },
comment: { contains: "awesome" },
author: { ne: "Me" }
}
}
}
) {
nodes {
title
}
}
```
Filters are only querying against the database by default,
it is not possible to filter by fields with custom resolvers.
#### Customising the filter fields
By default, all fields on the dataobject, including relationships, are included. To customise
this, just add a `fields` config to the plugin definition:
*app/_graphql/models.yml*
```yaml
MyProject\Models\ProductCategory:
fields:
title: true
featured: true
operations:
read:
plugins:
filter:
fields:
title: true
```
#### Disabling the filter plugin
Just set it to `false` in the configuration.
*app/_graphql/models.yml*
```yaml
MyProject\Models\ProductCategory:
operations:
read:
plugins:
filter: false
```
To disable filtering globally, use `modelConfig`:
*app/_graphql/modelConfig.yml*
```yaml
DataObject:
operations:
read:
plugins:
filter: false
```
### The sort plugin
The sort plugin (`SilverStripe\GraphQL\Schema\DataObject\Plugin\QuerySort`) adds a
special `sort` argument to the `read` and `readOne` operations.
```graphql
query {
readPages (
sort: { created: DESC }
) {
nodes {
title
created
}
}
}
```
Nested fields are supported by default, but only for linear relationships (e.g `has_one`):
```graphql
query {
readProducts(
sort: {
primaryCategory: {
lastEdited: DESC
}
}
) {
nodes {
title
}
}
}
```
#### Customising the sort fields
By default, all fields on the dataobject, including `has_one` relationships, are included.
To customise this, just add a `fields` config to the plugin definition:
*app/_graphql/models.yml*
```yaml
MyProject\Models\ProductCategory:
fields:
title: true
featured: true
operations:
read:
plugins:
sort:
fields:
title: true
```
#### Disabling the sort plugin
Just set it to `false` in the configuration.
*app/_graphql/models.yml*
```yaml
MyProject\Models\ProductCategory:
operations:
read:
plugins:
sort: false
```
To disable sort globally, use `modelConfig`:
*app/_graphql/config.yml*
```yaml
modelConfig:
DataObject:
operations:
read:
plugins:
sort: false
```
### The getByLink plugin
When the `silverstripe/cms` module is installed (it is in most cases), a plugin called `getByLink`
will ensure that queries that return a single DataObject model (e.g. readOne) get a new query argument
called `link` (configurable on the `field_name` property of `LinkablePlugin`).
```graphql
readOneSiteTree(link: "/about-us" ) {
title
}
```
### Further reading
[CHILDREN]