Ontology Service
The Ontology Service is a standalone Python/FastAPI microservice (port 8101) that manages entity relationships, semantic models, and domain ontologies for the MATIH platform. It provides a GraphQL API for querying entity types and relationships, REST APIs for CRUD operations, and integrates with Dgraph for graph-native storage.
Architecture
Ontology Service (Port 8101)
|
+-- API Layer
| +-- REST Routes (/api/v1/ontology/*)
| +-- GraphQL Endpoint (/graphql)
|
+-- Models Layer
| +-- ObjectType (entity definitions)
| +-- Enums (classification types)
| +-- Semantic Models (semantic relationships)
|
+-- Service Layer
| +-- OntologyService (core business logic)
| +-- SchemaMapping (data catalog mapping)
|
+-- Storage Layer
| +-- Dgraph Repository (graph storage)
| +-- Templates (ontology templates)
|
+-- Configuration
+-- config.py (service settings)Source Organization
The Ontology Service is organized under data-plane/ontology-service/src/:
src/
main.py # FastAPI entry point
config.py # Service configuration
api/
routes/ # REST API route handlers
graphql/ # GraphQL schema and resolvers
models/
object_type.py # Entity type definitions
enums.py # Enumeration types
semantic/ # Semantic model definitions
storage/ # Storage backends
schema_mapping/ # Schema-to-ontology mapping
templates/ # Ontology templatesData Model
Entity Types
The Ontology Service manages entity types that define the domain vocabulary:
class ObjectType:
"""An entity type in the ontology."""
urn: str # Unique resource name
name: str # Human-readable name
description: str # Entity description
namespace: str # Ontology namespace
properties: list[Property] # Entity properties
relationships: list[Relationship] # Connections to other types
parent_type: str | None # Inheritance hierarchy
tags: list[str] # Classification tags
tenant_id: str # Owning tenantProperties
class Property:
"""A property of an entity type."""
name: str
data_type: str # string, int, float, date, boolean
description: str
required: bool = False
indexed: bool = False
searchable: bool = False
default_value: Any | None = NoneRelationships
class Relationship:
"""A relationship between entity types."""
name: str
source_type: str
target_type: str
cardinality: str # one_to_one, one_to_many, many_to_many
description: str
inverse_name: str | None = None
properties: list[Property] = []GraphQL API
The Ontology Service exposes a GraphQL endpoint for flexible entity queries:
Schema
type ObjectType {
urn: String!
name: String!
description: String
namespace: String!
properties: [Property!]!
relationships: [Relationship!]!
parentType: ObjectType
childTypes: [ObjectType!]!
tags: [String!]!
}
type Property {
name: String!
dataType: String!
description: String
required: Boolean!
indexed: Boolean!
}
type Relationship {
name: String!
sourceType: ObjectType!
targetType: ObjectType!
cardinality: String!
description: String
inverseName: String
}
type Query {
objectType(urn: String!): ObjectType
objectTypes(
namespace: String
tags: [String!]
limit: Int = 50
): [ObjectType!]!
searchEntities(
query: String!
limit: Int = 20
): [ObjectType!]!
relationships(
sourceUrn: String!
depth: Int = 1
): [Relationship!]!
}
type Mutation {
createObjectType(input: CreateObjectTypeInput!): ObjectType!
updateObjectType(urn: String!, input: UpdateObjectTypeInput!): ObjectType!
deleteObjectType(urn: String!): Boolean!
addRelationship(input: AddRelationshipInput!): Relationship!
removeRelationship(
sourceUrn: String!
targetUrn: String!
name: String!
): Boolean!
}Example Query
query {
objectType(urn: "urn:matih:ontology:acme:customer") {
name
description
properties {
name
dataType
required
}
relationships {
name
targetType {
name
urn
}
cardinality
}
}
}REST API
Entity Type Operations
POST /api/v1/ontology/types # Create entity type
GET /api/v1/ontology/types # List entity types
GET /api/v1/ontology/types/{urn} # Get entity type
PUT /api/v1/ontology/types/{urn} # Update entity type
DELETE /api/v1/ontology/types/{urn} # Delete entity typeRelationship Operations
POST /api/v1/ontology/relationships # Add relationship
GET /api/v1/ontology/relationships?source_urn=... # List relationships
DELETE /api/v1/ontology/relationships/{id} # Remove relationshipSearch Operations
GET /api/v1/ontology/search?query=customer&limit=10 # Semantic search
GET /api/v1/ontology/graph?urn=...&depth=2 # Graph traversalSchema Mapping
The schema mapping module connects ontology entities to physical data catalog tables:
class SchemaMapper:
"""Maps ontology entities to data catalog tables."""
async def map_entity_to_table(
self,
entity_urn: str,
table_fqn: str,
column_mappings: dict[str, str],
) -> SchemaMapping:
"""Create a mapping between an ontology entity and a table."""
return SchemaMapping(
entity_urn=entity_urn,
table_fqn=table_fqn,
column_mappings=column_mappings,
)
async def resolve_entity(
self,
entity_urn: str,
) -> TableResolution:
"""Resolve an ontology entity to its physical table(s)."""
mappings = await self._get_mappings(entity_urn)
return TableResolution(
entity_urn=entity_urn,
tables=[m.table_fqn for m in mappings],
columns={
m.table_fqn: m.column_mappings for m in mappings
},
)Mapping Example
{
"entity_urn": "urn:matih:ontology:acme:customer",
"table_fqn": "analytics.crm.customers",
"column_mappings": {
"customer_id": "id",
"full_name": "name",
"email_address": "email",
"signup_date": "created_at",
"lifetime_value": "ltv"
}
}Ontology Templates
Pre-built ontology templates for common business domains:
| Template | Domain | Entity Types |
|---|---|---|
| E-Commerce | Retail | Customer, Product, Order, Category, Review |
| SaaS | Software | User, Subscription, Feature, Usage, Invoice |
| Healthcare | Medical | Patient, Provider, Appointment, Diagnosis, Prescription |
| Finance | Banking | Account, Transaction, Customer, Instrument, Portfolio |
| Manufacturing | Industrial | Product, Component, Supplier, WorkOrder, Quality |
Integration with AI Service
The AI Service queries the Ontology Service to enrich agent context:
# Within AI Service
class OntologyClient:
"""Client for Ontology Service integration."""
async def resolve_entities(
self,
query: str,
tenant_id: str,
) -> list[dict[str, Any]]:
"""Resolve entities mentioned in a query."""
response = await self._http.get(
f"{self._base_url}/api/v1/ontology/search",
params={"query": query, "tenant_id": tenant_id},
)
return response.json()["results"]
async def get_relationships(
self,
entity_urn: str,
depth: int = 1,
) -> list[dict[str, Any]]:
"""Get relationships for an entity."""
response = await self._http.get(
f"{self._base_url}/api/v1/ontology/graph",
params={"urn": entity_urn, "depth": depth},
)
return response.json()["relationships"]Dgraph Storage
The Ontology Service uses Dgraph for graph-native entity storage:
| Advantage | Description |
|---|---|
| Native graph queries | Traversals without JOIN operations |
| Schema flexibility | Add properties and relationships dynamically |
| Full-text search | Dgraph's built-in full-text indexing |
| Multi-tenancy | Tenant-isolated queries via predicates |
| GraphQL native | Dgraph supports GraphQL mutations/queries natively |