Semantic Patterns
Understanding $.Subject.predicate.Object - the foundation of GraphDL and Business-as-Code
Semantic Patterns in GraphDL
Welcome to the comprehensive guide to semantic patterns in the .do platform. This documentation explains how $.Subject.predicate.Object patterns form the foundation of Business-as-Code, enabling AI-native applications through natural language semantics.
What Are Semantic Patterns?
Semantic patterns are the core abstraction in GraphDL (Graph Definition Language), implementing the same Subject-Verb-Object structure found in natural language. Every operation in the .do platform follows this pattern:
$.Subject.predicate.ObjectWhere:
- Subject = The entity performing or experiencing the action (TitleCase noun)
- predicate = The relationship or action (camelCase verb or preposition)
- Object = The entity receiving the action or related entity (TitleCase noun)
Why Semantic Patterns Matter
Natural Language Alignment
Semantic patterns read like English sentences, making code self-documenting:
// Natural language: "A customer places an order"
// GraphDL: $.Customer.places.Order
// Natural language: "Send email to user"
// GraphDL: $.Email.send.to.User
// Natural language: "Organization employs person"
// GraphDL: $.Organization.employs.PersonAI Understanding
AI models are trained on semantic data. When you use semantic patterns, AI can:
- Understand your business logic without custom training
- Reason about relationships and workflows
- Suggest improvements and optimizations
- Generate code that integrates seamlessly
Type Safety
TypeScript provides compile-time validation of semantic patterns:
import $ from 'sdk.do'
// TypeScript knows all valid subjects, predicates, and objects
const order = await $.Order.create({
customer: $.Person,
items: [$.Product],
})
// Autocomplete suggests valid predicates
await $.Organization.employs.Person({
// ✓ Valid
person: personId,
organization: orgId,
})Core Concepts
The $ Proxy
The $ symbol is a TypeScript Proxy that builds semantic paths dynamically:
// Each property access builds the semantic path
$.Customer // → Subject
$.Customer.places // → Subject.predicate
$.Customer.places.Order // → Subject.predicate.Object
// The proxy captures the entire semantic triple
const pattern = $.Customer.places.Order
console.log(pattern.subject) // "Customer"
console.log(pattern.predicate) // "places"
console.log(pattern.object) // "Order"Casing Conventions
GraphDL uses casing to distinguish parts of speech:
- TitleCase: Subjects and Objects (nouns) →
Person,Organization,Product - camelCase: Predicates (verbs, relationships) →
creates,employs,worksFor - lowercase: Prepositions →
to,from,in,of,at,by,with
// Clear semantic structure through casing
$.Person.worksFor.Organization.in.Department
//│ │ │ │ │
//│ │ │ │ └─ preposition (lowercase)
//│ │ │ └──── Object (TitleCase)
//│ │ └───────────────── predicate (camelCase)
//│ └────────────────────────── Subject (TitleCase)Documentation Structure
This comprehensive guide covers all aspects of semantic patterns in GraphDL:
Foundations
- Introduction - Why semantic patterns matter
Quick Start
Basic Pattern
import $, { db } from 'sdk.do'
// Create entities using semantic patterns
const organization = await db.create($.Organization, {
name: 'Acme Inc',
industry: 'Technology',
})
const person = await db.create($.Person, {
givenName: 'Alice',
familyName: 'Smith',
email: '[email protected]',
})
// Create relationships using semantic predicates
await db.relate(organization, $.employs, person)
// Query using semantic patterns
const employees = await db.related(organization, $.employs, $.Person)Event Patterns
import { on, send } from 'sdk.do'
// Listen for events using semantic patterns
on.Order.created, async (order) => {
console.log('New order:', order.id)
// Send follow-up events
send.Email.sent, {
to: order.customer.email,
template: 'order-confirmation',
})
})
// Emit events
send.Order.created, {
id: 'ord_123',
customer: personId,
items: products,
})Complex Patterns
// Compound predicates with prepositions
await $.Email.send.to.User.about.Order({
user: userId,
order: orderId,
subject: 'Your order has shipped!',
})
// Conditional patterns
on.Payment.succeeded, async (payment) => {
if (payment.amount > 1000) {
await $.Order.requires.Approval({
order: payment.orderId,
})
} else {
await $.Order.auto.Process({
order: payment.orderId,
})
}
})
// Iterative patterns
await $.forEach.Product.in.Catalog.do.Update.Inventory({
catalog: catalogId,
operation: 'recount',
})Real-World Examples
E-Commerce
// Product management
const product = await $.Product.create({
name: 'Widget Pro',
price: 29.99,
manufacturer: $.Organization,
})
// Order processing
on.Order.created, async (order) => {
await $.Inventory.decrement.for.Product({
product: order.items[0].product,
quantity: order.items[0].quantity,
})
await $.Shipment.create.for.Order({
order: order.id,
carrier: 'USPS',
})
})HR & Workforce
// Employment relationships
await $.Organization.employs.Person({
organization: orgId,
person: personId,
jobTitle: 'Software Engineer',
startDate: new Date(),
})
// Task assignment
await $.Task.assigned.to.Person.for.Project({
task: taskId,
person: personId,
project: projectId,
dueDate: '2025-11-01',
})Supply Chain
// Shipment tracking
on.Shipment.departed.from.Warehouse, async (shipment) => {
await $.Customer.notify.about.Shipment({
customer: shipment.orderId.customer,
shipment: shipment.id,
tracking: shipment.trackingNumber,
})
})
// Inventory management
await $.Warehouse.receives.Product.from.Supplier({
warehouse: warehouseId,
product: productId,
supplier: supplierId,
quantity: 500,
})Next Steps
- Read the Introduction - Understand why semantic patterns are powerful
- Learn the Basics - Master the $ proxy and core patterns (coming soon - issue #7037)
- Explore Pattern Types - Discover 10 pattern categories (coming soon - issue #7040)
- Try Examples - Interactive examples and tutorials (coming soon)
Platform Tip: Semantic patterns make your code self-documenting and AI-understandable. Start with simple patterns and gradually adopt more advanced techniques as you become comfortable with the approach.