This article describes an approach to application development based on a single, highly detailed format for describing domain entities and contracts. It provides practical examples of how such descriptions can be used and demonstrates how declarative schemas can bring some of the conveniences of low-code platforms into conventional full-code programs.

The approach is independent of any particular technology stack and is especially useful in heterogeneous systems. For that reason, the examples draw from a variety of programming languages and technologies: Java, Python, TypeScript, REST, GraphQL, and Protocol Buffers.

Introduction

Every program operates on data. Most projects contain numerous declarative descriptions of that data: object-oriented class definitions, database table schemas, GraphQL and protobuf schemas, and so on. Each of these descriptions serves a specific technical purpose.

A PostgreSQL table schema exists so that the database can store data, while an ORM schema exists so that application code can interact with the database. Although both describe the same information, they are neither equivalent nor interchangeable. An ORM schema may not support defining database constraints, yet it may contain auxiliary metadata that does not exist in the database itself. Nevertheless, the logical connection between the two schemas is obvious. At least column names and types must remain consistent.