Ubiquitous <Programming> Language

Tim Kleier
4 min readSep 30, 2023

In Domain-Driven Design, there’s a notion of Ubiquitous Language. Its purpose is to create a bridge between business stakeholders and the development team. A common language amongst humans. This is a critical first step in creating effective software.

However, we also need to create a common language amongst computers. We can’t afford for humans to be on the same page and our applications on different ones. We need a way to ensure, for example, that business concepts are represented in the same way across a platform consisting of JavaScript, PHP and Ruby.

The Problem

This may sound hypothetical, but it’s not. With my employer’s recent acquisition and restructuring, we’ve found ourselves with two teams managing half a dozen applications with three separate tech stacks. We have established an eventing mechanism so each of the apps can pass messages to each other, but we need a more ubiquitous and low-level solution to ensure our domain model (represented by Aggregates) is consistent across the applications.

In one application, a real estate Property is a primary object (Entity), and it has property details attached to it. In the other applications, it’s a secondary concern — tied to a Loan in one and a Project in the other. In those secondary contexts, Property data may be more minimal, but fundamentally its the same. It has an address, property type (house, condo, land), baths and beds, square footage, etc.

Herein lies the problem — we can’t easily ensure consistency of a real estate Property represented across these applications in Ruby, JavaScript, and PHP. We need a higher order representation that informs (even generates!) code in each of those languages.

The Solution

Enter JSON Schema. JSON Schema, obviously based on JSON, is incredibly portable. With it we can construct a domain model that can be imported into virtually any programming language. From there, we can use our schema to validate data passed in by PHP, Ruby, or JavaScript.

For example, given the Property schema definition below, we can ensure that every property address has a propertyType , regardless of its context. So we could be on a server using PHP, on the frontend in JavaScript, or sending events across an event bus, and still be able to validate any representation of a Property against this schema. We could also use the Property schema to generate TypeScript interfaces or Rails models.

{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Real Estate Property",
"properties": {
"propertyId": {
"type": "string",
"description": "Unique identifier for the property"
},
"propertyName": {
"type": "string",
"description": "Name or title of the property"
},
"propertyType": {
"type": "string",
"enum": ["House", "Apartment", "Condo", "Townhouse", "Land", "Commercial"],
"description": "Type of property"
},
"address": {
"type": "object",
"properties": {
"street": {
"type": "string",
"description": "Street address"
},
"city": {
"type": "string",
"description": "City"
},
"state": {
"type": "string",
"description": "State or province"
},
"postalCode": {
"type": "string",
"description": "Postal code"
},
"country": {
"type": "string",
"description": "Country"
}
},
"required": ["street", "city", "state", "postalCode", "country"],
"description": "Address of the property"
},
"bedrooms": {
"type": "integer",
"description": "Number of bedrooms"
},
"bathrooms": {
"type": "integer",
"description": "Number of bathrooms"
},
"sizeSqFt": {
"type": "number",
"description": "Size of the property in square feet"
},
"yearBuilt": {
"type": "integer",
"description": "Year the property was built"
}
},
"required": ["propertyId", "propertyName", "propertyType", "address"],
"additionalProperties": false
}

Here’s an overview of potential implementation steps in our solution:

  1. Determine our Domain Model (key Aggregates)
  2. Define them using JSON Schema
  3. Import that schema into our various applications
  4. Validate system data to ensure data integrity
  5. Generate code based on schemas

Thankfully, there’s some great tooling around JSON Schema implementations to handle the nuts and bolts of several of the steps above. That said, there is a lot of room for growth in building a language-agnostic domain model.

Conclusion

Bridging the human-language gap between business stakeholders and developers is one thing. Bridging the computer-language gap between systems is another.

Our brief exploration here is only scratching the surface of what’s possible in a ubiquitous Domain Model representation. And beyond the Domain Model, we would need to think about things like Domain Events and how they could be represented in a language-agnostic way across systems.

Developing a Ubiquitous Programming Language will not be easy. But if humans need to establish shared language around a Domain Model, systems do as well.

--

--