QuickCode Documentation

Complete guide to using QuickCode for microservice generation

Not boilerplate code
Not just templates
Turn your DBML designs into production-ready, maintainable microservices.

1. Quick Start

Get started with QuickCode in 5 minutes. Follow these simple steps to create your first microservice project.

Step 1: Create Your DBML Diagram

Use the integrated DBML editor to create your database schema. Start with a simple example:

Enum "ORDER_STATUS" {
  PENDING [note: "Pending"]
  PAID [note: "Paid"]
  SHIPPED [note: "Shipped"]
  DELIVERED [note: "Delivered"]
  CANCELLED [note: "Cancelled"]
}

Table "USER" {
  "ID" integer [pk, increment, not null]
  "EMAIL" string
  "NAME" string
  "CREATED_AT" datetime
  "IS_NEW" boolean
}

Table "PRODUCT" {
  "ID" integer [pk, increment, not null]
  "TITLE" string
  "PRICE" decimal
  "STOCK_QUANTITY" integer
}

Table "ORDER" {
  "ID" integer [pk, increment, not null]
  "USER_ID" integer
  "ORDER_DATE" datetime
  "TOTAL_AMOUNT" decimal
  "STATUS" ORDER_STATUS
}

Ref: "ORDER"."USER_ID" > "USER"."ID"

Step 2: Enter Project Details

  • Project Name: Choose a unique name for your project (lowercase, no spaces)
  • Email: Your email address for project identification
  • Secret Code: Create a secure code to protect your project

Step 3: Select Modules

Choose the microservice modules you need for your project. Common modules include:

  • API Gateway
  • Authentication Service
  • API Services for each table/module
  • Event Listener Service

Step 4: Configure Database

Select your target database type. QuickCode supports:

  • PostgreSQL - Advanced open-source relational database
  • MySQL - Popular open-source database
  • SQL Server - Microsoft SQL Server

The generated SQL and database code will be optimized for your chosen database type.

Step 5: Choose Architectural Pattern

Select the architectural pattern that defines the structure of your generated code:

  • CQRS and Mediator - Command Query Responsibility Segregation with Mediator pattern. Separates read and write operations, providing better scalability and maintainability.
  • Service - Traditional service-oriented architecture. Simpler structure with service layers handling business logic.

Each pattern provides different benefits and suits different project requirements. Choose based on your project complexity and team preferences.

Step 6: Generate and Access

Click "Generate Microservices" and wait for the process to complete. Once done, access your code via the provided GitHub link.

2. DBML Format Guide

What is DBML?

DBML (Database Markup Language) is a simple, readable syntax for describing database schemas. It's designed to be easy to write and understand, making it perfect for documenting and generating database structures.

Basic Syntax

DBML uses a clean, intuitive syntax:

// Table definition
Table table_name {
  column_name type [constraints]
}

// Relationships
Ref: table1.column > table2.column

Enum Definitions

Define enums for reusable value types:

Enum "ORDER_STATUS" {
  PENDING [note: "Pending"]
  PAID [note: "Paid"]
  SHIPPED [note: "Shipped"]
  DELIVERED [note: "Delivered"]
  CANCELLED [note: "Cancelled"]
}

Enum "PAYMENT_METHOD" {
  CREDIT_CARD [note: "Credit Card"]
  BANK_TRANSFER [note: "Bank Transfer"]
  CASH_ON_DELIVERY [note: "Cash on Delivery"]
  DIGITAL_WALLET [note: "Digital Wallet"]
}

Table Definitions

Define tables with their columns and constraints:

Table "USER" {
  "ID" integer [pk, increment, not null]
  "EMAIL" string
  "NAME" string
  "CREATED_AT" datetime
  "IS_NEW" boolean
  "COMPANY_ID" integer
}

Table "PRODUCT" {
  "ID" integer [pk, increment, not null]
  "TITLE" string
  "PRICE" decimal
  "CURRENCY" CURRENCY
  "STOCK_QUANTITY" integer
  "DESCRIPTION" json
}

Common Column Types

Integer Types:
  • integer or int - Integer numbers (32-bit)
  • big_integer or bigint - Large integer numbers (64-bit)
  • small_integer or smallint - Small integer numbers (16-bit)
  • tinyint - Very small integer numbers (8-bit)
String Types:
  • string or varchar(n) - Variable-length string (default: 250 chars)
  • short_string - Short string (50 chars)
  • big_string - Large string (1000 chars)
  • large_string or text - Very long text (unlimited)
  • html - HTML content (unlimited)
  • json - JSON data type (for flexible schema, unlimited)
  • yaml or yml - YAML content (unlimited)
  • phone - Phone number (50 chars)
  • email - Email address (500 chars)
  • address - Address text (1000 chars)
  • url - URL string (1000 chars)
Date/Time Types:
  • datetime or datetime2 - Date and time
  • datetimeoffset - Date and time with timezone offset
Boolean Types:
  • boolean or bool or bit - True/false
Decimal/Numeric Types:
  • decimal or decimal(p, s) - Decimal with precision
  • money - Monetary value (precision: 18, scale: 2)
  • decimal_degree - Geographic coordinates (precision: 9, scale: 6)
  • decimal_18_8 - High precision decimal (precision: 18, scale: 8)
  • float - Floating-point numbers
Binary Types:
  • blob_image - Image/blob data stored as string (500 chars)
  • image - Image data stored as binary (varbinary)
  • file - File data stored as binary (varbinary)
Special Types:
  • guid or uuid - Globally unique identifier
  • Enum types - Custom enum (e.g., ORDER_STATUS, PAYMENT_METHOD)

Example with enum:

Table "ORDER" {
  "ID" integer [pk, increment]
  "STATUS" ORDER_STATUS
  "PAYMENT_METHOD" PAYMENT_METHOD
  "DETAILS" json
}

Constraints

  • pk - Primary key
  • increment - Auto-increment
  • unique - Unique constraint
  • not null - Not null constraint
  • default: value - Default value

Relationships

Define relationships between tables:

// One-to-many
Ref: "ORDER"."USER_ID" > "USER"."ID"
Ref: "PRODUCT"."PRODUCT_GROUP_ID" > "PRODUCT_GROUP"."ID"

// Many-to-many (with junction table)
Ref: "USER_COUPON"."USER_ID" > "USER"."ID"
Ref: "USER_COUPON"."COUPON_ID" > "COUPON"."ID"

// One-to-one
Ref: "ORDER"."SHIPPING_INFO_ID" > "SHIPPING_INFO"."ID"
  • > - One-to-many or many-to-one
  • - - One-to-one

Note: Use double quotes for table and column names that contain uppercase letters or special characters.

QuickCode DSL - Custom Operations

⚠️ Important: QuickCode automatically generates default CRUD operations for every table:

  • GET /api/{table-name} → List all records (supports pagination, filtering)
  • GET /api/{table-name}/{id} → Get record by ID
  • POST /api/{table-name} → Create new record
  • PUT /api/{table-name}/{id} → Update record by ID
  • DELETE /api/{table-name}/{id} → Delete record by ID

What is QuickCode DSL?

QuickCode DSL (Domain-Specific Language) is a simple, intent-based language used within DBML Notes to define custom backend operations. It's not a programming language—it has no control flow, variables, loops, or branching. It only describes data access and simple state changes in a single line.

Each DSL line uses semantic keywords in the form Keyword:Value. The order is not important; keywords define meaning. QuickCode generates the full backend implementation—HTTP endpoints, service methods, repository queries, SQL, and DTOs—from your DSL definitions.

You should ONLY add custom business logic operations using QuickCode DSL in your DBML Notes:

  • ✅ Custom filter queries (e.g., Query:GET_BY_STATUS[])
  • ✅ Existence checks (e.g., Query:EXISTS_BY_EMAIL[?])
  • ✅ Partial updates with meaningful names (e.g., Update:UPDATE_STATUS)
  • ✅ Custom delete operations (e.g., Delete:DELETE_BY_USER_ID)

QuickCode DSL - Core Keywords

QuickCode DSL uses semantic keywords in the form Keyword:Value. Order is not important; keywords define meaning:

  • Query:<NAME> - Defines a query operation
  • Update:<NAME> - Defines an update operation
  • Delete:<NAME> - Defines a delete operation
  • Where:<conditions> - Filter conditions
  • Select:<fields> - Fields to return (for queries)
  • Set:<operations> - Fields to update (for updates)
  • Tables:<tables> - Table context (for joins)

Query Format

⚠️ CRITICAL: Every Query MUST have a keyword in brackets!

Query:NAME[Keyword] Tables:... Where:... Select:...

Available Keywords:

  • [] or [List] - Returns array of items (most common)
  • [1] or [First] - Returns single object
  • [P] or [Pager] - Returns paginated list
  • [*] or [Count] - Returns count number
  • [?] or [Exists] - Returns true/false

Examples from real projects:

Query:GET_NEW_USERS[] Where:IS_NEW[true], CREATED_AT[>|NowRemoveDays30] Select:ID, EMAIL, NAME, CREATED_AT
Query:SEARCH_PRODUCTS[] Where:TITLE[Like], PRICE[Between], PRODUCT_GROUP_ID Select:ID, TITLE, PRICE, CURRENCY
Query:LIST_LOW_STOCK[] Where:STOCK_QUANTITY[<|10] Select:ID, TITLE, STOCK_QUANTITY
Query:GET_ABANDONED_CARTS[] Where:IS_ACTIVE[true], CREATED_AT[<|NowAddHours24] Select:ID, USER_ID, CREATED_AT
Query:GET_ORDERS_BY_STATUS_DATE[] Where:STATUS, ORDER_DATE[Between] Select:ID, ORDER_DATE, TOTAL_AMOUNT
Query:GET_USER_ORDERS[] Tables:ORDER O, PAYMENT P Where:O.USER_ID, P.STATUS[COMPLETED] Select:O.ID ORDER_ID, O.TOTAL_AMOUNT ORDER_TOTAL_AMOUNT

Update Format

⚠️ CRITICAL: Set: is REQUIRED in every Update!

Update:NAME Where:... Set:...
Update:NAME Tables:... Where:... Set:...

Important Rules:

  • Update names must be descriptive, NOT table name with UPDATE_ prefix
  • Update/Delete do NOT use keywords (no brackets after name)
  • Set: section is REQUIRED for Update
  • Tables: section is optional - only use when JOIN is needed across multiple tables

Examples from real projects:

Update:REDUCE_STOCK Where:ID Set:STOCK_QUANTITY[-1]
Update:DEACTIVATE_STALE_CARTS Where:CREATED_AT[<|NowRemoveHours48], IS_ACTIVE[true] Set:IS_ACTIVE[false]
Update:MARK_PAYMENT_FAILED Where:STATUS[PENDING], PAYMENT_DATE[<|NowRemoveHours1] Set:STATUS[FAILED]
Update:MARK_SHIPMENT_DELIVERED Where:ID, STATUS[NotEquals|DELIVERED] Set:STATUS[DELIVERED], DELIVERED_DATE[Now]

Delete Format

Delete:NAME Where:...
Delete:NAME Tables:... Where:...

Important Rules:

  • Delete does NOT have Set: section!
  • Tables: section is optional - only use when JOIN is needed across multiple tables

Examples:

Delete:DELETE_BY_USER_ID Where:USER_ID
Delete:DELETE_BY_POST_ID Where:POST_ID
Delete:REMOVE_EXPIRED_COUPONS Where:END_DATE[<|Now]

QuickCode DSL - Operators and Semantics

QuickCode DSL supports various operators for filtering and data manipulation:

  • = - Equality
  • Like - String contains
  • Between - Range
  • >| - Greater than
  • <| - Less than
  • NowRemoveDays30 - Current time minus 30 days (deterministic time functions)
  • NowAddHours24 - Current time plus 24 hours

Important: Time functions are deterministic and not runtime parameters. Nothing that is not explicitly written in the DSL may be assumed—no implicit joins, ordering, or limits.

Complete Example with QuickCode DSL

Enum "ORDER_STATUS" {
  PENDING [note: "Pending"]
  PAID [note: "Paid"]
  SHIPPED [note: "Shipped"]
  DELIVERED [note: "Delivered"]
  CANCELLED [note: "Cancelled"]
}

Table "USER" {
  "ID" integer [pk, increment, not null]
  "EMAIL" string
  "NAME" string
  "CREATED_AT" datetime
  "IS_NEW" boolean
  "COMPANY_ID" integer
  
  Note: '''
    Query:GET_NEW_USERS[] Where:IS_NEW[true], CREATED_AT[>|NowRemoveDays30] Select:ID, EMAIL, NAME, CREATED_AT
  '''
}

Table "PRODUCT" {
  "ID" integer [pk, increment, not null]
  "TITLE" string
  "PRICE" decimal
  "STOCK_QUANTITY" integer
  
  Note: '''
    Query:SEARCH_PRODUCTS[] Where:TITLE[Like], PRICE[Between], PRODUCT_GROUP_ID Select:ID, TITLE, PRICE, CURRENCY
    Query:LIST_LOW_STOCK[] Where:STOCK_QUANTITY[<|10] Select:ID, TITLE, STOCK_QUANTITY
    Update:REDUCE_STOCK Where:ID Set:STOCK_QUANTITY[-1]
  '''
}

Table "ORDER" {
  "ID" integer [pk, increment, not null]
  "USER_ID" integer
  "ORDER_DATE" datetime
  "TOTAL_AMOUNT" decimal
  "STATUS" ORDER_STATUS
  
  Note: '''
    Query:GET_ORDERS_BY_STATUS_DATE[] Where:STATUS, ORDER_DATE[Between] Select:ID, ORDER_DATE, TOTAL_AMOUNT
    Query:GET_USER_ORDERS[] Tables:ORDER O, PAYMENT P Where:O.USER_ID, P.STATUS[COMPLETED] Select:O.ID ORDER_ID, O.ORDER_DATE ORDER_DATE, O.TOTAL_AMOUNT ORDER_TOTAL_AMOUNT
  '''
}

Table "CART" {
  "ID" integer [pk, increment, not null]
  "USER_ID" integer
  "CREATED_AT" datetime
  "IS_ACTIVE" boolean
  
  Note: '''
    Query:GET_ABANDONED_CARTS[] Where:IS_ACTIVE[true], CREATED_AT[<|NowAddHours24] Select:ID, USER_ID, CREATED_AT
    Update:DEACTIVATE_STALE_CARTS Where:CREATED_AT[<|NowRemoveHours48], IS_ACTIVE[true] Set:IS_ACTIVE[false]
  '''
}

// Relationships
Ref: "ORDER"."USER_ID" > "USER"."ID"
Ref: "CART"."USER_ID" > "USER"."ID"

Note: Basic CRUD operations (GET_BY_ID, GET_ALL, basic UPDATE/DELETE) are automatically generated and should NOT be added to QuickCode DSL in Notes.

3. Project Creation Workflow

Project Parameters

  • Project Name: Must be lowercase, alphanumeric with hyphens/underscores. Must be unique.
  • Email: Used for project identification and access control.
  • Secret Code: Acts as a password for project access. Store it securely.

Module Selection

Choose from available microservice modules based on your architecture needs. Each module will be generated as a separate service.

Database Type Selection

Select your target database. QuickCode supports the following database types:

  • PostgreSQL - Advanced open-source relational database with extensive features
  • MySQL - Popular open-source database, widely used
  • SQL Server - Microsoft SQL Server, enterprise-grade

The generated SQL queries, connection strings, and database-specific code will be optimized for your chosen database type.

Architectural Pattern

Choose an architectural pattern that defines the structure and organization of your generated code:

  • CQRS and Mediator - Command Query Responsibility Segregation with Mediator pattern. Separates read and write operations, providing better scalability and maintainability. Ideal for complex business logic and high-performance applications.
  • Service - Traditional service-oriented architecture. Simpler structure with service layers handling business logic. Ideal for straightforward CRUD operations and simpler applications.

Each pattern provides different benefits and suits different project requirements. Choose based on your team's preferences and project complexity.

4. CLI Tool Guide

Installation

macOS (Homebrew):

brew install quickcode-cli

Windows (Scoop):

scoop bucket add quickcode https://github.com/QuickCodeNet/quickcode-cli-bucket
scoop install quickcode

Linux:

Download the latest release from GitHub and add to your PATH.

Basic Commands

# Check if project exists
quickcode myproject check

# Create a new project
quickcode myproject create --email [email protected]

# Store project secret code
quickcode myproject config --set secret_code=YOUR_SECRET_CODE

# Download DBML files
quickcode myproject get-dbmls

# Upload DBML changes
quickcode myproject update-dbmls

# Generate microservices
quickcode myproject generate

# Clone project from GitHub
quickcode myproject pull

For detailed CLI documentation, visit our CLI Tool page.

5. Best Practices

DBML Writing Tips

  • Use descriptive table and column names
  • Always define primary keys
  • Use appropriate data types (avoid oversized types)
  • Define relationships explicitly using Ref:
  • Add comments to complex tables/columns

QuickCode DSL Best Practices

  • Remember: Default CRUD operations are automatically generated - don't add them!
  • Every Query MUST have a keyword: Use [] for lists, [1] for single items, [?] for existence checks, [*] for counts, [P] for pagination
  • Update names must be descriptive: Use names like UPDATE_STATUS, UPDATE_PASSWORD, NOT table name with UPDATE_ prefix
  • Every Update MUST have Set: Always include what fields to update
  • Update/Delete do NOT use keywords: No brackets after Update/Delete names
  • Only add custom business logic: Filter queries, existence checks, partial updates, custom deletes
  • Use Tables: for JOINs: Only when you need data from multiple related tables in one result

Project Organization

  • Keep project names simple and descriptive
  • Store your secret codes securely (password manager)
  • Use the same email for related projects
  • Document your DBML changes

Security

  • Never share your secret codes
  • Don't store sensitive data in DBML files
  • Review generated code before deployment
  • Keep your generated code repositories private if needed