@mongalayer/server

Configuration

How to create and configure a Mongalayer server instance.

The Mongalayer class is the central entry point on the server side. It connects to MongoDB, holds your collection definitions (schemas + access rules), and executes operations.

Check out the AWS Lambda / Express examples in Quick start for how to integrate with your HTTP server.

Creating an instance

import { MongoClient } from "mongodb";
import { Mongalayer } from "@mongalayer/server";

const mongoClient = new MongoClient("mongodb://localhost:27017");

const layer = new Mongalayer(mongoClient, {
    // Each key is a MongoDB collection name
    users: {
        schema: userSchema,
        access: userAccess
    },
    projects: {
        schema: projectSchema,
        access: projectAccess
    }
});

The first argument is a standard MongoDB MongoClient instance. The second argument is an object mapping collection names to their configuration, each containing:

  • schema — a Zod object schema describing the document structure
  • access — an array of access definitions (see Access Control)

Options

You can pass an optional third argument to configure behavior:

const layer = new Mongalayer(mongoClient, collections, {
    useSessions: true,    // Enable MongoDB sessions (default: true)
    debugging: false,     // Enable debug logging (default: false)
    accessDefaults: {
        document: AccessPermissions.Read,  // Default document permission
        delete: false                      // Default delete permission
    }
});

useSessions

When true, Mongalayer starts a MongoDB session for each operation. This is required for transactions and is enabled by default.

debugging

When true, Mongalayer logs debug information to the console and throws the original Zod/MongoDB errors instead of wrapping them. Useful during development.

You can also enable debugging via the MONGALAYER_DEBUG=1 environment variable.

accessDefaults

Default permissions applied when a document does not match any access role, or when a role doesn't explicitly define a permission:

PropertyTypeDefaultDescription
documentAccessPermissionAccessPermissions.ReadDefault document-level permission
deletebooleanfalseWhether documents can be deleted by default

Executing operations

Mongalayer provides two methods for executing operations:

execute(action, stringifiedPayload, accessPayload) => string

The primary method for HTTP integrations. Accepts a JSON-stringified payload and returns a JSON string result. Handles serialization of special types like Date and RegExp.

The client SDK uses the same (de)serialization methods.
const payload = `{"filter":{},"options":{"limit":10}}`;

const result = await layer.execute(
    { database: "myapp", collection: "projects", operation: "find" },
    payload,
    { user: { id: "user-123" } }
);

// result is a JSON string from a serialized object

executeRaw(action, payload, accessPayload) => object

For server-side use when you don't want to use serialization. Accepts and returns native JavaScript objects.

When using executeRaw, you must ensure that the payload is properly formatted and does not contain unsupported types. We advice you to use execute when using the client SDK.
const payload = { filter: {}, options: { limit: 10 } };

const result = await layer.executeRaw(
    { database: "myapp", collection: "projects", operation: "find" },
    payload,
    { user: { id: "user-123" } }
);

// result is already a JavaScript object

Action structure

Every operation requires an action object with three properties:

{
    database: string,    // MongoDB database name
    collection: string,  // Collection name (must match a key in your collections config)
    operation: string    // One of the supported operations
}

Supported operations

OperationDescription
findOneFind a single document
findFind multiple documents
findOneAndUpdateFind and update a single document, returning the result
aggregateRun an aggregation pipeline
insertOneInsert a single document
insertManyInsert multiple documents
updateOneUpdate a single document
updateManyUpdate multiple documents
deleteOneDelete a single document
deleteManyDelete multiple documents

Action payload validation

Mongalayer already validates the structure of the action structure when calling execute or executeRaw. If necesarry the package also exports this validateAction function that you can use to validate the action structure separately:

import { validateAction } from "@mongalayer/server";

const action = { database: "myapp", collection: "projects", operation: "find" };

try {
    validateAction(action);
    // Action is valid, proceed with execution
} catch (error) {
    // Handle invalid action error
}

Access payload

The third argument to execute / executeRaw is the access payload — a free-form object that becomes available in your access filters via the %% prefix.

// On the server, after verifying the user's JWT or session
const accessPayload = {
    user: {
        id: decodedToken.id,
        roles: decodedToken.roles,
        organizationId: decodedToken.org
    }
};

await layer.execute(action, payload, accessPayload);

In your access definitions, you reference these values:

{
    role: "member",
    filter: {
        organizationId: "%%user.organizationId"
    }
}
See Access Control for the full access system documentation.
Copyright © 2026