Skip to content

Using a schema (in Mermaid mmd), create a ReST server with validation logic using Mongo for persistance

Notifications You must be signed in to change notification settings

fptmark/schema2rest

Repository files navigation

Schema2Rest (S2R)

This project takes a Mermaid schema with enhancements and builds a ReST server for each entity. Validation logic is autogenerated.

The data is stored in a MongoDB database.

Installation

  1. Clone the repository
  2. Install dependencies:
    pip install -r requirements.txt
    
  3. Add the bin directory to your PATH for easy access:
    export PATH=$PATH:/path/to/schema2rest/bin
    

Usage

Option 1: Using Makefile (recommended)

  1. Copy the S2R Makefile to a new project directory
  2. Edit the Makefile and set S2R_DIR to the cloned repo location
  3. Create a .mmd file with your schema
  4. Execute make firsttime on first run
  5. Execute make all on changes to the schema

Option 2: Direct Command Line Usage

Converting a Schema

To convert an MMD schema to YAML:

./bin/convert_schema.py schema.mmd output_dir

Or from anywhere if you've added the bin directory to your PATH:

convert_schema.py schema.mmd output_dir

Generating a REST API

To generate a REST API from a schema:

./bin/schema2rest.py schema.yaml output_dir

Or from anywhere if you've added the bin directory to your PATH:

schema2rest.py schema.yaml output_dir

Environment

  1. Assumes MongoDB is installed
  2. Uses config.json to define the MongoDB config and server URL

MMD Enhancements (uses MMD comments)

  1. Allows a "BaseEntity" that all entities include (e.g. - id, updatedAt)
  2. Supports auto generation of fields (e.g. - id)
  3. Supports extensive validation logic
  4. Supports unique field constraints
  5. Automatically updates unique indexes for constraints (deletes unused and creates new)
  6. Support for UI metadata via the @ui decorator

Features

  • Convert MMD schema to YAML with minimal bloat
  • Generate a FastAPI-based REST API from a schema
  • Generate database connection code
  • Generate model definitions
  • Generate API routes
  • Support for validation rules
  • Support for UI metadata

UI Metadata

The @ui decorator allows you to customize how fields are displayed in the user interface. Only explicitly defined UI attributes will be included in the YAML, while sensible defaults are generated in the model phase.

Supported UI Attributes

Attribute Description Example Default
displayName Human-readable name for the field @ui firstName { displayName: "First Name" } Converted from camelCase to Title Case
display When to display the field @ui password { display: "form" } "always" (except passwords are "form")
widget UI control type @ui email { widget: "email" } Inferred from field type and validation
placeholder Placeholder text @ui email { placeholder: "[email protected]" } None
helpText Helper text shown below the field @ui password { helpText: "Min 8 characters" } None
readOnly Whether field is read-only @ui createdAt { readOnly: true } false
displayAfterField Field to display after (for ordering) @ui lastName { displayAfterField: "firstName" } Previous field name

Display Modes

The display attribute can have the following values:

  • always - Display in all views (default)
  • detail - Display only in detail views, not in tables/lists
  • form - Display only in edit/create forms, not in read-only views
  • hidden - Don't display in UI at all

Note: Setting display: "hidden" is the preferred way to hide fields rather than using the deprecated hidden attribute.

Widget Types

Common widget types include:

  • text - Standard text input (default for strings)
  • textarea - Multi-line text input (default for strings with maxLength > 100)
  • password - Password input with masked text
  • email - Email input with validation
  • url - URL input with validation
  • number - Numeric input (default for Number/Integer)
  • checkbox - Boolean checkbox (default for Boolean)
  • select - Dropdown select (default for fields with enum)
  • multiselect - Multi-select control (default for Array types)
  • date - Date picker (default for ISODate)
  • jsoneditor - JSON editor (default for JSON type)
  • reference - Reference selector (default for ObjectId references)

MMD Snippet

erDiagram
    BaseEntity {
        ObjectId _id
        ISODate createdAt
        ISODate updatedAt
    }
    %% @validation BaseEntity
    %% _id { type ObjectId, required true, autoGenerate true }
    %% createdAt { type ISODate, required true, autoGenerate true }
    %% updatedAt { type ISODate, required true, autoUpdate true }

    Account {
        ISODate expiredAt
    }
    %% @inherits BaseEntity
    %% @validation Account
    %% expiredAt: { type: ISODate, required: false }

    User {
        ObjectId accountId
        String username
        String email
        String password
        String firstName
        String lastName
        String gender
        Boolean isAccountOwner
    }
    %% @inherits BaseEntity
    %% @validation User
    %% @unique username ### Note specified combined field indexes by "username + email"
    %% accountId: { type: ObjectId, required: true }
    %% username: { type: String, required: true, minLength: 3, maxLength: 50 }
    %% email { type String, required true, minLength 8, maxLength 50, pattern ^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ }
    %% @ui email { widget: "email", helpText: "Please enter a valid email address" }
    %% password: { type: String, required: true, minLength: 8 }
    %% @ui password { widget: "password", display: "form" }
    %% firstName: { type: String, required: true, maxLength: 100 }
    %% lastName: { type: String, required: true, maxLength: 100 }
    %% gender { type String, required false, enum [male, female, other] }
    %% isAccountOwner: { type: Boolean, required: true }

Other Validations

    %% name: { type: String, required: true, maxLength: 100 }
    %% preferences: { type: JSON, required: false }
    %% radiusMiles: { type: Integer, required: false, min: 0 }
    %% tag: { type: String, required: true, maxLength: 50 }
    %% affinity: { type: Integer, required: true, min: -100, max: 100 }
    %% url: { type: String, required: true, pattern: ^https?://[^\s]+$ }
    %% title: { type: String, required: true, maxLength: 200 }
    %% location: { type: String, required: false, maxLength: 200 }
    %% cost: { type: Number, required: false, min: 0 }
    %% recurrence: { type: String, required: false, enum: [daily, weekly, monthly, yearly] }

About

Using a schema (in Mermaid mmd), create a ReST server with validation logic using Mongo for persistance

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published