mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-09-19 16:06:32 +02:00
311 lines
6.4 KiB
Markdown
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]
|