Design Your AppDesign Your Service
Design Your App

Building a Service in Mindbricks

Mindbricks is an AI-powered, pattern-driven platform for generating and deploying microservice-based backends. This document serves as a practical guide for both human architects and AI agents in designing robust microservices using the Mindbricks Service pattern.

Each service in Mindbricks is a fully encapsulated unit that manages its own data, logic, APIs, and integrations. This guide walks you through configuring a service’s key components—data models, API routes, business logic, custom code, and edge controllers—using the modular, composable structure of the Mindbricks Pattern Ontology.

It is recommended to read this guide together with:

  • The Mindbricks Pattern Reference (especially Service, DataObject, BusinessApi, ServiceLibrary, EdgeController)

  • The Authentication & Authorization Guide, since many service-level concerns depend on global auth configuration.

Terminology:
The term "architect" refers to both human users (software engineers, product owners, business analysts)
and AI agents working within Mindbricks.

1. Services Inside a Mindbricks Project

At the top level, your project is represented by MindbricksProject, which contains (among other things) a list of services:

{
  "MindbricksProject": {
    "projectSettings": { ... },
    "authentication": { ... },
    "bffService": { ... },
    "notificationService": { ... },
    "services": [
      { /* Service #0 */ },
      { /* Service #1 */ }
    ]
  }
}

Each item in services[] is a Service object representing a distinct microservice. The Service pattern itself is defined as:

{
  "Service": {
    "serviceSettings": "ServiceSettings",
    "dataObjects": ["DataObject"],
    "businessLogic": ["BusinessApi"],
    "library": "ServiceLibrary",
    "edgeControllers": ["EdgeController"]
  }
}

Conceptually, a Service is:

  • A domain boundary in your architecture (e.g., orders, inventory, eventCatalog).

  • A unit that owns:

    • Its data model (dataObjects)

    • Its business APIs (businessLogic)

    • Its custom code and assets (library)

    • Its custom edge endpoints (edgeControllers)

  • A microservice that can be deployed and scaled independently.

You do not manually create system services like auth, BFF, or Notifications; those are generated from project-level patterns (we’ll return to that later).


2. Configuration Notation

To keep documentation consistent across guides, we use JSON fragments to illustrate configuration.

For example:

{
  "services": [
    {
      "serviceSettings": {
        "serviceBasics": {
          "name": "orders",
          "description": "Handles customer orders and related workflows"
        },
        "serviceOptions": {
          "httpPort": 3000,
          "serviceRequiresLogin": true
        }
      }
    }
  ]
}

How to Read This

For human architects (UI view):

For AI agents:

This document will use JSON consistently, but you can still conceptually map it to path-style access or UI navigation when needed.


3. The Service Pattern: Conceptual View

A Mindbricks Service is more than a collection of tables:

  • It defines and enforces domain-specific data models via dataObjects.

  • It owns Business APIs (businessLogic) that encode business processes as declarative workflows.

  • It provides custom extension points via library (functions, templates, assets).

  • It exposes custom routes via edgeControllers when you need full flexibility beyond generated CRUD and Business APIs.

  • It integrates with global authentication, authorization, caching, events, payments (via patterns like AccessControl, RedisEntityCacheSettings, StripeOrder, ShoppingCart, etc., attached to DataObjects and Business APIs).

Each service is compiled into a standalone Node.js-based microservice (by default) with its own dependencies, configuration, and deployment assets.


4. Creating a Service

4.1 JSON / AI-Based Initialization

To define a new service programmatically, you add a Service object into the services array of MindbricksProject:

{
  "services": [
    {
      "serviceSettings": {
        "serviceBasics": {
          "name": "orders",
          "description": "Handles customer orders and related workflows"
        },
        "serviceOptions": {
          "serviceRequiresLogin": true
        }
      },
      "dataObjects": [],
      "businessLogic": [],
      "library": {},
      "edgeControllers": []
    }
  ]
}

This is a minimal valid skeleton:

  • Only serviceBasics.name and serviceBasics.description are strictly needed to start.

  • You can later add data objects, Business APIs, library code, and edge controllers.

4.2 UI-Based Creation

If you're using the Mindbricks Studio:

  1. Navigate to the Project menu.

  2. Open the Services module. You will see a list of existing services.

  3. Click Create a New Service (button text defined in patterns as "Create a New Service").

  4. Provide:

    • Service Name (e.g., orders)

    • Description (optional, but highly recommended)

  5. Click Save. The service now appears in the list and is ready for detailed configuration.

Tip:
Choose a service name that clearly reflects its business domain:
- `eventCatalog`
- `inventory`
- `ticketing`
- `notifications` (only if it's your own domain service – see system services below)

5. System-Generated Services: What You Should NOT Manually Build

Mindbricks automatically provisions several system-level services based on project-level patterns. These are not simply examples—they are deeply integrated into the platform’s architecture.

To preserve system integrity:

5.1 Do Not Manually Design an Auth Service

The auth service is created and configured from the ProjectAuthentication pattern. It handles:

  • User data model

  • Login, logout, and session handling

  • JWT issuance and validation

  • Verification flows (password reset, email/mobile verification, 2FA)

  • Role and permission resolution

  • Multi-tenant identity logic

Trying to create your own generic “user service” with similar responsibilities (e.g., manually modeling a user data object in a separate service) will conflict with the system’s understanding of identity. You may certainly build user-profile or domain-specific profile services linked to the user object (e.g., userProfile service referencing auth:user), but do not attempt to replace the auth service.

5.2 Do Not Manually Design a BFF Service

Mindbricks includes a dedicated BFF service controlled by the BFFService pattern at the project level.

  • You configure dataViews (static/dynamic) under bffService.

  • Mindbricks generates a specialized BFF microservice named bff.

  • It aggregates data from underlying services, optionally via Elasticsearch.

You should not create an ad-hoc service named bff and try to implement cross-service data views manually. Instead, define DataView patterns, and let Mindbricks generate the BFF code.

5.3 Do Not Manually Design a Notification Service

Similarly, the Notification service is governed by the NotificationService and NotificationServiceSettings patterns.

  • It configures providers (SMTP, Twilio, NetGSM, OneSignal, etc.).

  • It listens to Kafka topics and triggers EventNotification patterns.

  • It routes messages via email/SMS/push/in-app with templating.

You should not create your own service to replicate that generic notification behavior. You may create additional domain-specific services that emit events or call Notification APIs, but the baseline notification infra should be left to the system service.

5.4 Do Not Manually Design a “Payment Service” for Stripe Orders

Stripe integration in Mindbricks is handled declaratively via StripeSettings at project level and StripeOrder / ShoppingCart configuration at data-object level.

  • When you mark a DataObject as an order object (via stripeOrder.objectIsAnOrderObject), Mindbricks generates the necessary flows and microservice logic to handle payment intents, webhooks, mapping payment results to order statuses, etc.

  • Similarly, shopping cart logic is enabled via ShoppingCart configuration.

You can of course have an orders or billing service that models your domain, but you should not try to "recreate Stripe integration manually" as a separate generic payment service; that risks diverging from the canonical payment flow.

Mindbricks is declarative-first:
Let the platform generate infrastructure and boilerplate (auth, BFF, notifications, payment flows).
Focus your own services on your domain-specific logic.

6. serviceSettings: The Foundation of a Service

serviceSettings defines the identity and global behavior of the service. According to the ontology:

{
  "ServiceSettings": {
    "serviceBasics": "ServiceBasics",
    "serviceOptions": "ServiceOptions"
  }
}

6.1 serviceBasics

ServiceBasics provides core identifiers and metadata:

  • name – service name (used in files, folders, routes).

  • description – long-form description.

  • frontendDocument – UX/behavioral description for frontend agents.

  • customVariablesDataMapSimpleItem[] (name/value pairs as strings).

  • nodejsPackagesNodeJsPackageItem[] to extend the service’s dependencies.

Example:

{
  "serviceSettings": {
    "serviceBasics": {
      "name": "eventCatalog",
      "description": "Holds event, venue, session and ticketing information.",
      "frontendDocument": "# Event Catalog UX
Define how events are searched, filtered, and browsed...",
      "customVariables": [
        {
          "name": "DEFAULT_TIMEZONE",
          "value": "Europe/Istanbul"
        }
      ],
      "nodejsPackages": [
        {
          "packageName": "@googlemaps/google-maps-services-js",
          "version": "^3.3.0",
          "defaultImportConst": "GoogleMapsClient"
        }
      ]
    }
  }
}

UI Navigation: Service → Service SettingsBasic Settings

  • Human architects read and edit these fields in forms.

  • AI agents populate customVariables and nodejsPackages when extra runtime configuration or libraries are required.

6.2 serviceOptions

ServiceOptions defines fundamental runtime options: HTTP port, login requirements, and persistence details.

Fields include:

  • serviceRequiresLogin (Boolean, default true)

  • serviceAllowsUserToLogin (Boolean, default false)

  • httpPort (Integer, default 3000)

  • routerSuffix (String, optional)

  • dataModelName (String, default "main")

  • dbType (Enum: "postgresql" or "mongodb")

  • useSoftDelete (Boolean, default true)

Example:

{
  "serviceSettings": {
    "serviceOptions": {
      "serviceRequiresLogin": true,
      "serviceAllowsUserToLogin": false,
      "httpPort": 3002,
      "routerSuffix": null,
      "dataModelName": "main",
      "dbType": "postgresql",
      "useSoftDelete": true
    }
  }
}

Notes:

  • serviceRequiresLogin: If true, all APIs require authentication unless explicitly configured otherwise (e.g., a specific Business API or edge route may be public).

  • serviceAllowsUserToLogin: This should almost always remain false. You already have the auth system service for login. Turning this on is for very advanced/exceptional cases (e.g., a custom external identity service).

  • httpPort: Use distinct ports per service (e.g., 3001, 3002, 3003…) to simplify local development and debugging.

  • useSoftDelete: Controls default delete behavior for DataObjects in this service. Individual DataObjects can override this via their ObjectBasicSettings.useSoftDelete.

UI Navigation: Service → Service SettingsService Options


7. dataObjects: Domain Data Model

Although this guide is service-focused, we must highlight how dataObjects fit in:

{
  "dataObjects": [
    {
      "objectSettings": { ... },
      "properties": [ ... ]
    }
  ]
}

Each DataObject:

  • Represents a logical entity (e.g., event, ticket, warehouse, cart).

  • Owns its fields (properties as DataProperty objects).

  • Can define:

    • Authorization (ObjectAuthorization, including tenant scoping and DataObjectAccess)

    • Composite indexes (CompositeIndex)

    • Caching (RedisEntityCacheSettings)

    • Stripe order integration (StripeOrder)

    • Shopping-cart configuration (ShoppingCart)

    • Membership-based access (MembershipSettings)

You typically:

  1. Create a service.

  2. Add one or more dataObjects that represent domain entities.

  3. Attach Business APIs (businessLogic) to those DataObjects.


8. businessLogic: Business APIs (High-Level Overview)

The businessLogic array in a service holds BusinessApi definitions. Each BusinessApi describes a high-level operation (create/get/list/update/delete) on a LocalDataObjectName, plus workflow, parameters, auth options, etc.

At the service level:

{
  "businessLogic": [
    {
      "apiOptions": { ... },
      "authOptions": { ... },
      "restSettings": { ... },
      "whereClause": { ... },
      "dataClause": { ... },
      "actions": { ... },
      "workflow": { ... }
    }
  ]
}

This document doesn’t detail every Business API setting (see your Business API / Workflow guide), but it is important to understand:

  • Business APIs are the primary way you expose CRUD and more complex workflows.

  • When combined with serviceOptions, ObjectSettings, and access control, they define the runtime behavior of the service.


9. library: Custom Code, Templates, Assets, Public Files

ServiceLibrary is the code & asset hub of your service. It is defined as:

{
  "library": {
    "functions": [ "LibModule" ],
    "edgeFunctions": [ "LibModule" ],
    "templates": [ "LibModule" ],
    "assets": [ "LibModule" ],
    "public": [ "LibModule" ]
  }
}

Each LibModule has:

  • moduleName – unique name used for reference.

  • moduleExtension – file extension: js, ejs, txt, svg, pdf, etc.

  • moduleBody – text content (code, markup, etc.).

9.1 functions: Reusable JS Modules

These are general-purpose helper functions used in:

  • MScript logic

  • Business API actions

  • Validations, enrichment, etc.

Example:

{
  "library": {
    "functions": [
      {
        "moduleName": "capitalizeFirstLetter",
        "moduleExtension": "js",
        "moduleBody": "module.exports = function (str) { return str.charAt(0).toUpperCase() + str.slice(1); };"
      }
    ]
  }
}

9.2 edgeFunctions: Functions for Edge Controllers

These are special functions invoked via edgeControllers. They must export an async function with a request parameter and return an object (or throw):

{
  "library": {
    "edgeFunctions": [
      {
        "moduleName": "helloWorld",
        "moduleExtension": "js",
        "moduleBody": "module.exports = async (request) => { return { status: 200, message: 'Hello from the edge function', date: new Date().toISOString() }; };"
      }
    ]
  }
}

9.3 templates: EJS or other templates

Used with RenderDataAction or other rendering logic:

{
  "library": {
    "templates": [
      {
        "moduleName": "welcomeMail",
        "moduleExtension": "ejs",
        "moduleBody": "<html><body><h1>Welcome <%= user.name %></h1></body></html>"
      }
    ]
  }
}

9.4 assets: Internal Files

Static files accessible from backend logic (e.g., credentials, static JSON, logos for PDF generation).

9.5 public: Public Files

Files exposed via a static URL (e.g., favicon, static PDFs).

Rule of thumb:
- Use `functions` for reusable business logic.
- Use `edgeFunctions` for full custom API handlers.
- Use `templates` for HTML/markdown/file rendering.
- Use `assets` for internal-only files.
- Use `public` for files served directly to the client.

10. edgeControllers: Custom Edge Routes

While Business APIs cover most use cases, you sometimes need a custom route that:

  • Calls an edge function directly.

  • Does multiple non-standard operations.

  • Integrates with external providers in a bespoke way.

EdgeController is defined as:

{
  "edgeControllers": [
    {
      "edgeControllerOptions": {
        "functionName": "sendMail",
        "loginRequired": true
      },
      "edgeRestSettings": {
        "path": "/sendmail",
        "method": "POST"
      }
    }
  ]
}
  • edgeControllerOptions.functionName – must match a moduleName in library.edgeFunctions.

  • edgeControllerOptions.loginRequired – whether a valid session is required.

  • edgeRestSettings.path – route path relative to the service base URL.

  • edgeRestSettings.method – HTTP method (from HTTPRequestMethods enum: GET, POST, etc.).

How it works:

  1. Request hits POST /sendmail.

  2. Mindbricks auth middleware validates login if loginRequired = true.

  3. The sendMail edge function from edgeFunctions is executed with a request object.

  4. The function returns an object that Mindbricks sends as HTTP response.

Use edge controllers when:
- You need a completely custom flow not modeled as a BusinessApi.
- You must integrate with external APIs in a very specific way.
- You want full control of request/response handling.

11. (Optional) Share Token Configurations – Conceptual Extension

Your older guide mentioned Share Tokens as a way to share specific data records with external or unauthenticated users. That concept is not explicitly defined in the current patterns.json you shared, but it is conceptually consistent with Mindbricks’ authorization model.

Typical idea:

A hypothetical configuration might look like:

{
  "serviceSettings": {
    "serviceOptions": {
      "serviceRequiresLogin": true
    },
    "serviceAuthentication": {
      "shareTokenConfigurations": [
        {
          "configName": "publicInvoiceView",
          "sharedObject": "invoice",
          "peopleOptions": ["anyoneWithLink"],
          "shareableRoles": ["view"]
        }
      ]
    }
  }
}

Even though this exact pattern is not present in the shared ontology, you can treat Share Tokens as:

  • An advanced pattern for signed, limited access (similar to bucket tokens).

  • Conceptually aligned with ReadJwtTokenAction and CreateJWTTokenAction (which do exist in the Business API action store).

If/when Share Tokens are added to the official ontology, they would likely
appear as a pattern under Auth or Service authentication options.
For now, you can regard them as a project-specific extension or design pattern.

12. Putting It All Together

Designing a Service in Mindbricks involves:

  1. Defining the Service in MindbricksProject.services[] with serviceBasics and serviceOptions.

  2. Modeling Data in dataObjects (DataObject/Property patterns).

  3. Exposing Operations via businessLogic (BusinessApi patterns).

  4. Extending Behavior with library functions, templates, assets.

  5. Defining Custom Routes using edgeControllers pointing to edgeFunctions.

  6. Respecting System Services (auth, BFF, notification, payment flows) instead of re-building them manually.

Every service you define becomes a self-contained domain module:

  • Deployable as an independent microservice.

  • Backed by declarative patterns, not ad-hoc code.

  • Collaborating with other services through BFF, events, and shared auth rules.

Was this page helpful?
Built with Documentation.AI

Last updated today