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
edgeControllerswhen 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.nameandserviceBasics.descriptionare 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:
-
Navigate to the Project menu.
-
Open the Services module. You will see a list of existing services.
-
Click Create a New Service (button text defined in patterns as
"Create a New Service"). -
Provide:
-
Service Name (e.g.,
orders) -
Description (optional, but highly recommended)
-
-
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) underbffService. -
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
EventNotificationpatterns. -
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
ShoppingCartconfiguration.
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. -
customVariables–DataMapSimpleItem[](name/value pairs as strings). -
nodejsPackages–NodeJsPackageItem[]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 Settings → Basic Settings
-
Human architects read and edit these fields in forms.
-
AI agents populate
customVariablesandnodejsPackageswhen 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, defaulttrue) -
serviceAllowsUserToLogin(Boolean, defaultfalse) -
httpPort(Integer, default3000) -
routerSuffix(String, optional) -
dataModelName(String, default"main") -
dbType(Enum:"postgresql"or"mongodb") -
useSoftDelete(Boolean, defaulttrue)
Example:
{
"serviceSettings": {
"serviceOptions": {
"serviceRequiresLogin": true,
"serviceAllowsUserToLogin": false,
"httpPort": 3002,
"routerSuffix": null,
"dataModelName": "main",
"dbType": "postgresql",
"useSoftDelete": true
}
}
}
Notes:
-
serviceRequiresLogin: Iftrue, 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 remainfalse. You already have theauthsystem 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 theirObjectBasicSettings.useSoftDelete.
UI Navigation: Service → Service Settings → Service 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 (
propertiesasDataPropertyobjects). -
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:
-
Create a service.
-
Add one or more
dataObjectsthat represent domain entities. -
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 inlibrary.edgeFunctions. -
edgeControllerOptions.loginRequired– whether a valid session is required. -
edgeRestSettings.path– route path relative to the service base URL. -
edgeRestSettings.method– HTTP method (fromHTTPRequestMethodsenum:GET,POST, etc.).
How it works:
-
Request hits
POST /sendmail. -
Mindbricks auth middleware validates login if
loginRequired = true. -
The
sendMailedge function fromedgeFunctionsis executed with arequestobject. -
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
ReadJwtTokenActionandCreateJWTTokenAction(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:
-
Defining the Service in
MindbricksProject.services[]withserviceBasicsandserviceOptions. -
Modeling Data in
dataObjects(DataObject/Property patterns). -
Exposing Operations via
businessLogic(BusinessApi patterns). -
Extending Behavior with
libraryfunctions, templates, assets. -
Defining Custom Routes using
edgeControllerspointing toedgeFunctions. -
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.
Last updated today