|
| 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. |
| 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 | +* Etc. |
| 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 actually 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, like notifications or modals, are rendered in the correct context. |
| 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 | +```text |
| 25 | +Element → (Context) → Repository → Data Source(s) |
| 26 | +``` |
| 27 | + |
| 28 | +### Using an existing Repository <a href="#using-a-repository" id="using-a-repository"></a> |
| 29 | + |
| 30 | +Often, you will find that data is already available and observable in a [context](./contexts/README.md), such as the Workspace Context. 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. |
| 31 | + |
| 32 | +When a context with the appropriate data state is not available, reaching for a repository will ensure access to the needed information no matter the current application state. |
| 33 | + |
| 34 | +```typescript |
| 35 | +import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api'; |
| 36 | +import { LitElement} from '@umbraco-cms/backoffice/external/lit'; |
| 37 | +import {UmbDocumentDetailRepository} from '@umbraco-cms/backoffice/document'; |
| 38 | + |
| 39 | +class MyElement extends UmbElementMixin(LitElement) { |
| 40 | + ... |
| 41 | + #documentRepository = new UmbDocumentDetailRepository(this); |
| 42 | + |
| 43 | + firstUpdated() { |
| 44 | + const { data, error } = await this.#documentRepository.requestByUnique('some-unique-key'); |
| 45 | + console.log('The Document Data:', data); |
| 46 | + } |
| 47 | + ... |
| 48 | +} |
| 49 | + |
| 50 | +const documentRepository = new UmbDocumentDetailRepository(this); |
| 51 | + |
| 52 | +``` |
| 53 | + |
| 54 | +### Register a custom Repository <a href="#register-a-custom-repository" id="register-a-custom-repository"></a> |
| 55 | + |
| 56 | +By registering your repository in the [Extension Registry](../../extension-registry/README.md) you make it available to use in different extension kinds that requires a repository alias. |
| 57 | + |
| 58 | +Some of the common repository interfaces are: |
| 59 | +* [UmbDetailRepository](./repository-types/detail-repository.md) - for detail views of a single entity. |
| 60 | +* [UmbCollectionRepository](./repository-types/collection-repository.md) - for collection views of multiple entities. |
| 61 | +* [UmbTreeRepository](./repository-types/tree-repository.md) - for tree structures of entities. |
| 62 | +* [UmbItemRepository](./repository-types/item-repository.md) - for item requests. |
| 63 | + |
| 64 | +See the example below of how to register a custom repository: |
| 65 | + |
| 66 | +```typescript |
| 67 | +import { umbExtensionsRegistry } from "@umbraco-cms/backoffice/extension-registry"; |
| 68 | + |
| 69 | +interface MyEntityDetailModel { |
| 70 | + unique: string; |
| 71 | + entityType: string; |
| 72 | +} |
| 73 | + |
| 74 | +class MyEntityDetailRepository implements UmbDetailRepository<MyEntityDetailModel> { |
| 75 | + // Implement repository methods here |
| 76 | +} |
| 77 | + |
| 78 | +const repositoryManifest = { |
| 79 | + type: "repository", |
| 80 | + alias: "My.Repository.EntityDetail", |
| 81 | + name: "My Entity Detail Repository", |
| 82 | + api: MyRepository, |
| 83 | +}; |
| 84 | + |
| 85 | +umbExtensionsRegistry.register(repositoryManifest); |
| 86 | +``` |
| 87 | + |
0 commit comments