Zenith DSL Documentation
Zenith is a domain-specific language designed to eliminate the 9-file boilerplate ceremony of Java and Spring Boot. Declare your models, validation constraints, relations, security policies, background workers, and REST endpoints in clean .zen files and compile directly into production-ready Spring Boot 3 applications in milliseconds.
Overview & Philosophy
In traditional Spring Boot development, exposing a single validated, secured CRUD resource requires creating 7 to 9 separate files: Entity.java, CreateRequest.java, UpdateRequest.java, Response.java, Repository.java, Mapper.java, Service.java, ServiceImpl.java, and Controller.java (~350 lines of repetitive ceremony).
Zenith unifies this into a single strongly-typed AST. When you modify your schema, all downstream artifacts—JPA entities, Flyway migrations, Spring Security filters, MockMvc test suites, and frontend TypeScript clients—update in complete lockstep.
Installation & CLI Commands
The Zenith compiler is distributed as a single standalone executable JAR requiring Java 17+. Install via Scoop on Windows, download the standalone binary, or install the VS Code language extension.
| Command | Arguments | Description |
|---|---|---|
zenith build |
<file.zen> [-o <output-dir>] |
Transpiles the schema into a complete Spring Boot 3 Maven project. |
zenith watch |
<file.zen> [-o <output-dir>] |
Starts hot-reload daemon; regenerates application code on file save (< 150ms). |
zenith validate |
<file.zen> |
Performs lexing, AST parsing, and semantic analysis; reports exact errors. |
zenith inspect |
<file.zen> |
Prints an architectural summary of detected models, relations, DTOs, and endpoints. |
zenith studio |
<file.zen> [--desktop] [--port 3000] |
Launches Zenith Studio — available both as a local web IDE and native standalone desktop app. |
zenith mcp |
— |
Runs the native Model Context Protocol (MCP) server over standard I/O (JSON-RPC 2.0) for AI coding assistants (Claude Code, Cursor, Antigravity). |
zenith init |
[name] |
Scaffolds a clean starter schema.zen file in the current directory. |
Zenith Studio PRO (Web & Desktop IDE)
Zenith Studio is the full visual engineering workspace running locally at http://localhost:3000 or as a dedicated native desktop application. Designed for developers and architects who need full-spectrum visibility into their data models, relational graphs, and runtime APIs:
- Monaco Code Editor: Full syntax highlighting, auto-completion, linting markers, and hover tooltips.
- Vertical Modular File Explorer: Displays all workspace
.zenfiles stacked vertically with quick tab switching. - Clickable Import Navigation: Double-click any
import "./config.zen"line to instantly switch to that module. - Interactive Architecture ERD: Live SVG diagrams displaying models, columns, primary keys, and foreign key connectors.
- API Tester & Swagger: Test generated REST endpoints directly from the interface.
- Repository Tree & One-Click Run: Inspect emitted Java files and boot the backend with one click.
# Launch in web browser (http://localhost:3000):
zenith studio schema.zen
# Launch in dedicated native desktop application mode:
zenith studio schema.zen --desktop
1. Application Configuration (config)
The config { ... } block declares global application properties, database engines, security configurations, and infrastructure integrations.
| Property | Type | Default | Description |
|---|---|---|---|
app |
String | "ZenithApplication" |
Spring Boot application name and main class prefix. |
package |
String | "com.example.app" |
Root Java package directory for all generated classes. |
basePath |
String | "/api" |
Common root path prefix prepended to all REST endpoints. |
port |
Integer | 8080 |
HTTP server port (server.port). |
database |
postgres | h2 |
postgres |
Target SQL dialect and driver configuration. |
auth |
jwt | none |
none |
Activates Spring Security 6, JJWT token filter, and auth endpoints. |
jwtSecret |
String (Optional) | Auto-derived (256-bit) | Omit for automatic 256-bit key derivation, pass a short passphrase (e.g. "my-secret", auto-stretched via SHA-256), or provide an explicit 64-char hex key. Supports ${JWT_SECRET:...} env override. |
jwtExpiration |
Duration | Long (Optional) | 24h (86400000) |
Token TTL using duration units (30s, 15m, 24h, 7d) or raw milliseconds. Supports ${JWT_EXPIRATION_MS:...} env override. |
storage |
minio | s3 |
minio |
Object storage provider for @file and @image uploads. |
flyway |
Boolean | true |
Generates idempotent V1__initial_schema.sql migration scripts. |
swagger |
Boolean | true |
Enables SpringDoc OpenAPI 3 UI on /swagger-ui.html. |
rateLimit |
String (Optional) | none |
Global fallback token-bucket rate limit (e.g. "500/minute", "100/second", "5000/hour"). Automatically configures the Bucket4j RateLimitingFilter across all routes and returns HTTP 429 when exhausted. |
mail |
smtp | sendgrid | ses | console |
console |
Transactional email delivery provider backend. In local development (console), dispatched emails log complete headers, recipients, and rendered HTML bodies to stdout without requiring real SMTP credentials. |
mailHost |
String | "localhost" |
SMTP server hostname (e.g. "smtp.gmail.com"). Bound to ${SPRING_MAIL_HOST:...}. |
mailPort |
Integer | 587 |
SMTP server port (e.g. 587 for TLS, 465 for SSL). Bound to ${SPRING_MAIL_PORT:...}. |
mailUsername |
String | "" |
SMTP authentication username or email (e.g. "user@gmail.com"). Bound to ${SPRING_MAIL_USERNAME:...}. |
mailPassword |
String | "" |
SMTP authentication password or app password. Bound to ${SPRING_MAIL_PASSWORD:...}. |
mailFrom |
String | "noreply@example.com" |
Default sender email address for all transactional email dispatches. Supports ${SPRING_MAIL_FROM:...} env override. |
cache |
redis | caffeine | memory | none |
none |
Declarative cache provider. Configures Spring Boot Cache abstraction (@EnableCaching, CacheConfig.java), JSON serialization, custom TTLs, and fault-tolerant fallback error handlers. In redis mode, provisions redis:7-alpine container in docker-compose.yml. |
cacheTtl |
Duration | String | "10m" |
Default cache expiration time-to-live (e.g. "15m", "1h", "300s"). Overridable per CRUD entity or individual read endpoint. |
config {
app: "NexusCommerce"
package: "com.nexus.commerce"
basePath: "/api/v1"
port: 8080
database: postgres
auth: jwt
// Option 2 (Clean): Use a simple passphrase + duration unit (or omit both for auto 256-bit key & 24h default)
jwtSecret: "nexus-commerce-secret"
jwtExpiration: 24h
// Option 1 (Explicit): Full 64-char hex secret + raw milliseconds is also supported
storage: minio
flyway: true
swagger: true
rateLimit: "500/minute" // Global baseline token-bucket rate limit (HTTP 429 on exhaustion)
}
2. Data Types & Nullability
Zenith primitives map automatically to SQL database columns, Java JPA field types, and TypeScript client interfaces. Fields are non-null by default; append ? to mark a field as optional. Assign default values using = value.
| Zenith Type | Java 17 Type | PostgreSQL SQL Type | TypeScript Type |
|---|---|---|---|
String |
java.lang.String |
VARCHAR(255) |
string |
Text / @text |
java.lang.String |
TEXT |
string |
Int / Integer |
java.lang.Integer |
INTEGER |
number |
Long |
java.lang.Long |
BIGINT |
number |
Decimal |
java.math.BigDecimal |
NUMERIC(p,s) |
number |
Boolean |
java.lang.Boolean |
BOOLEAN |
boolean |
UUID |
java.util.UUID |
UUID |
string |
Date |
java.time.LocalDate |
DATE |
string |
DateTime |
java.time.LocalDateTime |
TIMESTAMP |
string |
model CustomerProfile {
id: UUID @id @auto
fullName: String(min = 2, max = 100)
bio: String? @text // Optional unbounded text
rewardPoints: Int = 0 // Defaults to 0
balance: Decimal(precision = 10, scale = 2) @positive
isVerified: Boolean = false
birthDate: Date?
lastLogin: DateTime?
}
3. Field Decorators & Validation Rules
Decorators attach database primary keys, validation rules, security behaviors, and media handlers directly to attributes.
| Decorator | Arguments | Behavior & Emitted Code |
|---|---|---|
@id |
— | Marks field as table Primary Key (@Id in JPA). |
@auto |
— | Automated identity generation (GenerationType.IDENTITY or UUID random). |
@unique |
— | Adds unique database constraint and derived query findBy[Field]. |
@index |
[fields], name, unique |
Declares single-column (field-level) or composite (model-level) database index in Flyway SQL and JPA @Table(indexes = ...). |
@uniqueIndex |
[fields], name |
Declares a unique single-column or composite index (CREATE UNIQUE INDEX & @Index(unique = true)). |
@rateLimit |
requests, per or "cap/unit" |
Enforces token-bucket rate limiting via Bucket4j (e.g. @rateLimit("10/minute"), @rateLimit(requests = 5, per = "1m")). Emits RFC headers and HTTP 429 when throttled. |
@email |
— | Enforces valid email format with Jakarta @Email. |
@password |
— | Hashes value with BCrypt; strips field from response DTO records. |
@min(n) |
Number | Validates minimum integer or string length constraint. |
@max(n) |
Number | Validates maximum integer or string length constraint. |
@positive |
— | Ensures numeric attribute is strictly greater than zero (@Positive). |
@autoNow |
— | Sets creation timestamp on @PrePersist. |
@autoUpdate |
— | Updates modification timestamp on @PreUpdate. |
@role |
— | Designates enum as user role authority for Spring Security. |
@file |
path, maxSize |
Attaches cloud document upload endpoint (MinIO / S3). |
@image |
path, types, maxSize |
Validates image MIME type and attaches cloud media upload endpoint. |
model Order {
id: UUID @id @auto
orderNumber: String(length = 32) @unique
status: OrderStatus = PENDING @index // 1. Inline single-column index
totalAmount: Decimal(precision = 12, scale = 2)
createdAt: DateTime @autoNow
relations {
customer: Customer @relation(manyToOne)
}
// 2. Composite index on foreign key + status
@index([customer, status])
// 3. Composite index with explicit custom name
@index([status, createdAt], name = "idx_orders_status_timeline")
// 4. Composite unique index
@uniqueIndex([orderNumber, customer])
}
relations { ... }
Always declare model-level composite indexes (@index([...]) and @uniqueIndex([...])) after your relations { ... } block (and before endpoints { ... }). Because composite indexes often include foreign-key relations like customer (which resolves to customer_id), placing them below relations ensures all referenced relations are declared first and clearly separates model-level indexes from inline field decorators.
config {
rateLimit: "500/minute" // Global baseline rate limit
}
model Checkout {
id: UUID @id @auto
amount: Decimal(12, 2)
endpoints {
// 1. Decorator syntax on custom route
@rateLimit(requests = 5, per = "1m")
post "/charge" -> OrderResponse {
action: { }
}
// 2. Shorthand capacity/timeUnit syntax
@rateLimit("10/minute")
post "/instant-pay" -> Void {
action: { }
}
// 3. Route body property
post "/verify-card" -> Void {
rateLimit: "3/second"
action: { }
}
// 4. CRUD-wide rate limit
crud {
rateLimit: "100/minute"
list: ["public"]
}
}
}
4. Enums & Security Roles
Enums define finite states or access control roles. Decorating an enum with @role integrates it with Spring Security's GrantedAuthority hierarchy.
enum UserRole {
ADMIN,
STAFF,
CUSTOMER
}
enum OrderStatus {
PENDING,
PAID,
PROCESSING,
SHIPPED,
DELIVERED,
CANCELLED
}
model UserEntity {
id: UUID @id @auto
email: String @email @unique
password: String @password
role: UserRole = CUSTOMER @role
isActive: Boolean = true
}
5. Entity Relationships
Relationships are declared cleanly inside the relations { ... } block using @relation. Zenith generates foreign key columns, join tables, bidirectional links, and Jackson JSON serialization shields to prevent infinite recursion.
model Category {
id: Long @id @auto
name: String @unique
relations {
products: List<Product> @relation(oneToMany, mappedBy = "category")
}
}
model Product {
id: Long @id @auto
title: String
price: Decimal
relations {
category: Category @relation(manyToOne)
orderItems: List<OrderItem> @relation(oneToMany, mappedBy = "product")
}
}
model Order {
id: UUID @id @auto
orderNumber: String @unique
relations {
customer: UserEntity @relation(manyToOne)
items: List<OrderItem> @relation(oneToMany, mappedBy = "order")
}
}
model OrderItem {
id: Long @id @auto
quantity: Int @min(1)
unitPrice: Decimal
relations {
order: Order @relation(manyToOne)
product: Product @relation(manyToOne)
}
}
6. Standard CRUD Endpoints
The crud { ... } block declares standard REST endpoints: GET / (list with pagination/filter/search), GET /{id}, POST / (create), PUT /{id} (update), and DELETE /{id}.
model Product {
id: Long @id @auto
title: String
sku: String @unique
status: ProductStatus
price: Decimal
endpoints {
crud {
paginate: true // PageResponse<T> with ?page=0&size=20
search: [title, sku] // Case-insensitive ?search= query
filter: [status] // Exact match query ?status=ACTIVE
sort: [price, createdAt] // Sorting ?sort=price,desc
rateLimit: "100/minute" // Token-bucket rate limiting
auth: true // Requires valid JWT token
roles: {
create: [ADMIN, STAFF], // Emits @PreAuthorize("hasAnyRole('ADMIN','STAFF')")
delete: [ADMIN], // Emits @PreAuthorize("hasRole('ADMIN')")
list: ["public"] // Anonymous public access allowed
}
}
}
}
7. Custom Routes & Request Bodies
Declare custom domain routes (get, post, put, delete) with path variables and decoupled DTO request bodies.
Response or Request (Never Return Raw Entities):For every
model <ModelName>, Zenith auto-generates <ModelName>Response, Create<ModelName>Request, and Update<ModelName>Request. You cannot return a raw JPA entity as a REST API response (e.g., -> Order is rejected at compile time in Zenith Studio). Always return -> <ModelName>Response, -> List<<ModelName>Response>, a custom dto, or -> Void.
dto CheckoutItemRequest {
productId: Long
quantity: Int
}
dto CheckoutRequest {
shippingAddress: String
notes: String?
items: List<CheckoutItemRequest>
}
model Order {
id: UUID @id @auto
status: OrderStatus = PENDING
endpoints {
// Custom POST endpoint with rate limiting & typed request body
@rateLimit(requests = 5, per = "1m")
post "/checkout" (body: CheckoutRequest) -> OrderSummaryResponse {
auth: true
action: {
// Execute domain mutation logic
}
}
// Route with path variable
post "/{id}/cancel" -> Void {
auth: true
guard: status == OrderStatus.PENDING, "Only pending orders can be cancelled"
action: {
status = OrderStatus.CANCELLED
}
}
}
}
8. Domain Actions & Guards
The action: { ... } block handles multi-entity mutations, automated audit logging, customer notifications, conditional guards, and Action Variable Binding (capturing database-generated IDs, timestamps, and relations with var) directly in your schema.
post "/{id}/pay" -> OrderSummaryResponse {
auth: true
// 1. Guard check: fails with 400 Bad Request if false
guard: status == OrderStatus.PENDING, "Only pending orders can be marked as paid"
action: {
// 2. State mutation on primary entity
status = OrderStatus.PAID
// 3. Action Variable Binding: create and capture invoice
var invoice = create Invoice {
orderNumber = entity.orderNumber,
amount = entity.totalAmount,
status = InvoiceStatus.PAID
}
// 4. Instantiate secondary audit log entity referencing bound variable
var audit = create AuditLog {
action = "ORDER_PAYMENT_PROCESSED",
invoiceId = invoice.id,
details = "Order " + entity.orderNumber + " marked PAID by " + currentUser.email
}
// 5. Dispatch notification to customer
notify(entity.customer.email, "Your payment for order " + entity.orderNumber + " succeeded!")
// 6. Return explicit DTO
return OrderSummaryResponse {
orderNumber = entity.orderNumber,
totalAmount = entity.totalAmount,
status = entity.status,
paidAt = now()
}
}
}
var x = create / update)
Zenith compiles var <name> = create <Model> { ... } and var <name> = update <Model> { ... } into strongly-typed local variable assignments in Java. The returned entity from repository.save() is captured, enabling you to access database-generated primary keys (id), timestamps (createdAt), and relationship fields in downstream statements within the same atomic @Transactional boundary.
9. DTOs & Custom Return Types
Define decoupled Java 17 records and TypeScript interfaces using dto Name { ... }. Note that auto-generated DTOs for any model <ModelName> always end with <ModelName>Response, Create<ModelName>Request, or Update<ModelName>Request — raw model entities can never be returned directly from REST endpoints. When an endpoint returns a custom DTO, Zenith supports two approaches:
dto OrderSummaryResponse {
orderNumber: String
totalAmount: Decimal
status: OrderStatus
processedBy: String?
}
// Approach A: Explicit return construction inside action
post "/{id}/pay" -> OrderSummaryResponse {
action: {
status = OrderStatus.PAID
return OrderSummaryResponse {
orderNumber = entity.orderNumber,
totalAmount = entity.totalAmount,
status = entity.status,
processedBy = currentUser.email
}
}
}
// Approach B: Automatic field mapping (zero boilerplate)
get "/{id}/summary" -> OrderSummaryResponse {
// Coincident fields (orderNumber, totalAmount, status) map automatically
}
10. Declarative Database Seeding
Populate development and staging environments instantly using seed Model { ... }. Zenith generates a Spring Boot ApplicationRunner (active in non-prod profiles) with password hashing and relational cross-referencing via seed Model[index].
seed UserEntity [
{
email: "admin@nexus.dev",
password: "AdminSecret2026!", // Automatically BCrypt hashed
fullName: "Platform Admin",
role: ADMIN
},
{
email: "customer@example.com",
password: "Pass1234!",
fullName: "John Doe",
role: CUSTOMER
}
]
seed Order [
{
orderNumber: "ORD-2026-001",
totalAmount: 149.99,
status: PENDING,
customer: seed UserEntity[1] // Cross-references 2nd UserEntity record
}
]
11. Modular File Imports
Decompose large schemas into clean, focused .zen modules using import "./filename.zen". Zenith resolves diamond imports, prevents circular dependencies, and compiles the entire workspace into a single unified AST.
import "./config.zen"
import "./auth.zen"
import "./catalog.zen"
import "./orders.zen"
import "./jobs.zen"
import "./seeds.zen"
12. Object Storage (S3 / MinIO)
Decorate fields with @file or @image to automatically generate multipart upload controllers and streaming download endpoints. Switch between MinIO and AWS S3 in config without altering code.
model Product {
id: Long @id @auto
title: String
// Media image upload with MIME type and size checks
coverImage: String? @image(maxSize = "5MB", types = ["image/png", "image/jpeg"], path = "products/")
// Datasheet PDF upload
specSheet: String? @file(maxSize = "10MB", path = "specs/")
}
// Generated Endpoints:
// POST /api/v1/products/{id}/coverImage (multipart/form-data)
// GET /api/v1/products/{id}/coverImage (download stream)
13. Scheduled Workers (Cron)
Declare background batch jobs and cleanup routines using job Name { cron: "...", action: { ... } }. Zenith generates a Spring @Scheduled component with ThreadPoolTaskScheduler and bulk stream pipelines.
job ArchiveOldOrders {
cron: "0 0 2 * * ?" // Executes 2:00 AM daily
description: "Nightly maintenance archiving delivered orders older than 60 days"
action: {
update Order {
where: status == OrderStatus.DELIVERED and updatedAt < daysAgo(60)
status = OrderStatus.CANCELLED
}
}
}
14. Transactional Emails (mail & send)
The mail ContractName(params...) { ... } construct declares typed, asynchronous email contracts at the top level. Trigger them declaratively inside custom endpoint action blocks or scheduled jobs using the send statement.
Keywords, Directives & Properties Reference
Detailed breakdown of all email-related keywords, parameters, and properties supported in Zenith:
| Keyword / Property | Scope | Type / Value | Purpose & Behavior |
|---|---|---|---|
mail |
Top-level declaration | mail Name(param: Type, ...) |
Declares a typed transactional email contract. Emits a dedicated method on the asynchronous Spring EmailService interface and implementation. |
to |
Inside mail { ... } |
String / Property Expression | Required. Resolves the recipient email address. Supports parameter references and navigation (e.g., customer.email, user.email, or recipient). |
subject |
Inside mail { ... } |
String / Expression | Required. The subject line of the email. Supports string concatenation with dynamic parameter attributes (e.g. "Order #" + order.orderNumber + " Confirmed"). |
content |
Inside mail { ... } |
String / Expression | Inline content. Direct text or HTML email body supporting dynamic expressions and parameter interpolation (e.g. "<h1>Order Confirmed</h1><p>Order #" + order.orderNumber + " for " + customer.fullName + "</p>"). Use either content or template. |
template |
Inside mail { ... } |
String Path | Relative path to the Thymeleaf HTML template file under src/main/resources/templates/ (e.g. "emails/order-confirmation.html"). If absent and no content is provided, Zenith auto-scaffolds a starter template. |
from |
Inside mail { ... } |
String (Optional) | Overrides the sender address for this specific email contract (e.g. "security@company.com"). If omitted, falls back to the global mailFrom setting. |
send |
Inside action { ... } |
send MailName(arg = val, ...) |
Dispatches the declared email contract asynchronously (via Spring @Async). Named arguments must match the parameter signature of the target contract. Does not block the HTTP request or database transaction. |
config.mail |
Inside config { ... } |
smtp | sendgrid | ses | console |
Configures the email delivery backend. In console mode (default for dev), dispatched emails print formatted preview headers and rendered HTML to standard out without external SMTP credentials. |
config.mailHost |
Inside config { ... } |
String | SMTP server hostname (e.g. "smtp.gmail.com"). Bound to ${SPRING_MAIL_HOST}. |
config.mailPort |
Inside config { ... } |
Integer | SMTP server port (e.g. 587, 465). Bound to ${SPRING_MAIL_PORT}. |
config.mailUsername |
Inside config { ... } |
String | SMTP authentication username or email. Bound to ${SPRING_MAIL_USERNAME}. |
config.mailPassword |
Inside config { ... } |
String | SMTP authentication password or app password. Bound to ${SPRING_MAIL_PASSWORD}. |
config.mailFrom |
Inside config { ... } |
String Email Address | Default global sender address (e.g. "noreply@example.com"). Bound to ${SPRING_MAIL_FROM} in application.yml for production environment overrides. |
config {
app: "NexusStore"
mail: smtp
mailFrom: "support@nexusstore.io"
}
// 1. Declare typed email contract
mail OrderConfirmation(order: Order, customer: Customer) {
to: customer.email
subject: "Order #" + order.orderNumber + " Confirmed"
template: "emails/order-confirmation.html"
from: "orders@nexusstore.io" // Optional override
}
model Order {
id: UUID @id @auto
orderNumber: String @unique
relations {
customer: Customer @relation(manyToOne)
}
endpoints {
post "/checkout" -> OrderResponse {
action: {
status = OrderStatus.CONFIRMED
// 2. Trigger asynchronous email dispatch
send OrderConfirmation(order = entity, customer = entity.customer)
}
}
}
}
Zenith automatically injects spring-boot-starter-mail and spring-boot-starter-thymeleaf into pom.xml, writes an @Async @Service EmailService.java class, and auto-generates responsive starter HTML templates under src/main/resources/templates/emails/. In console mode, dispatched emails print structured previews to logs for instant verification without external SMTP overhead.
15. Declarative Caching Layer (Redis / Spring Cache)
Zenith features first-class, declarative caching powered by Spring Boot's caching abstraction (@EnableCaching, @Cacheable, @CacheEvict). Developers can configure caching at the CRUD collection level or on individual custom GET endpoints with granular time-to-live durations.
config {
app: "HighTrafficStore"
cache: redis // redis | caffeine | memory | none
cacheTtl: "15m" // Default TTL for cached records
}
model Product {
id: UUID @id @auto
name: String
price: Decimal
endpoints {
crud {
cache: "15m" // Enables @Cacheable on getById/getAll & @CacheEvict on mutations
}
get "/featured" -> List<ProductResponse> {
cache: "1h" // Custom endpoint cache TTL (1 hour)
}
}
}
| Feature / Component | Behavior & Generated Output |
|---|---|
RedisCacheManager |
Configures JSON serialization (GenericJackson2JsonRedisSerializer) for zero Java-serialization vulnerabilities and custom per-cache TTL mappings. |
CacheErrorHandler |
Fault-tolerant error handling: logs Redis connection timeouts or network blips and seamlessly falls back to direct database execution instead of terminating client HTTP requests. |
@CacheEvict |
Mutations (create, update, delete) automatically evict <model> and <model>_list cache entries, ensuring zero stale data. |
docker-compose.yml |
When cache: redis is active, automatically spins up a lightweight redis:7-alpine container on port 6379 with persistent volume storage. |
16. Full-Stack TypeScript Client SDK
Zenith generates a zero-dependency TypeScript client SDK in sdk/typescript/ containing strongly-typed models, fetch API clients with JWT bearer injection, and React Query caching hooks.
import React from 'react';
import { createClient } from './sdk/typescript/src/client';
import { useOrderList } from './sdk/typescript/src/react-query';
const api = createClient({
baseUrl: 'http://localhost:8080',
getToken: () => localStorage.getItem('jwt_token')
});
export function OrdersDashboard() {
const { data, isLoading } = useOrderList(api, { page: 0, size: 10, sort: 'createdAt,desc' });
if (isLoading) return <div>Loading orders...</div>;
return (
<ul>
{data?.content.map(order => (
<li key={order.id}>{order.orderNumber} - ${order.totalAmount} ({order.status})</li>
))}
</ul>
);
}
16. Automated Test Generation
Zenith synthesizes complete JUnit 5, Spring Boot Test, and MockMvc test suites under src/test/. Tests run against an isolated in-memory H2 profile (application.yml) so mvn test passes anywhere without requiring external databases or Docker.
| Test File | Framework | Assertion Coverage |
|---|---|---|
application.yml |
Spring Test Profile | In-memory H2 (create-drop), disabled Flyway, mock secrets. |
*ApplicationTests.java |
@SpringBootTest |
Verifies application context startup and bean wiring. |
AuthControllerTest.java |
MockMvc |
Asserts /auth/login and /auth/register validation errors and bad credentials. |
*ControllerTest.java |
MockMvc + @WithMockUser |
Asserts unauthenticated (401), forbidden roles (403), validation (400), not found (404), and happy paths. |
*RepositoryTest.java |
@DataJpaTest |
Verifies JPA entity mappings, constraints, foreign keys, and queries under H2. |
17. Automated Test Generation
Zenith generates full test suites with MockMvc and DataJpaTest under src/test/java/:
| Test Class | Framework | Assertion Scope |
|---|---|---|
*ApplicationTests.java |
@SpringBootTest |
Verifies Spring context startup, bean wiring, and configuration health. |
AuthControllerTest.java |
MockMvc |
Tests JWT registration, authentication, token return, and bad credentials. |
*ControllerTest.java |
MockMvc + @WithMockUser |
Asserts unauthenticated (401), forbidden roles (403), validation (400), not found (404), and happy paths. |
*RepositoryTest.java |
@DataJpaTest |
Verifies JPA entity mappings, constraints, foreign keys, and queries under H2. |
mvn test
18. Docker Containerization
Zenith generates a multi-stage Dockerfile (Maven 3.9 builder + Eclipse Temurin 17 JRE Alpine runtime with unprivileged user) and a pre-configured docker-compose.yml pairing the API with PostgreSQL healthchecks and persistent storage volumes.
docker compose up --build
19. Zenith MCP Server (AI Agent Integration)
Zenith features an official, zero-overhead Model Context Protocol (MCP) Server complying with protocol standard 2024-11-05 over standard I/O (JSON-RPC 2.0). Connect Claude Code, Cursor, Antigravity, and autonomous AI agents directly to Zenith to retrieve language specifications, generate valid schemas, diagnose syntax/semantic errors, and compile full applications.
# Launch the Zenith MCP server over stdio
zenith mcp
| MCP Tool | Arguments | Description |
|---|---|---|
zenith_get_specification |
— | Retrieves the complete Zenith language specification, top-level grammar, and decorators. |
zenith_get_examples |
topic? |
Retrieves production-grade .zen schemas by category (basic-crud, authentication, relationships, rate-limiting, emails). |
zenith_list_features |
— | Discovers all supported capabilities, decorators, and features supported by the compiler core. |
zenith_validate |
source?, filePath? |
Validates source code and returns machine-readable structured diagnostics (error codes ZEN-xxx, exact line/column, and auto-fix suggestions). |
zenith_explain_error |
errorMessage, errorCode? |
Explains compiler diagnostics and provides actionable code corrections and correct syntax examples. |
zenith_build |
source?, filePath?, outputDir? |
Compiles a Zenith project and emits complete production Java 17 & Spring Boot 3 code. |
zenith_get_project_info |
source?, filePath? |
Inspects project configuration, models, fields, enums, security roles, and active endpoints. |
MCP Resources & AI Workflow Prompts
Agents can discover built-in resources under zenith://specification/* and zenith://examples/*, and execute guided workflow prompts:
create_crud_project: Step-by-step guidance to scaffold a complete typed CRUD REST API.create_authentication_system: Guides creation of JWT authentication with Role enums and RBAC.debug_zenith_project: Diagnoses and repairs compiler validation diagnostics.extend_existing_project: Guides extending existing domain models without breaking relational foreign keys.
20. Zenith Core Micro-Engine (In-Memory Simulation)
The Zenith Core Micro-Engine provides an in-memory tree-walk evaluator embedded inside the compiler core and Zenith Studio. It executes custom endpoint action statements, domain precondition guards, and email dispatch contracts in under 5 milliseconds directly on the parsed AST without compiling Java or booting the Spring Boot JVM.
| Execution Mode | Trigger / Button | Scope & Responsibility |
|---|---|---|
| In-Memory Simulation | Simulate (API Tester) |
Instantly evaluates custom endpoint logic (action: { ... }, guard: condition, message, variable calculations var x = ..., and mocked transactional emails send Mail(...)). Returns simulated status, state diffs, and step-by-step precondition traces.
|
| Live Spring Boot Execution | Send (API Tester) |
Hits the live running Spring Boot port on localhost:8080 (or configured port). Handles physical PostgreSQL/H2 SQL transactions, cryptographic BCrypt authentication (/auth/login, /auth/register), JPA repositories, and file uploads.
|
Note on Studio UI: In the API Tester, the Simulate button is selectively displayed only on custom endpoints declaring executable domain logic (actions or guards). Standard persistence operations (CRUD and Auth) use Send to interact with the database.
21. Complete Reference Project
The canonical reference project NexusCommerce illustrates how all Zenith features integrate cleanly. Inspect the complete codebase in zenith-exemples/nexus-commerce/ or test it live in Zenith Studio.