Enterprise Search API Gateway
All templates

Enterprise Search API Gateway

Replace direct provider connections with a single governed search endpoint. Routes each request to Elasticsearch, OpenSearch, or Algolia — enforcing per-tenant permissions, applying centralized query rewrites, normalizing all responses into one shape, and logging every call.

Start building in Xano: Access the prompt at https://go.xano.co/start-xano-with-template-skill and run it here with enterprise-search-gateway-elasticsearch-opensearch-algolia as your template.
ClaudeOpenAI CodexCursorVS Code

Copy and paste the prompt in your local coding agent of choice.

Template Details

4 Tables 2 APIs 7 Functions

Integrations

Elasticsearch OpenSearch Algolia
Template Preview
Client appClient appWeb · mobile · agentsearch APIsearch APIsearchBusiness logicBusiness logicEsg apply query rewriteEsg check permissionEsg search algoliaEsg search elasticsearchEsg search opensearchEsg searchEsg validate requestDataDataapi_request_logssearch_logssearch_rulestenant_search_permissionsExternal servicesExternal services Elasticsearch OpenSearch Algolia

Overview

Replace direct provider connections with a single governed search endpoint. One POST /search routes each request to Elasticsearch, OpenSearch, or Algolia — enforcing per-tenant permissions, applying centralized query rewrites, normalizing every response into one shape, and logging every call.

Apps stop talking to three different search APIs and start talking to one governed contract. Xano owns the routing, the permissions, the query policy, and the audit; the providers stay the search engines. Push it and the whole validate → authorize → rewrite → route → normalize → log flow runs, with the provider calls doc-mocked so it works before you wire credentials.

What it provides

Give every app a direct connection to Elasticsearch (and OpenSearch, and Algolia) and you've given up governance: each client re-implements search, there's no central tenant isolation, query policy is copy-pasted everywhere, response shapes differ per provider, and nobody can answer "who searched what." Swapping or adding a provider means touching every app.

This template puts one governed gateway in front of all of them. A single POST /search validates the request, checks the caller's tenant against a permissions table, applies any active query-rewrite rule, routes to the chosen provider's adapter, and returns one normalized envelope — writing a search log and a request log every time (including on validation failures, permission denials, and provider errors). Provider access, tenant isolation, and query policy live in one place, so changing them is one change, not N.

Repo layout

backend/
  api/
    search/
      api_group.xs
      search_post.xs
  function/
    esg_apply_query_rewrite.xs
    esg_check_permission.xs
    esg_search_algolia.xs
    esg_search_elasticsearch.xs
    esg_search_opensearch.xs
    esg_search.xs
    esg_validate_request.xs
  table/
    api_request_logs.xs
    search_logs.xs
    search_rules.xs
    tenant_search_permissions.xs
  workflow_test/
    esg_authorized_search.xs
    esg_validation_failure.xs
  workspace/
    templates.xs

How it works

POST /search runs a strict, governed sequence (esg_search):

  1. Validate the request (esg_validate_request) — provider is one of elasticsearch / opensearch / algolia, plus the query/filter shape.
  2. Authorize the tenant against tenant_search_permissions — a tenant may only query the indexes (and, optionally, the filter key/value) it's been granted.
  3. Rewrite the query if an active rule in search_rules matches (centralized query policy).
  4. Route to the selected provider's adapter (esg_search_elasticsearch / _opensearch / _algolia) — one branch per provider, the HTTP call wrapped so a provider error is caught, not fatal.
  5. Normalize the provider response into one unified envelope.
  6. Log a search_logs row and an api_request_logs row — validation failures, permission denials, and provider errors all still write the request log.

Validation and permission checks are explicit, non-throwing, so the unified error envelope carries the exact reason.

Quick start

Start with your coding agent. Paste the prompt below into a local MCP-capable coding agent — Claude Code, Cursor, Windsurf, and others. It installs the Xano CLI, connects Xano, and imports this template.

Start building in Xano: Access the prompt at https://go.xano.co/start-xano-with-template-skill and run it here with enterprise-search-gateway-elasticsearch-opensearch-algolia as your template.

The agent will walk you through the setup below.

  1. Push the backend to a Xano workspace (the CLI/agent flow below does this).
  2. Call itPOST /search with a provider, query, optional filters, and the tenant_id / user_id the request is attributed to.
  3. What runs without credentials. Validation, tenant authorization, query rewrite, normalization, and logging all run out of the box (with API_AUTH_SECRET unset the auth check is a no-op); the live provider search needs that provider's credentials. Set the environment variables to connect Elasticsearch, OpenSearch, and/or Algolia.

API surface

The one endpoint lives in the EnterpriseSearchGateway API group (canonical esg-search) and requires the API secret when API_AUTH_SECRET is set. Every call is logged.

Method Path Purpose
POST /search Governed search: validate → authorize tenant → rewrite → route to Elasticsearch/OpenSearch/Algolia → normalize → log.

Database Tables

  • tenant_search_permissions — per-tenant grants: which index a tenant_id may query, optionally scoped to an allowed_filter_key / value.
  • search_rules — centralized query-rewrite rules: match a query, send a rewritten one instead (active rules only).
  • search_logs — one row per search reaching a provider: provider, post-rewrite query, filters, result count, response time, tenant, user.
  • api_request_logs — one row per request (success or error), correlated to search_logs by request_id.

Testing

Run from a deployed workspace with xano workflow_test run_all:

  • esg_authorized_search — an authorized tenant's request validates, passes the permission check, routes, and is logged (against a doc-mocked provider).
  • esg_validation_failure — an invalid request is rejected by the validation gate with the exact reason, and still writes a request log.

These exercise the governance flow without provider credentials; the live provider call requires them.

Environment variables

Set the credentials for whichever provider(s) you route to. The gateway's governance (validation, permissions, rewrite, logging) runs without them.

  • ELASTICSEARCH_URL, ELASTICSEARCH_API_KEY — Elasticsearch endpoint + API key.
  • OPENSEARCH_URL, OPENSEARCH_USERNAME, OPENSEARCH_PASSWORD — OpenSearch endpoint + basic-auth credentials.
  • ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY, ALGOLIA_INDEX_NAME — Algolia application, search key, and index.
  • API_AUTH_SECRET — shared secret every request checks. When unset the check is a no-op so it runs out of the box; set it in production.

Frequently asked questions

Can I add a fourth search provider beyond the three included?
Yes. Each provider is a routing branch behind the single /search endpoint. Add a branch that maps the normalized request to your new provider's API and its response back into the shared envelope, and the gateway routes to it like the others.
Every request carries a tenant identity, and the gateway checks that tenant's permissions against tenant_search_permissions before routing — so a tenant can only query the indexes (and optional filter scope) it's been granted, enforced centrally instead of in each app.
Before a request reaches a provider, the gateway can apply centralized rewrites from search_rules — swapping a matched query for a rewritten one — so query policy lives in one place rather than being reimplemented in every client.
Every template runs on any Xano plan, including the free tier. All you need is a Xano account and a coding agent connected to the CLI and Developer MCP.
You can import and run it with your local coding agent — it works against the seed data it ships with. Paste this prompt into your agent: Start building in Xano: Access the prompt at https://go.xano.co/start-xano-with-template-skill and run it here with enterprise-search-gateway-elasticsearch-opensearch-algolia as your template. You can also do a manual clone from Github, still using the Xano CLI and Developer MCP to connect to Xano to build and deploy.
Yes — that's the intent. The backend is plain XanoScript that you can read and AI can build on: add or edit tables, endpoints, and logic, or swap integrations. It ships with tests you can extend as you go.
Xano gives you an enterprise-grade backend — database, APIs, and logic — that AI can build and you can visually inspect, edit, and trust. Hosted, scalable, and production-ready from day one. Speed of generation, without the black box.

Get started for free today

Xano gives you everything you need to ship modern applications—fast, securely, and at scale.

Get started