Skip to main content

Introduction

Middleware in XanoScript allows you to define reusable logic that can be applied to multiple types of objects in your application. Unlike other primitives, middleware functions are designed to be shared and applied across different contexts. Middleware can be applied to four types of objects:
  • APIs — Pre/post processing for API endpoints
  • Functions — Pre/post processing for custom functions
  • Tasks — Pre/post processing for background tasks
  • AI Tools — Pre/post processing for AI tool executions
Each middleware function follows the same structure as other XanoScript primitives, but includes additional configuration for how it should behave when applied to different objects.

Anatomy

Every XanoScript middleware follows a predictable structure. Here’s a quick visual overview of its main building blocks — from declaration at the top to settings at the bottom.

You can find more detail about each section by continuing below.

Declaration

Every middleware starts with a declarative header that specifies its type, name, and description.
XanoScript
middleware <middleware_name> {
description = "<what this middleware does>"
...
}
ElementRequiredDescription
middlewareDeclares a middleware primitive.
middleware_nameThe unique name for the middleware function.
descriptionnoOptional human-readable description of the middleware’s purpose.

Application Types

Middleware can be applied to four different types of objects, each providing different contexts and data:

APIs

Middleware applied to APIs can perform pre-processing (before the API executes) or post-processing (after the API completes).

Functions

Middleware applied to custom functions can validate inputs, transform outputs, or perform additional logic around function execution.

Tasks

Middleware applied to background tasks can handle task initialization, cleanup, or error handling.

AI Tools

Middleware applied to AI tools can modify tool inputs, validate permissions, or process tool outputs.

Section 1: Input

The input block defines the data that will be available to the middleware. Middleware receives standardized input regardless of which object type it’s applied to.
XanoScript
input {
  json vars
  enum type {
    values = ["pre", "post"]
  }
}
Middleware Input Schema:
  • vars — Contains all variables and data from the calling context
  • type — Indicates whether this is pre-processing ("pre") or post-processing ("post")
The vars object contains different data depending on the object type the middleware is applied to:
  • APIs: Contains $input, $auth, and other API-specific variables
  • Functions: Contains function parameters and context variables
  • Tasks: Contains task-specific variables and configuration
  • AI Tools: Contains tool inputs and context variables

Section 2: Stack

The stack block contains the actual logic that will be executed when the middleware runs.
XanoScript
stack {
  db.get user {
    field_name = "id"
    field_value = $auth.id
  } as $user1

  precondition ($user1.banned == false) {
    error_type = "unauthorized"
    error = "Your account has been suspended."
  }
}
The stack works exactly like other XanoScript primitives:
  • Functions are called with their parameters
  • Variables can be created and manipulated
  • Conditional logic can be applied
  • Database operations can be performed
  • Preconditions can be used to halt execution
Middleware stacks typically focus on:
  • Validation — Checking permissions, data integrity, or business rules
  • Transformation — Modifying data before or after processing
  • Logging — Recording activity or debugging information
  • Security — Enforcing access controls or rate limiting

Section 3: Response

The response block defines what data your middleware returns to the calling context.
XanoScript
response {
  value = {user1: $user1}
}
Middleware Response Behavior:
  • The response data is merged with the calling context’s variables
  • Variables returned in the response become available to the calling object
  • The response_strategy setting controls how the response is merged
Common Response Patterns:
  • Validation middleware — Often returns user or permission data
  • Transformation middleware — Returns modified input data
  • Logging middleware — May return logging results or status
  • Security middleware — Returns authentication or authorization data

Settings

Middleware primitives support several optional settings that control how the middleware behaves and integrates with calling objects.
SettingTypeRequiredDescription
response_strategystringnoControls how the response is merged with the calling context. Options: "merge", "replace". Default: "merge".
exception_policystringnoControls how exceptions are handled. Options: "critical", "silent", "rethrow". Default: "silent".
tagsarray[string]noA list of tags used to categorize and organize the middleware in your workspace.
Response Strategy Options:
  • "merge" — Merges response data with existing context variables (default)
  • "replace" — Replaces the entire response with the middleware response
Exception Policy Options:
  • "critical" — Stops execution and returns error
  • "silent" — Silently ignores exceptions (default)
  • "rethrow" — Rethrows exceptions

Detailed Example

Below, you’ll see a complete example of a typical middleware function that checks for banned users.
XanoScript
middleware check_banned_user {
  description = "Checks to see if a banned user is attempting to perform any action, and if so, blocks it"
  input {
    json vars
    enum type {
      values = ["pre", "post"]
    }
  }

  stack {
    db.get user {
      field_name = "id"
      field_value = $auth.id
    } as $user1

    precondition ($user1.banned == false) {
      error_type = "unauthorized"
      error = "Your account has been suspended."
    }
  }

  response {
    value = {user1: $user1}
  }

  response_strategy = "merge"
  exception_policy = "critical"
  tags = ["user actions"]
}
This middleware can be applied to any API, function, task, or AI tool to ensure that banned users cannot perform actions. The middleware:
  1. Validates — Checks if the authenticated user is banned
  2. Blocks — Uses a precondition to halt execution if the user is banned
  3. Returns — Provides the user data to the calling context for further use

What’s Next

Now that you understand how to define middleware in XanoScript, here are a few great next steps:

Explore the function reference

Learn about the built-in functions available in the stack to start writing more complex middleware logic.
https://mintlify.s3.us-west-1.amazonaws.com/xano-997cb9ee/images/vscode.svg

Try it out in VS Code

Use the XanoScript VS Code extension with Copilot to write XanoScript in your favorite IDE.

Learn about APIs

Create APIs that can use your middleware functions to build secure and robust endpoints.
I