Skip to content

Commit 46b6dd1

Browse files
authored
Merge pull request #7553 from madsrasmussen/v17/update-repository-docs
Backoffice Repositories
2 parents e22d974 + 0efdcb6 commit 46b6dd1

File tree

10 files changed

+177
-51
lines changed

10 files changed

+177
-51
lines changed

17/umbraco-cms/.gitbook.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,6 @@ redirects:
148148
fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date: fundamentals/backoffice/property-editors/built-in-umbraco-property-editors/date-time-editor/README.md
149149
customizing/extending-overview/extension-types/workspaces/workspace-action-menu-item: customizing/extending-overview/extension-types/workspaces/workspace-action-menu-items.md
150150
customizing/extending-overview/extension-types/workspaces/workspace-footer-app: customizing/extending-overview/extension-types/workspaces/workspace-footer-apps.md
151+
customizing/foundation/repositories: customizing/foundation/repositories/README.md
151152
customizing/extending-overview/extension-kind: customizing/extending-overview/extension-types/kind.md
152153

17/umbraco-cms/.gitbook/assets/data-flow.svg

Lines changed: 0 additions & 19 deletions
This file was deleted.

17/umbraco-cms/SUMMARY.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,12 @@
213213
* [Context API](customizing/foundation/context-api/README.md)
214214
* [Consume a Context](customizing/foundation/context-api/consume-a-context.md)
215215
* [Provide a Context](customizing/foundation/context-api/provide-a-context.md)
216-
* [Repositories](customizing/foundation/repositories.md)
216+
* [Repositories](customizing/foundation/repositories/README.md)
217+
* [Repository Types](customizing/foundation/repositories/repository-types/README.md)
218+
* [Collection Repository](customizing/foundation/repositories/repository-types/collection-repository.md)
219+
* [Detail Repository](customizing/foundation/repositories/repository-types/detail-repository.md)
220+
* [Item Repository](customizing/foundation/repositories/repository-types/item-repository.md)
221+
* [Tree Repository](customizing/foundation/repositories/repository-types/tree-repository.md)
217222
* [States](customizing/foundation/states.md)
218223
* [UI Sorting](customizing/foundation/sorting.md)
219224
* [Routes](customizing/foundation/routes.md)

17/umbraco-cms/customizing/foundation/fetching-data/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,6 @@ After fetching data, the next step is to execute the request. You can use the `t
5555
### [Custom Generated Client](custom-generated-client.md)
5656

5757
For advanced scenarios, you can generate a custom client for your API using tools like [@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts). This approach is ideal when working with custom API controllers or when you need type-safe, reusable client code.
58+
59+
### [Repositories](../repositories/README.md)
60+
Repositories provide a structured way to manage data operations in the Backoffice. They abstract the data access layer, allowing for easier maintenance and scalability.

17/umbraco-cms/customizing/foundation/repositories.md

Lines changed: 0 additions & 31 deletions
This file was deleted.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Repositories
2+
Repositories provide a structured way to manage data operations in the Backoffice. They abstract the data access layer, allowing for easier reuse and scalability.
3+
4+
Repositories create separation between domain logic and data access. By providing a known interface for data requests, we can reuse UI components across different domains. For example, we have a generic UX flow for deleting an entity. By supplying this flow with a repository that has a known interface for deletion, we can use the same UX flow to delete any entity. The same applies to Trees, Collections, Workspaces, and more.
5+
6+
Additionally, repositories can utilize different data sources depending on the application's state. These sources may include:
7+
8+
* A REST API
9+
* Offline storage
10+
* A local cache
11+
* And more.
12+
13+
This abstraction ensures that consumers don’t need to worry about how to access data. The repository serves as the Backoffice’s entry point for requesting new data. As a result, we achieve a loosely coupled connection between consumers and data storage procedures, effectively hiding complex implementations.
14+
15+
* **Repository:** defines what data operations are available (get, add, update, delete).
16+
* **Data Source:** defines how data is fetched or stored.
17+
18+
### Data flow with a repository <a href="#data-flow-with-a-repository" id="data-flow-with-a-repository"></a>
19+
20+
A repository must be instantiated where it is used. It should take an [UmbController](../umbraco-controller/README.md) as part of the constructor. This ensures that any contexts consumed in the repository are scoped correctly.
21+
22+
A repository can be initialized directly from an element, but will often be instantiated in a [context](../context-api/README.md), like the Workspace Context.
23+
24+
The data flow when using a repository can be illustrated as follows:
25+
26+
```text
27+
(Data Source) -> Repository -> (Controller/Context) -> Element
28+
```
29+
30+
### Using an existing Repository <a href="#using-a-repository" id="using-a-repository"></a>
31+
32+
Often, you will find that data is already available and observable in a [context](../contexts/README.md). In that case, subscribing to the context [state](../states.md) will be the right approach to take. This way, you will receive all runtime updates that occur to the data throughout the session.
33+
34+
If the needed data isn’t available in a context, use a repository to request the data. This will give you the correct data no matter the current application state.
35+
36+
In the example below, we instantiate the `UmbDocumentItemRepository` directly in a custom element to request Document Item data by its unique key.
37+
38+
```typescript
39+
import { LitElement} from '@umbraco-cms/backoffice/external/lit';
40+
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
41+
import { UmbDocumentItemRepository } from '@umbraco-cms/backoffice/document';
42+
43+
// Simplified element
44+
class MyElement extends UmbElementMixin(LitElement) {
45+
...
46+
#documentItemRepository = new UmbDocumentItemRepository(this);
47+
48+
firstUpdated() {
49+
const { data, error } = await this.#documentItemRepository.requestItems(['some-unique-key', 'another-unique-key']);
50+
console.log('Response', data, error);
51+
// Render data in the element
52+
}
53+
...
54+
}
55+
```
56+
57+
Alternatively, you can instantiate the repository in a [controller](../umbraco-controller/README.md) or [context](../context-api/README.md), store the data in a [state](../states.md), and then observe that state in your element. This is often the preferred approach as it allows for better separation of concerns and reusability across different components.
58+
59+
```typescript
60+
import { UmbArrayState } from '@umbraco-cms/backoffice/observable-api';
61+
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
62+
import { UmbDocumentItemRepository } from '@umbraco-cms/backoffice/document';
63+
64+
export class MyController extends UmbControllerBase {
65+
66+
#items = new UmbArrayState<DocumentItemModel>([]);
67+
items = this.#items.asObservable();
68+
69+
#documentItemRepository = new UmbDocumentItemRepository(this);
70+
71+
constructor(host: UmbControllerHost) {
72+
super(host);
73+
this.#load();
74+
}
75+
76+
async #load() {
77+
const { data, error } = await this.#documentItemRepository.requestItems(['some-unique-key', 'another-unique-key']);
78+
console.log('Response', data, error);
79+
this.#items.setValue(data ?? []);
80+
// The items state can now be observed by any element initializing this controller
81+
}
82+
}
83+
```
84+
85+
86+
### Register a custom Repository <a href="#register-a-custom-repository" id="register-a-custom-repository"></a>
87+
88+
By registering your repository in the [Extension Registry](../../extending-overview/extension-registry/README.md), you make it available to use in different extension kinds that require a repository alias.
89+
90+
Some of the common repository interfaces are:
91+
* [UmbDetailRepository](./repository-types/detail-repository.md) - for detail views of a single entity.
92+
* [UmbCollectionRepository](./repository-types/collection-repository.md) - for collection views of multiple entities.
93+
* [UmbTreeRepository](./repository-types/tree-repository.md) - for tree structures of entities.
94+
* [UmbItemRepository](./repository-types/item-repository.md) - for item requests.
95+
96+
See the example below of how to register a custom repository:
97+
98+
```typescript
99+
import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry";
100+
import { UmbRepositoryBase } from "@umbraco-cms/backoffice/repository";
101+
import type { UmbTreeRepository } from "@umbraco-cms/backoffice/tree";
102+
103+
class MyEntityTreeRepository extends UmbRepositoryBase implements UmbTreeRepository {
104+
// Implement repository methods here
105+
}
106+
107+
const repositoryManifest = {
108+
type: "repository",
109+
alias: "My.Repository.EntityTree",
110+
name: "My Entity Tree Repository",
111+
api: MyEntityTreeRepository,
112+
};
113+
114+
umbExtensionsRegistry.register(repositoryManifest);
115+
```
116+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Collection Repository
2+
3+
A collection repository is a specific type of repository designed to handle operations related to collections of items. It provides methods to request collections of data in a filtered and paginated manner.
4+
5+
The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/interfaces/packages_core_collection.UmbCollectionRepository.html).
6+
7+
```typescript
8+
interface UmbCollectionRepository {
9+
requestCollection();
10+
}
11+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Detail Repository
2+
3+
A detail repository is a specific type of repository designed to handle operations related to individual entities. It provides methods to create, retrieve, update, and delete single entities.
4+
5+
The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/interfaces/packages_core_repository.UmbDetailRepository.html).
6+
7+
```typescript
8+
interface UmbDetailRepository {
9+
createScaffold();
10+
create();
11+
requestByUnique();
12+
save();
13+
delete();
14+
}
15+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Item Repository
2+
3+
An item repository is a specific type of repository designed to handle operations related to multiple individual items. It provides methods to request multiple items based on unique identifiers.
4+
5+
The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/interfaces/packages_core_repository.UmbItemRepository.html).
6+
7+
```typescript
8+
interface UmbItemRepository {
9+
requestItems();
10+
}
11+
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Tree Repository
2+
3+
A tree repository is a specific type of repository designed to handle operations related to tree data structures. It provides methods to request tree roots, tree items, and their ancestors.
4+
5+
The interface below is simplified for clarity and omits return types and arguments. See full interfaces in the [UI API Documentation](https://apidocs.umbraco.com/v17/ui-api/interfaces/packages_core_tree.UmbTreeRepository.html).
6+
7+
```typescript
8+
interface UmbTreeRepository {
9+
requestTreeRoot();
10+
requestTreeRootItems();
11+
requestTreeItemsOf();
12+
requestTreeItemAncestors();
13+
}
14+
```

0 commit comments

Comments
 (0)