LazyMagic

LazyMagic MDD

LazyMagic Model Driven Development is a deterministic system code generator. It ingests LazyMagic directives, openAPI specifications, project templates, code templates, and deployment templates to generate deployable artifacts for one or more deployment targets. Unlike LLM based systems, the code generated is consistent across generation runs. All artifacts are generated in clear text. Developers may extend the generated code without fear of losing their work. The generated artifacts include deployment scripts that may be used in CI/CD pipelines for full end-to-end automation into your existing engineering process.

Business Objectives:

  • Reduce technical and business risk.
  • Reduce time-to-market.
  • Reduce development, dev-ops, and support costs.
  • Increase adoption by deploying web, mobile and desktop applications from one codebase.
  • Align production costs with usage.
  • Provide a buttoned down and easily auditable system.
  • Clean Rip-n-Replace strategy for existing systems providing a REST API.

Model Driven Generation

Inputs and Generated Artifacts

LazyMagic ingests inputs and generates artifacts:

  • Developer Provided Inputs
    • OpenApi REST Specification - defines what your system does.
    • LazyMagic Directives - organizes your system components.

  • LazyMagic Provided Inputs (can be modified by developer)
    • Deployment Templates - deployment target snippets used to generate deployment target templates.
    • Code Project Templates - Example: .NET projects.

  • Generated Artifacts
    • Source Code - generated source code.
    • Deployment Scripts - generated scripts suitable for use in your CD Pipeline.
    • Target Platform Templates - final templates suitable for deployment to your target environment.

The LazyMagic generator is available as a Visual Studio IDE Extension and dotnet CLI command.

Continuos Integration Pipeline

It is normal practice to use a services like GitHub or GitLab to compile and test source code checked-in by a developer. If the compiled artifacts are found suitable, they are then made available for deployment by the Continuos Deployment Pipeline. Here at LazyMagic we use GitHub Actions and a GitFlow process to implement our CI. However, LazyMagic makes no substantial assumptions about your CI process implementation.

When doing development, it is common to do local compilation and test before checking in newly developed code (which would kick off a CI process). LazyMagic aggressively supports local development and integration testing. Integration testing is supported on the local workstation by providing a hybrid local .NET Host. This local host runs service-side logic code while also providing access to deployment target services.

For an AWS SAM application this means we run the same code used in AWS Lambdas, but we run it locally so you can debug it easily. Typically, one would launch a debugging session on the client app and one on the service app and then debug calls from the client through the local service and back to the client.

Continuos Deployment Pipeline

It is normal practice to use generalized tools like Teraform, or proprietary tools, like AWS CloudFormation, to deploy your approved artifacts to a target environment. For small systems, you can perform such deployments using command line tools or even a browser based dashboard provided by the target deployment environment.

LazyMagic produces PowerShell scripts that may be used in CD Pipelines or used from your workstation. These scripts use the AWS CloudFormation service along with the AWS CLI and AWS SAM CLI, called.

Deploying directly from a workstation is usually only appropriate for development environments.

Deployment Targets

The current supported targets include:

  • AWS Serverless Application Model (SAM) Stacks using .NET Lambdas.
  • Local .NET hybrid hosting for debugging lambdas.

LazyMagic is designed to be extensible and will support additional deployment targets going forward. Planned extensions include:

  • Azure with Aspire support
  • Intranet (on-prem)
  • Data Center (remote prem)
  • GCP
  • Teraform example scripts

LazyMagic Service Framework

LazyMagic provides a collection of .NET libraries to accelerate service side development. A sample muti-tenant SaaS solution is provided that demonstrates the use of these libraries in a non-trivial reference architecture that you can copy and extend to fit your system needs.

The LazyMagic sample system includes a collection of AWS CloudFront templates that you may modify and extend to suite your system requirements. The provided templates exemplify AWS Best Practices for a multi-tenant system utilizing AWS Services like Cognito, CloudFront, API Gateway, Lambda, and DynamoDB.

Note: We are current working on extending the sample system to include Azure templates so you can target the Azure cloud.

LazyMagic Client Framework

LazyMagic provides a sample app and collection of .NET libraries to accelerate client side development using Microsoft's MAUI and Blazor frameworks.

The LazyMagic sample application, client side libraries, and generated system service access libraries, demonstrate how to target iOS, Android, Windows, MacOS and WebApp deployment with a single codebase. These libraries and sample app go well beyond the simple example projects provided by Microsoft and address many of the differences among native platform and web applications.

Some of the advanced features demonstrated in our sample client app and libraries include:

  • Proper use of service-workers in WASM apps.
  • Static Assets caching implemented in both WASM service-worker and MAUI contexts.
  • Multi-language support.
  • Ability to debug client against local WebHost or Cloud APIs.
  • Consolidated configuration into BlazorUI and Viewmodel libraries.
  • MVVM - Model, View, ViewModel architecture.
  • Use of .NET ReactiveX libraries to make Blazor a first class citizen in a MVVM architecture.

No-Hassle Intellectual Property Approach

LazyMagic MDD is an open source platform. The generator itself is dual-licensed with GPL and Proprietary license options. All supplied libraries, packages, and templates, that may be included in your generated system, are provided under the permissive MIT license allowing your generated code to be licensed under your preferred/required terms; including a proprietary closed-source license.

Audience

This documentation is tailored to full-stack architects and those with an interest in understanding the concepts and particulars of designing systems at scale using modern design patterns. The current version of LazyMagic MDD focuses on the following technologies:

  • Multi-Tenant SaaS deployments.
  • Microsoft .NET Services.
  • AWS Serverless Application Model Architecture.
  • AWS CloudFront Deployments.
  • Microsoft .NET MAUI Applications.
  • Microsoft Blazor Web Assembly Applications.
  • OpenAPI (formerly Swagger) REST API specifications.

We do not attempt to provide a step-by-step tutorial. However, we do provide a complete and rather robust sample system generated by LazyMagic and all of the necessary system specification documents necessary to generate the system from scratch and deploy it.

Technical Objectives:

  • Generate non-trivial modular systems.
  • Provide multi-target deployments. eg: AWS Cloud, Local Deployment, (Azure, Intranet, Data Center, and GCP coming)
  • Promote best security practices.
  • Produce an auditable codebase.
  • Promote a high level of code reuse.
  • Support CI/CD pipelines.
  • Enable and embrace extension of generated code classes.
  • Enhance team productivity at senior and journeyman levels.
  • Provide a roadmap for junior programmers to develop journeyman level skills.
  • Use AWS Free Tier services to avoid "idle" system costs.
AWS Costs

Many AWS Services are "Serverless". Not all of them are included in the AWS Free Tier. For instance, we use the DynamoDB database in our sample system because it is both Serverless and included in the AWS Free Tier. In addition, DynamoDB encrypts data at rest and this feature is included in the AWS Free Tier service.

Our sample system includes only services that are provided in the AWS Free Tier. Generally, these are services that cost nothing unless a substantial amount of usage is reached.

Reference Architecture

Our sample system implements the AWS Serverless Application Model (SAM) reference architecture. We use the AWS CloudFormation service to deploy the system as a collection of SAM stacks. This sample system is a multi-tenant Software-as-a-Service (SaaS) system with many advanced features:

  • Tenants - each tenant has its own domain name, database, static assets, and collection of web apps.
  • Subtenants. A Tenant may have Subtenants which have their own subdomain name, database, static assets, and collection of web apps.
  • Tenant assets may be shared with Subtenants.
  • WebApps can be shared across tenancies or be customized for a tenant or subtenant.
  • DynamoDB accessed via .NET repository projects that abstract access into common CRUDL operations.
  • Multi-Authentication - use different Cognito user pools for administration, employees, and consumers.
  • Sophisticated Authorization - generated code has hooks for easily implementing user authorization to API methods.

Here is a high level diagram of this SAM architecture:

Note: For developers that have used three-tier service stacks, this architecture looks sparse and simplistic. That is the point of Serverless Application Models. There are no instances to manage or scale; there is no Virtual Private Cloud network to define, secure, and manage. There are only Services, no servers. Of course, the AWS Services have servers behind them, but you don't have to configure, manage or scale them, so from your perspective, you have a serverless architecture.

LazyMagic is not limited to the use of the AWS Serverless Application Model (SAM) architecture.

LazyMagic Directives

Systems are defined as modular components, in a LazyMagic.yaml file, using a hierarchy of directives:

  • Schema - ingest data entities from OpenApi schema components.
  • Module - ingest methods from OpenApi paths. Schema directive references are automatically discovered.
  • Container - defines executables that references Module directives.
  • Queue - defines a message queue service.
  • Authentication - defines an authentication service.
  • Api - defines an API Gateway that references Container directives. May also reference an Authentication directive.
  • Service - defines a deployment that references Api directives.
  • WebApp - defines a web application that references API directives.
  • Tenancy - defines a deployment that references WebApp directives.

A system definition may have many of each type of directive.

Since directives reference other directives, a dependency graph is maintained and used to generate artifact closures, thereby eliminating manual configuration of code and deployment scripts.

Modular system design is achieved using multiple Schema and Module directives, each referencing different OpenAPI specification documents. The final aggregate OpenAPI specification, for each API, is generated by traversing the directive dependencies: eg: Api -> Containers -> Modules -> Schemas.

Because a Container may be referenced by multiple Api directives, each Api serves a different aggregate OpenAPI specification.

In general, modularity is achieved based on these directives relation axioms:

  • Many Tenant to many WebApp.
  • Many WebApp to many Api.
  • Many Api to one System.
  • Many Api to one Authentication.
  • Many Api to many Container.
  • Many Container to many Module.
  • Many Module to many Schema.
  • One Module to one OpenApi file.
  • One Schema to one OpenApi file.

The use of modular system design is not mandated. You can define a monolithic system having one OpenAPI specification file, and one each of Schema, Module, Container, Api, Service and Authentication directives. You may still have multiple WebApp directives and multiple Tenancy directives but they all reference the single API directive and authenticate using the single Authentication directive.

The use of modular system design offers numerous advantages:

  • Limiting exposure of Apis to only those clients that need that Api.
  • Module reuse. OpenAPI specs and code can be reused in other systems easily.
  • Smaller Container size. Containers use fewer libraries.
  • Authentication by Api doesn't require extra code. (e.g. no need to use a Lambda to authenticate)
  • Smaller Client size, client's only need to load the Api SDK(s) they need.

In general, we treat Containers, for example a Lambda or Fargate instance, as modular-monoliths. To satisfy the modular-monoliths pattern, each Module referenced by the Container must satisfy these criteria:

  • Must be Independent and Interchangeable.
  • Must have a well-defined Interface exposed to other modules.

Directive Artifacts

Directive artifacts map system and code elements onto a target platform's services. Here is our how the various directive artifacts map to AWS services and .NET code in our sample system. Each directive may have one or more Artifacts associated with it.

Artifact Types

Artifacts types include:

  • Application Code - in our sample system, the application code is generated into .NET projects.
  • Deployment Templates - our sample system uses CloudFormation templates. CloudFormation is an AWS service that creates and updates AWS Stacks based on the content of the provided template. AWS Stacks contain resources these resources are generally just configurations of AWS services. The one exception to this is that AWS Lambdas also reference the DotNetLambda project's executable code. This executable code is deployed to the cloud and used by the Lambda service to launch instances of your Lambdas to handle incoming requests in a scalable fashion.
  • Deployment Scripts - in our sample system, the deployment scripts are PowerShell scripts that deploy static assets and CloudFormation templates to the AWS Cloud. This deployment creates and/or updates an AWS Stack.

AWS CloudFormation Templates

Here are our Sample System's CloudFormation templates and the AWS CLI and AWS SAM CLI, called from PowerShell scripts, to create AWS Stacks.

The scripts (*.ps1) and CloudFormation templates (*.yaml) in bold are final artifacts ready for use in a CI/CD pipeline (or from your workstation). The items in italics are template scripts or CloudFormation template snippets ingested by generators to produce the final artifacts.

Edit the scripts, and template snippets to modify the generated system to suit your specific needs. The templates and scripts provided are robust and may be suitable for many system requirements as is.

Artifact Generators

Each directive may have one or more artifact Generators associated with them. Each Generator produces one or more artifacts for the system. For example, here are the Generators, grouped by associated directives, supporting the generation of .NET projects and AWS SAM deployment templates and scripts in the sample system's reference architecture.

  • Schema artifact generators
    • DotNetSchemaProject - generates C# classes library for each OpenApi schema components.
    • DotNetRepoProject - generates C# CRUDL persistence library for schema components.

  • Module artifact generators
    • DotNetControllerProject - generates C# controller library for OpenApi paths.

  • Container artifact generators
    • DotNetApiLambdaProject - generates a C# project that handles requests from API Gateway.
    • DotNetSQSlambdaProject - generates a C# project that handles events from SQS.
    • DotNetWSApiLambdaProject - generates a C# project that handles WebSocket connections.
    • AwsApiLambdaResource - generates AWS Api Lambda resource definitions.
    • AwsSQSLambdaResource - generates AWS SQS Lambda resource definitions.
    • AwsWSApiLambdaResource - generates AWS WebSocket Lambda resource definition.

  • Authentication artifact generators
    • AwsCognitoResource - generates AWS Cognito resource definition used in stack templates.

  • Api artifact generators
    • AwsHttpApiResource - generates AWS ApiGateway resource definition.
    • AwsWSApiResource - generates AWS web socket resource definition.
    • DotNetHttpApiSDKProject - generates C# client SDK to call Http Api Gateway.
    • DotNetWSApiSDKProject - generates C# SDK to call WebSocket Api Gateway.

  • Service artifact generators
    • AwsServiceStackTemplate - generates SAM template and deployment script.
    • DotNetLocalWebApiProject - generates local web host for debugging.

  • Tenancy artifact generators
    • AwsTenancyStackTemplate - generates SAM template and deployment script.

Multiple Deployment Targets

New targets are supported through the addition of new artifact generators. New Artifact Generator specifications are added to the existing Directives, producing the artifacts required for additional target deployments.

Modifying Artifact Generation

LazyMagic generators reference template projects in your solution to generate the artifacts. This means you may edit these template projects to generate artifacts tailored to your specific needs. This allows solution by solution control over artifact generation.

You may also create your own Artifact Generator to implement more substantial changes to artifact generation. The existing generators provide a solid framework for the development of new generators.

Plug-in Support

We are currently implementing a plug-in architecture for artifact generators. Currently, you would fork the LazyMagicMDD repo to add your own artifact generators. With plug-in support, LazyMagic will discover your plug-in and register it for use. This is a high-priority feature for the team.