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 `<vendorName><shortName>`.
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.
### Upgrading
Change any references to DataObject type names in your queries
**before**
`query SilverStripeSiteTrees {}`
**after**
`query SiteTrees {}`
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.
## The Connection class has been moved to 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).
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.
### 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
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.
### 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
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).
## Enums are first-class citizens
In the 3.x release, there was no clear path to creating enum types, but in 4.x, they have a prime spot in the
configuration layer.
**before**
(A type creator that has been hacked to return an `Enum` singleton?)