# Domain

Domains are curated, top-level categories for organizing data assets within an organization. They represent logical groupings that typically align with business units, departments, or functional areas. Unlike tags which are informal labels, Domains provide a structured way to organize assets with centralized or distributed management. A data asset can belong to only one Domain at a time.

## Identity

Domains are identified by a single piece of information:

- A unique domain id: This is a string identifier that uniquely identifies the domain within DataHub. The id can be either auto-generated by DataHub or manually specified during domain creation. When creating a domain via the UI or API without specifying an id, DataHub will auto-generate a UUID-based identifier. For programmatic access or when human-readable identifiers are desired, you can specify a custom id like "marketing", "engineering", or "finance".

An example of a domain identifier is `urn:li:domain:marketing`.

For auto-generated domains, the URN might look like `urn:li:domain:6289fccc-4af2-4cbb-96ed-051e7d1de93c`.

## Important Capabilities

### Domain Properties

Domain properties are stored in the `domainProperties` aspect and contain the core metadata about a domain:

- **Name**: The display name of the domain (e.g., "Marketing", "Platform Engineering")
- **Description**: An optional detailed description of what the domain represents
- **Parent Domain**: Domains can be hierarchical, with child domains nested under parent domains. This allows for organizational structures like "Engineering" > "Data Engineering" > "Data Platform"
- **Created Timestamp**: Audit information about when the domain was created

Here is an example of creating a domain with properties:

<details>
<summary>Python SDK: Create a domain</summary>

```python
{{ inline /metadata-ingestion/examples/library/domain_create.py show_path_as_comment }}
```

</details>

### Nested Domain Hierarchies

Domains support hierarchical organization through parent-child relationships. This enables representing organizational structures with multiple levels. For example, you might have a top-level "Engineering" domain with child domains for "Data Engineering", "ML Engineering", and "Infrastructure Engineering".

<details>
<summary>Python SDK: Create a nested domain</summary>

```python
{{ inline /metadata-ingestion/examples/library/domain_create_nested.py show_path_as_comment }}
```

</details>

### Ownership

Like other entities in DataHub, domains can have owners assigned to them using the `ownership` aspect. Domain owners are typically responsible for:

- Managing which assets belong to the domain
- Maintaining domain metadata and documentation
- Governing data quality standards within the domain
- Serving as points of contact for domain-related questions

Ownership types for domains follow the same patterns as other entities, including `TECHNICAL_OWNER`, `BUSINESS_OWNER`, `DATA_STEWARD`, etc.

<details>
<summary>Python SDK: Add an owner to a domain</summary>

```python
{{ inline /metadata-ingestion/examples/library/domain_add_owner.py show_path_as_comment }}
```

</details>

### Documentation and Links

Domains support documentation through the `institutionalMemory` aspect, which allows linking to external resources such as:

- Confluence pages describing the domain's purpose and scope
- Documentation about data governance policies
- Team wikis or handbooks
- Onboarding guides for the domain

<details>
<summary>Python SDK: Add documentation links to a domain</summary>

```python
{{ inline /metadata-ingestion/examples/library/domain_add_documentation.py show_path_as_comment }}
```

</details>

### Assigning Assets to Domains

The primary purpose of domains is to organize data assets. Assets are assigned to domains using the `domains` aspect on the asset entity (not on the domain entity itself). This creates a relationship between the asset and the domain.

<details>
<summary>Python SDK: Assign a dataset to a domain</summary>

```python
{{ inline /metadata-ingestion/examples/library/dataset_add_domain.py show_path_as_comment }}
```

</details>

When you assign an asset to a domain, it will:

- Appear in the domain's entity list in the UI
- Be filterable by domain in search results
- Show the domain badge on the asset's profile page

### Querying Domains

You can query domains and their associated entities using both the REST API and GraphQL API.

#### Fetching Domain Information via REST API

<details>
<summary>REST API: Get domain by URN</summary>

```bash
curl 'http://localhost:8080/entities/urn%3Ali%3Adomain%3Amarketing' \
  -H 'Authorization: Bearer <token>'
```

This will return the domain entity with all its aspects, including:

- `domainKey`: The unique identifier
- `domainProperties`: Name, description, parent domain
- `ownership`: Owners of the domain
- `institutionalMemory`: Links and documentation

</details>

#### Listing Assets in a Domain

Domains maintain relationships to all assets assigned to them. You can query these relationships to find all entities within a domain.

<details>
<summary>REST API: Find all assets in a domain</summary>

```bash
curl 'http://localhost:8080/relationships?direction=INCOMING&urn=urn%3Ali%3Adomain%3Amarketing&types=AssociatedWith' \
  -H 'Authorization: Bearer <token>'
```

This returns all entities that have been associated with the specified domain.

</details>

<details>
<summary>Python SDK: Query domain from a dataset</summary>

```python
{{ inline /metadata-ingestion/examples/library/dataset_query_domain.py show_path_as_comment }}
```

</details>

### Searching and Filtering by Domain

Once assets are assigned to domains, you can:

- Filter search results by domain using the domain filter
- Search within a specific domain to find assets
- Use domains as part of complex search queries

The `domains` field on assets is indexed and searchable, making it efficient to filter large datasets by domain membership.

<details>
<summary>Python SDK: Search for entities in a domain</summary>

```python
{{ inline /metadata-ingestion/examples/library/search_filter_by_domain.py show_path_as_comment }}
```

</details>

## Integration Points

Domains integrate with several key DataHub features:

### Relationship to Other Entities

Domains have relationships with:

- **Data Assets**: Datasets, dashboards, charts, ML models, and other data assets can be assigned to domains via the `domains` aspect
- **Parent Domains**: Domains can have parent-child relationships, creating hierarchical organizational structures
- **Users and Groups**: Domains have owners (via the `ownership` aspect) who are responsible for managing the domain

### GraphQL Resolvers

The domain entity is supported by several GraphQL resolvers in the `datahub-graphql-core` module:

- `CreateDomainResolver`: Creates new domains
- `SetDomainResolver`: Assigns assets to domains
- `UnsetDomainResolver`: Removes assets from domains
- `ListDomainsResolver`: Lists all available domains
- `DeleteDomainResolver`: Deletes a domain
- `DomainEntitiesResolver`: Retrieves all entities within a domain
- `ParentDomainsResolver`: Resolves the parent hierarchy of a domain
- `BatchSetDomainResolver`: Assigns multiple assets to a domain in one operation
- `MoveDomainResolver`: Moves a domain to a different parent

### Usage Patterns

Common usage patterns include:

1. **Data Mesh Organization**: Using domains to represent different data product teams or business domains
2. **Departmental Structure**: Organizing assets by company departments (Finance, Marketing, Engineering)
3. **Product Lines**: Grouping assets by product or business line
4. **Regulatory Boundaries**: Separating assets by compliance requirements or data residency rules
5. **Nested Structures**: Creating hierarchical organizations like Region > Country > Business Unit

### Integration with Ingestion

During metadata ingestion, domains can be automatically assigned using the `domain` configuration in ingestion recipes. This allows:

- Bulk assignment of domains based on naming patterns
- Automated domain assignment during discovery
- Consistent domain tagging across similar assets

See the [Domains feature guide](https://docs.datahub.com/docs/domains) for detailed ingestion configuration examples.

## Notable Exceptions

### Single Domain Assignment

Unlike tags and glossary terms which support multiple assignments, an asset can belong to only one domain at a time. If you assign an asset to a new domain, it will automatically be removed from its previous domain.

### Domain Resolution During Ingestion

When using bare domain names (like "Marketing") in ingestion recipes, DataHub will attempt to resolve them to provisioned domains. The resolution process checks:

1. First, for a domain with URN `urn:li:domain:Marketing`
2. Then, for any domain with the name "Marketing"

If resolution fails, ingestion will fail to ensure data integrity. To avoid resolution issues, you can use fully-qualified domain URNs in ingestion configurations.

### Hierarchical Considerations

When organizing domains hierarchically:

- Assets are assigned to the most specific (leaf) domain, not to parent domains
- Parent domains do not automatically inherit assets from child domains
- Domain hierarchies are primarily for organizational clarity in the UI
- Deleting a parent domain does not automatically delete or reassign child domains

### Permissions

Managing domains requires the "Manage Domains" platform privilege. This includes:

- Creating new domains
- Modifying domain properties
- Assigning assets to domains
- Deleting domains

Individual asset assignment can also be controlled by "Edit Domain" metadata policies on specific entity types.
