### Local Development from Monorepo Subdirectory Source: https://github.com/zuplo/docs/blob/main/docs/articles/monorepo-deployment.mdx Navigate to the Zuplo project folder within your monorepo and run these commands to start the local development server. Ensure dependencies are installed first. ```bash cd packages/api-gateway npm install npx zuplo dev ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/zuplo/docs/blob/main/README.md Install all necessary project dependencies using pnpm. This command should be run after cloning the repository. ```bash pnpm install ``` -------------------------------- ### Create Zuplo API with an Official Example Source: https://github.com/zuplo/docs/blob/main/docs/cli/create-zuplo-api.mdx Initialize a new Zuplo API project using a specific example from the official Zuplo GitHub repository. ```bash npx create-zuplo-api@latest my-api --example my-example ``` -------------------------------- ### Install Zuplo Tools Skill Source: https://github.com/zuplo/docs/blob/main/docs/articles/ai-agents.mdx Install the Zuplo tools skill from GitHub to enable agents to access task-specific guidance on project setup, policies, handlers, and more. ```bash npx skills add zuplo/tools ``` -------------------------------- ### Policy Configuration Example Source: https://github.com/zuplo/docs/blob/main/docs/articles/custom-code-patterns.md Example JSON configuration for registering a custom inbound policy named 'require-tenant-header'. ```json { "name": "require-tenant-header", "policyType": "custom-code-inbound", "handler": { "export": "default", "module": "$import(./modules/require-tenant-header)", "options": { "headerName": "x-tenant-id" } } } ``` -------------------------------- ### CLI Examples in JSON Source: https://github.com/zuplo/docs/blob/main/scripts/generate-cli-docs.md Format for examples within the cli.json metadata, used by the component to render command examples. ```typescript examples: [ ["$0 deploy --project my-project", "Deploy to a specific project"], ["$0 deploy --env production", "Deploy to production environment"], ]; ``` -------------------------------- ### Consumer Tags Example Source: https://github.com/zuplo/docs/blob/main/docs/articles/api-key-management.mdx Example of a key-value pair for consumer tags. Tags are used for management purposes and do not get sent to the runtime as part of authorization. ```txt customer=1234 ``` -------------------------------- ### Start Local Development Server Source: https://github.com/zuplo/docs/blob/main/docs/articles/local-development-routes-designer.mdx Run this command to start the Zuplo Gateway and the Routes Designer locally. The Routes Designer is available on port 9100. ```bash npm run dev ``` -------------------------------- ### Example Partial MDX File Source: https://github.com/zuplo/docs/blob/main/scripts/generate-cli-docs.md Use .partial.mdx files to add custom content to generated CLI documentation. This content appears after the help block and before the examples section. ```mdx Your introductory text here. This appears after the help block and before examples. See [Custom CI/CD](../articles/custom-ci-cd.mdx) for examples. ## Common Use Cases Add detailed documentation, examples, tips, etc. ### Deploying your Gateway The deploy command pushes your changes to production. ``` -------------------------------- ### Install Zuplo Tools Skill via Discovery Source: https://github.com/zuplo/docs/blob/main/docs/articles/ai-agents.mdx Alternatively, install the Zuplo tools skill using `.well-known` discovery by providing the Zuplo domain. ```bash npx skills add https://zuplo.com/ ``` -------------------------------- ### Basic Caching Example Source: https://github.com/zuplo/docs/blob/main/docs/programmable-api/streaming-zone-cache.mdx An example demonstrating how to use StreamingZoneCache to cache and serve responses, improving performance by serving from cache on subsequent requests. ```APIDOC ## Example ```ts import { StreamingZoneCache, ZuploContext, ZuploRequest } from "@zuplo/runtime"; export default async function handler( request: ZuploRequest, context: ZuploContext, ) { const cache = new StreamingZoneCache("response-cache", context); const cacheKey = `response:${request.url}`; // Try to get cached response const cachedStream = await cache.get(cacheKey); if (cachedStream) { return new Response(cachedStream, { headers: { "X-Cache": "HIT" }, }); } // Fetch from origin const response = await fetch("https://api.example.com/large-file"); // Clone the response so we can cache it and return it const [streamForCache, streamForResponse] = response.body!.tee(); // Cache the response for 1 hour (3600 seconds) await cache.put(cacheKey, streamForCache, 3600); return new Response(streamForResponse, { headers: { ...response.headers, "X-Cache": "MISS", }, }); } ``` ``` -------------------------------- ### Install and Initialize Git LFS Source: https://github.com/zuplo/docs/blob/main/README.md Ensure Git LFS is installed and initialized before cloning the repository. This is necessary for managing large files. ```bash # Install Git LFS (if not already installed) # macOS: brew install git-lfs # Ubuntu/Debian: apt-get install git-lfs # Windows: Download from https://git-lfs.github.com/ # Initialize Git LFS git lfs install # Clone the repository git clone https://github.com/zuplo/docs cd docs # Verify LFS files were downloaded git lfs ls-files ``` -------------------------------- ### Start Local Zuplo Gateway Source: https://github.com/zuplo/docs/blob/main/docs/articles/step-1-setup-basic-gateway-local.mdx Navigate to your project directory and run this command to start the local Zuplo gateway and its associated development server. This also makes the Route Designer accessible. ```bash cd npm run dev ``` -------------------------------- ### Zudoku Configuration Example Source: https://github.com/zuplo/docs/blob/main/docs/dev-portal/migration.mdx Create a `zudoku.config.ts` file to configure the Zudoku dev portal. This example shows how to map old `dev-portal.json` fields like `pageTitle` and `faviconUrl` to the new `site.title` and `metadata.favicon` properties. ```typescript import type { ZudokuConfig } from "zudoku"; const config: ZudokuConfig = { site: { title: "My API", // Was pageTitle in the old format }, metadata: { favicon: "https://www.example.org/favicon.ico", // Was faviconUrl }, navigation: [ { type: "category", label: "Documentation", items: [ ``` -------------------------------- ### Example: BackgroundDispatcher Usage Source: https://github.com/zuplo/docs/blob/main/docs/programmable-api/background-dispatcher.mdx Demonstrates a complete example of using BackgroundDispatcher for logging. It includes defining the entry type, the dispatch function that sends data to an external logging service, initializing the dispatcher, and enqueuing entries within a request handler. ```typescript import { ZuploContext, ZuploRequest, BackgroundDispatcher, environment, } from "@zuplo/runtime"; // The type that identifies the entries // to be batched interface ExampleEntry { message: string; } // The dispatch function that will be invoked by the // BatchDispatcher at most every 'n' milliseconds const dispatchFunction = async (entries: ExampleEntry[]) => { // consider implementing a retry or backup call // if the data being transmitted is important await fetch(`https://example-logging-service.com/`, { method: "POST", headers: { "api-key": environment.MY_LOGGING_API_KEY, }, body: JSON.stringify(entries), }); }; // The dispatcher is typically initiated at the module level // so it can be shared by requests. Note that the msDelay is set // to 100ms. const backgroundDispatcher = new BackgroundDispatcher( dispatchFunction, { msDelay: 100 }, ); // This is an example Request Handler that used the component, a simple // "Hello World" handler. export default async function (request: ZuploRequest, context: ZuploContext) { backgroundDispatcher.enqueue( { message: `new request on '${request.url}' with id ${context.requestId}`, }, context, ); return "Hello World!"; } ``` -------------------------------- ### Example Authorization Callback URL Source: https://github.com/zuplo/docs/blob/main/docs/articles/manual-mcp-oauth-testing.mdx This is an example of the callback URL format you will receive after a successful authorization. You need to extract the 'code' parameter from this URL. ```text http://localhost:8080/authorization-code/callback?code=ABC123&state=XYZ987 ``` -------------------------------- ### Install dependencies for an existing project Source: https://github.com/zuplo/docs/blob/main/docs/articles/local-development.mdx If you are importing an existing Zuplo project from a Git repository, run this command to install the necessary project dependencies. ```sh npm install ``` -------------------------------- ### OpenAPI Path Transformation Example Source: https://github.com/zuplo/docs/blob/main/docs/guides/modify-openapi-paths.mdx Illustrates the transformation of OpenAPI paths before and after applying a prefix script. ```json { "paths": { "/users": { "get": {...} }, "/products": { "get": {...} } } } ``` ```json { "paths": { "/v1/users": { "get": {...} }, "/v1/products": { "get": {...} } } } ``` -------------------------------- ### Create Pro Plan with Trial Source: https://github.com/zuplo/docs/blob/main/docs/articles/monetization/plans.mdx This example demonstrates creating a Pro plan with a 1-week trial, a default phase with a monthly subscription, and overage pricing for API requests. It also includes static features for premium access. ```shell curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/plans \ --request POST \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "key": "pro", "name": "Pro Plan", "description": "For growing teams with a 1-week free trial", "currency": "USD", "billingCadence": "P1M", "phases": [ { "key": "trial", "name": "Trial", "duration": "P1W", "rateCards": [ { "type": "flat_fee", "key": "api_requests", "name": "API Requests (Trial)", "featureKey": "api_requests", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": false, "usagePeriod": "P1W" } }, { "type": "flat_fee", "key": "priority_support", "name": "Priority Support (Trial)", "featureKey": "priority_support", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "boolean", "config": true } } ] }, { "key": "default", "name": "Default", "duration": null, "rateCards": [ { "type": "usage_based", "key": "api_requests", "name": "API Requests", "featureKey": "api_requests", "billingCadence": "P1M", "entitlementTemplate": { "type": "metered", "issueAfterReset": 10000, "isSoftLimit": true, "usagePeriod": "P1M" }, "price": { "type": "tiered", "mode": "graduated", "tiers": [ { "upToAmount": "10000", "flatPrice": { "type": "flat", "amount": "99.00" }, "unitPrice": null }, { "flatPrice": null, "unitPrice": { "type": "unit", "amount": "0.01" } } ] } }, { "type": "flat_fee", "key": "priority_support", "name": "Priority Support", "featureKey": "priority_support", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "boolean", "config": true } } ] } ] } EOF ``` -------------------------------- ### Create a Starter Plan with Static Entitlements Source: https://github.com/zuplo/docs/blob/main/docs/articles/monetization/plan-examples.mdx This example demonstrates how to create a starter plan that includes both metered API requests and a static entitlement for large payloads. The static entitlement is configured as a boolean feature that is always enabled. ```shell curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/plans \ --request POST \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "key": "starter", "name": "Starter Plan", "description": "1,000 API requests per month with 2-week free trial and overages", "currency": "USD", "billingCadence": "P1M", "phases": [ { "key": "trial", "name": "Free Trial", "duration": "P2W", "rateCards": [ { "type": "flat_fee", "key": "api_requests", "name": "API Requests (Trial)", "featureKey": "api_requests", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": false, "usagePeriod": "P2W" } }, { "type": "flat_fee", "key": "large_payloads", "name": "Large Payloads (Trial)", "featureKey": "large_payloads", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "boolean", "config": true } } ] }, { "key": "default", "name": "Default", "duration": null, "rateCards": [ { "type": "usage_based", "key": "api_requests", "name": "API Requests", "featureKey": "api_requests", "billingCadence": "P1M", "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": true, "usagePeriod": "P1M" }, "price": { "type": "tiered", "mode": "graduated", "tiers": [ { "upToAmount": "1000", "flatPrice": { "type": "flat", "amount": "9.99" }, "unitPrice": null }, { "flatPrice": null, "unitPrice": { "type": "unit", "amount": "0.01" } } ] } }, { "type": "flat_fee", "key": "large_payloads", "name": "Large Payloads", "featureKey": "large_payloads", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "boolean", "config": true } } ] } ] } EOF ``` -------------------------------- ### Create Plan with Free Trial Source: https://github.com/zuplo/docs/blob/main/docs/articles/monetization/plan-examples.mdx This example extends a basic plan to include a free trial period with a specific duration and included requests. After the trial, customers are moved to the default paid phase. ```shell curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/plans \ --request POST \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "key": "starter", "name": "Starter Plan", "description": "1,000 API requests per month with 2-week free trial", "currency": "USD", "billingCadence": "P1M", "phases": [ { "key": "trial", "name": "Free Trial", "duration": "P2W", "rateCards": [ { "type": "flat_fee", "key": "api_requests", "name": "API Requests (Trial)", "featureKey": "api_requests", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": false, "usagePeriod": "P2W" } } ] }, { "key": "default", "name": "Default", "duration": null, "rateCards": [ { "type": "flat_fee", "key": "api_requests", "name": "API Requests", "featureKey": "api_requests", "billingCadence": "P1M", "price": { "type": "flat", "amount": "9.99" }, "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": false, "usagePeriod": "P1M" } } ] } ] } EOF ``` -------------------------------- ### Azure Pipeline for Local Testing and Deployment Source: https://github.com/zuplo/docs/blob/main/docs/articles/ci-cd-azure/local-testing.mdx This YAML defines an Azure Pipeline with two stages: 'LocalTest' and 'Deploy'. The 'LocalTest' stage installs Node.js, installs dependencies, starts a local Zuplo dev server, runs tests against it, and then stops the server. The 'Deploy' stage, which depends on the success of 'LocalTest', installs Node.js, installs dependencies, and deploys the API to Zuplo using an API key. ```yaml trigger: - main pool: vmImage: ubuntu-latest stages: - stage: LocalTest displayName: "Local Testing" jobs: - job: Test steps: - task: NodeTool@0 inputs: versionSpec: "20.x" displayName: "Install Node.js" - script: npm install displayName: "Install dependencies" - script: | npx zuplo dev & DEV_PID=$! sleep 10 npx zuplo test --endpoint http://localhost:9000 kill $DEV_PID displayName: "Start local server and run tests" - stage: Deploy displayName: "Deploy to Zuplo" dependsOn: LocalTest condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) jobs: - job: Deploy steps: - task: NodeTool@0 inputs: versionSpec: "20.x" - script: npm install - script: npx zuplo deploy --api-key $(ZUPLO_API_KEY) displayName: "Deploy to Zuplo" ``` -------------------------------- ### Flat Fee Rate Card Example Source: https://github.com/zuplo/docs/blob/main/docs/articles/monetization/rate-cards.mdx Defines a fixed one-time or recurring charge for a feature or service. Use for setup fees, subscriptions, or access charges. ```json { "type": "flat_fee", "key": "platform_fee", "name": "Platform Fee", "billingCadence": "P1M", "price": { "type": "flat", "amount": "99.00", "paymentTerm": "in_advance" } } ``` -------------------------------- ### Wire Up Logging Policies in Routes Source: https://github.com/zuplo/docs/blob/main/docs/articles/log-request-response-data.mdx Integrate the configured inbound and outbound logging policies into your API routes. This example shows how to apply them to a specific GET request. ```json { "paths": { "/my-route": { "get": { "x-zuplo-route": { "handler": { "export": "urlForwardHandler", "module": "$import(@zuplo/runtime)", "options": { "baseUrl": "https://api.example.com" } }, "policies": { "inbound": ["log-request-data"], "outbound": ["log-response-data"] } } } } } } ``` -------------------------------- ### Cloud Deployment Output Example Source: https://github.com/zuplo/docs/blob/main/docs/articles/step-1-setup-basic-gateway-local.mdx This output shows a successful deployment to the cloud, including the creation of a new project and the URL where your API is now accessible. ```bash ? You don't have any projects configured for this account. Enter the name of the new project: my-tutorial ✔ Project my-tutorial created successfully. ✔ Deployed to https://my-tutorial-main-11686c3.zuplo.app (93/150) ``` -------------------------------- ### Update Zuplo CLI Source: https://github.com/zuplo/docs/blob/main/docs/articles/local-development-troubleshooting.mdx Install the latest version of the Zuplo CLI. Ensure you include '@latest' to get the newest release and avoid cached older versions. ```bash npm install zuplo@latest ``` -------------------------------- ### Configure a 14-Day Free Trial Plan Source: https://github.com/zuplo/docs/blob/main/docs/articles/monetization/subscription-lifecycle.md Define a multi-phase plan with a free trial. This example configures a 14-day trial with 1,000 requests, automatically transitioning to a paid Pro phase with overage billing. ```json { "key": "pro-trial", "name": "Pro with Free Trial", "currency": "USD", "billingCadence": "P1M", "phases": [ { "key": "trial", "name": "14-Day Free Trial", "duration": "P2W", "rateCards": [ { "type": "flat_fee", "key": "api_calls", "name": "API Calls", "featureKey": "api_calls", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": false } } ] }, { "key": "default", "name": "Pro Monthly", "duration": null, "rateCards": [ { "type": "usage_based", "key": "api_calls", "name": "API Calls", "featureKey": "api_calls", "billingCadence": "P1M", "price": { "type": "tiered", "mode": "graduated", "tiers": [ { "upToAmount": "50000", "flatPrice": { "type": "flat", "amount": "99.00" }, "unitPrice": null }, { "flatPrice": null, "unitPrice": { "type": "unit", "amount": "0.50" } } ] }, "entitlementTemplate": { "type": "metered", "issueAfterReset": 50000, "isSoftLimit": true } } ] } ] } ``` -------------------------------- ### Apply OpenAPI Overlays Sequentially Source: https://github.com/zuplo/docs/blob/main/docs/guides/openapi-overlays.mdx Combine multiple overlays by applying them one after another. This example first adds parameters and then Zuplo extensions, using temporary files to store intermediate results. ```bash npx zuplo openapi overlay \ --input openapi.json \ --overlay add-params.json \ --output temp.json npx zuplo openapi overlay \ --input temp.json \ --overlay zuplo-routes.json \ --output final.json rm temp.json ``` ```bash #!/bin/bash npx zuplo openapi overlay -i openapi.json -l docs.json -o step1.json && \ npx zuplo openapi overlay -i step1.json -l params.json -o step2.json && \ npx zuplo openapi overlay -i step2.json -l zuplo.json -o final.json && \ rm step1.json step2.json ``` -------------------------------- ### GitHub Actions Workflow for Local Testing and Deployment Source: https://github.com/zuplo/docs/blob/main/docs/articles/ci-cd-github/local-testing.mdx This workflow automates local testing before deployment. It checks out code, sets up Node.js, installs dependencies, starts a local Zuplo dev server in the background, runs tests against it, and then stops the server. If local tests pass, it proceeds to deploy to Zuplo on pushes to the main branch. ```yaml name: Local Test Then Deploy on: push: branches: - main pull_request: jobs: local-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - name: Install dependencies run: npm install - name: Start local server and run tests run: | # Start the local dev server in the background npx zuplo dev & DEV_PID=$! # Wait for server to be ready echo "Waiting for local server to start..." sleep 10 # Run tests against local server npx zuplo test --endpoint http://localhost:9000 # Stop the dev server kill $DEV_PID deploy: needs: local-test runs-on: ubuntu-latest # Only deploy on push to main, not on PRs if: github.event_name == 'push' && github.ref == 'refs/heads/main' env: ZUPLO_API_KEY: ${{ secrets.ZUPLO_API_KEY }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - name: Install dependencies run: npm install - name: Deploy to Zuplo run: npx zuplo deploy --api-key "$ZUPLO_API_KEY" ``` -------------------------------- ### Example of Combined URL with Environment Variable Source: https://github.com/zuplo/docs/blob/main/docs/handlers/url-forward.mdx Illustrates how an environment variable like BASE_PATH can be combined with a path to form a complete backend URL. ```text https://example.com/foo/bar ``` -------------------------------- ### Bitbucket Pipeline for Local Testing Source: https://github.com/zuplo/docs/blob/main/docs/articles/ci-cd-bitbucket/local-testing.mdx This YAML configuration defines a Bitbucket pipeline with two steps: 'Local Testing' and 'Deploy to Zuplo'. The local testing step installs dependencies, starts a local Zuplo server, waits for it to become available, runs tests against the local endpoint, and then stops the server. Deployment only occurs if local tests pass. ```yaml image: node:20 pipelines: branches: main: - step: name: Local Testing script: - npm install - npx zuplo dev & - sleep 10 - npx zuplo test --endpoint http://localhost:9000 - kill %1 - step: name: Deploy to Zuplo script: - npm install - npx zuplo deploy --api-key "$ZUPLO_API_KEY" ``` -------------------------------- ### Example URL Substitution Values Source: https://github.com/zuplo/docs/blob/main/docs/handlers/url-rewrite.mdx Demonstrates various available substitutions for constructing rewrite URLs, including headers, host, method, parameters, query, and environment variables. ```txt ${headers.get("content-type")} ``` ```txt ${host} ``` ```txt ${hostname} ``` ```txt ${method} ``` ```txt ${origin} ``` ```txt ${params.productId} ``` ```txt ${pathname} ``` ```txt ${port} ``` ```txt ${protocol} ``` ```txt ${query.category} ``` ```txt ${search} ``` ```txt ${url} ``` ```txt ${env.BASE_URL} ``` -------------------------------- ### Install Zuplo CLI Source: https://github.com/zuplo/docs/blob/main/docs/cli/overview.mdx Install the Zuplo CLI globally using npm. Ensure Node.js 20.0.0 or later is installed. ```bash npm install -g zuplo ``` -------------------------------- ### Create Zuplo API with Default Template Source: https://github.com/zuplo/docs/blob/main/docs/cli/create-zuplo-api.mdx Bootstrap a new Zuplo API project using the default template and then start the development server. ```bash npx create-zuplo-api@latest my-api cd my-api npm run dev ``` -------------------------------- ### GitLab CI/CD Pipeline for Local Testing Source: https://github.com/zuplo/docs/blob/main/docs/articles/ci-cd-gitlab/local-testing.mdx This YAML configuration defines a GitLab CI/CD pipeline with two stages: 'test' and 'deploy'. The 'local-test' job installs dependencies, starts the Zuplo dev server in the background, waits for it to be ready, runs tests against the local endpoint, and then stops the server. The 'deploy' job only runs if the local tests pass and deploys the API using a provided API key. ```yaml image: node:20 stages: - test - deploy local-test: stage: test script: - npm install - npx zuplo dev & - sleep 10 - npx zuplo test --endpoint http://localhost:9000 - kill %1 deploy: stage: deploy needs: - local-test script: - npm install - npx zuplo deploy --api-key "$ZUPLO_API_KEY" only: - main ``` -------------------------------- ### Verify Zuplo CLI Installation Source: https://github.com/zuplo/docs/blob/main/docs/cli/overview.mdx Confirm the Zuplo CLI is installed correctly by checking its version. ```bash zuplo --version ``` -------------------------------- ### Install React API Key Manager Source: https://github.com/zuplo/docs/blob/main/docs/articles/api-key-react-component.mdx Install the component in your React project using npm. ```bash npm install @zuplo/react-api-key-manager ``` -------------------------------- ### Create a new Zuplo API project Source: https://github.com/zuplo/docs/blob/main/docs/articles/local-development.mdx Use this command to initialize a new Zuplo API project. Navigate into the project directory and run `npm run dev` to start the local gateway. ```bash npx create-zuplo-api@latest ``` ```bash cd npm run dev ``` -------------------------------- ### Kong Lua Plugin Example Source: https://github.com/zuplo/docs/blob/main/docs/articles/migrate-from-kong.md This is an example of a custom Kong plugin written in Lua that checks for the presence of a specific header. ```lua local MyPlugin = {} function MyPlugin:access(conf) local header_value = kong.request.get_header("x-custom-header") if not header_value then return kong.response.exit(403, { message = "Missing required header" }) end end return MyPlugin ``` -------------------------------- ### Install Custom Node Package Source: https://github.com/zuplo/docs/blob/main/docs/dev-portal/node-modules.mdx Use this command to install any npm package within your project's /docs directory. ```bash npm install your-package-name ``` -------------------------------- ### Start Local Server with Zuplo CLI Source: https://github.com/zuplo/docs/blob/main/docs/articles/custom-ci-cd.mdx Launch a local server for testing purposes within your CI environment using the `zuplo dev` command. ```bash zuplo dev ``` -------------------------------- ### Run Local Development Server Source: https://github.com/zuplo/docs/blob/main/AGENT.md Use this command to start the local development server for Zuplo agent. ```bash pnpm run dev ``` -------------------------------- ### Flat Fee One-Time Setup Source: https://github.com/zuplo/docs/blob/main/docs/articles/monetization/pricing-models.mdx Define a one-time setup fee charged at the beginning of a subscription. This model does not require a billing cadence. ```json { "type": "flat_fee", "key": "setup_fee", "name": "Setup Fee", "price": { "type": "flat", "amount": "500.00" } } ``` -------------------------------- ### API Key Authentication User Data Example Source: https://github.com/zuplo/docs/blob/main/docs/programmable-api/request-user.mdx Shows an example of `request.user.data` for API key authentication, often containing consumer-specific information. ```typescript // After API key validation request.user = { // The subject of the consumer sub: "consumer-id-123", data: { // The metadata you set when creating the consumer customerId: "123", plan: "premium", }, }; ``` -------------------------------- ### ZoneCache Example Usage Source: https://github.com/zuplo/docs/blob/main/docs/programmable-api/zone-cache.mdx An example demonstrating how to use the ZoneCache to store and retrieve user data, fetching from an API if the data is not found in the cache. ```APIDOC ## Example ```ts import { ZoneCache, ZuploContext, ZuploRequest } from "@zuplo/runtime"; interface UserData { id: string; name: string; email: string; } export default async function handler( request: ZuploRequest, context: ZuploContext, ) { const cache = new ZoneCache("user-cache", context); // Try to get user from cache const userId = request.params.userId; let userData = await cache.get(userId); if (!userData) { // Not in cache, fetch from API const response = await fetch(`https://api.example.com/users/${userId}`); userData = await response.json(); // Cache for 5 minutes await cache.put(userId, userData, 300); } return new Response(JSON.stringify(userData)); } ``` ``` -------------------------------- ### Add Overage Charges to a Plan Source: https://github.com/zuplo/docs/blob/main/docs/articles/monetization/plan-examples.mdx This example shows how to configure a plan with a base fee for a certain number of requests and an additional charge for overages. It uses tiered pricing to combine the base fee and overage cost. ```shell curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/plans \ --request POST \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "key": "starter", "name": "Starter Plan", "description": "1,000 API requests per month with 2-week free trial and overages", "currency": "USD", "billingCadence": "P1M", "phases": [ { "key": "trial", "name": "Free Trial", "duration": "P2W", "rateCards": [ { "type": "flat_fee", "key": "api_requests", "name": "API Requests (Trial)", "featureKey": "api_requests", "billingCadence": null, "price": null, "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": false, "usagePeriod": "P2W" } } ] }, { "key": "default", "name": "Default", "duration": null, "rateCards": [ { "type": "usage_based", "key": "api_requests", "name": "API Requests", "featureKey": "api_requests", "billingCadence": "P1M", "entitlementTemplate": { "type": "metered", "issueAfterReset": 1000, "isSoftLimit": true, "usagePeriod": "P1M" }, "price": { "type": "tiered", "mode": "graduated", "tiers": [ { "upToAmount": "1000", "flatPrice": { "type": "flat", "amount": "9.99" }, "unitPrice": null }, { "flatPrice": null, "unitPrice": { "type": "unit", "amount": "0.01" } } ] } } ] } ] } EOF ``` -------------------------------- ### General Error Examples Source: https://github.com/zuplo/docs/blob/main/docs/programmable-api/http-problems.mdx Provides examples of using HttpProblems for common general errors like Bad Request and Internal Server Error. ```APIDOC ## General HttpProblems Usage ### Description Examples of using the HttpProblems helper for common HTTP status codes. ### Method POST ### Endpoint N/A (These are helper functions, not direct endpoints) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```ts // General errors HttpProblems.badRequest(request, context); HttpProblems.internalServerError(request, context); // Authorization errors HttpProblems.unauthorized(request, context); HttpProblems.forbidden(request, context); // Success codes (though typically used for errors, can be used to signal success) HttpProblems.ok(request, context); HttpProblems.created(request, context); ``` ### Response #### Success Response (200) N/A (These functions are primarily for returning errors) #### Error Responses (Examples) - **400 Bad Request**: Returns a standard 400 error. - **500 Internal Server Error**: Returns a standard 500 error. - **401 Unauthorized**: Returns a standard 401 error. - **403 Forbidden**: Returns a standard 403 error. - **200 OK**: Returns a standard 200 OK response. - **201 Created**: Returns a standard 201 Created response. ``` -------------------------------- ### Good JSON Schema for Tool Arguments Source: https://github.com/zuplo/docs/blob/main/docs/mcp-server/tools.mdx This example demonstrates a well-structured JSON schema with descriptive names, specific types, and constraints like format, minimum, and maximum values. This helps LLMs understand and correctly use tool arguments. ```json { "type": "object", "required": ["userId"], "properties": { "userId": { "type": "string", "format": "uuid", "description": "Valid UUID for user ID" }, "amount": { "type": "number", "minimum": 0, "maximum": 10000, "description": "Amount in cents" } } } ``` -------------------------------- ### Process Order Workflow Source: https://github.com/zuplo/docs/blob/main/docs/mcp-server/custom-tools.mdx This example demonstrates a complex, multi-step workflow for processing customer orders. It uses `context.invokeRoute` to sequentially validate customer information, check inventory for ordered items, and finally create the order. ```APIDOC ## POST /process-order ### Description Process a customer order through multiple validation steps. ### Method POST ### Endpoint /process-order ### Parameters #### Request Body - **customerId** (string) - Required - Unique customer identifier - **items** (array) - Required - List of items to order - **productId** (string) - Required - Product identifier - **quantity** (number) - Required - Number of items to order ### Request Example ```json { "customerId": "cust-123", "items": [ { "productId": "prod-abc", "quantity": 2 }, { "productId": "prod-xyz", "quantity": 1 } ] } ``` ### Response #### Success Response (200) - **orderId** (string) - Generated order ID - **status** (string) - Order status (enum: created, pending, confirmed) - **total** (number) - Total amount - **estimatedDelivery** (string) - Estimated delivery date #### Response Example ```json { "orderId": "ord-789", "status": "created", "total": 150.75, "estimatedDelivery": "2023-10-27T10:00:00Z" } ``` ``` -------------------------------- ### Fetch API Example Source: https://github.com/zuplo/docs/blob/main/docs/programmable-api/web-standard-apis.mdx Use the Fetch API to make HTTP requests to external resources. This example demonstrates fetching JSON data. ```typescript const response = await fetch("https://echo.zuplo.io"); const body = await response.json(); ``` -------------------------------- ### Rate Limiting Response Example Source: https://github.com/zuplo/docs/blob/main/docs/articles/step-2-add-rate-limiting-local.mdx This is an example of the JSON response you will receive when the rate limit is exceeded, indicating a 429 Too Many Requests status. ```json { "type": "https://httpproblems.com/http-status/429", "title": "Too Many Requests", "status": 429, "instance": "/path-1", "trace": { "timestamp": "2025-08-26T21:50:40.220Z", "requestId": "4c62d425-2cb0-4a6c-9ac0-8d04a5f10c57", "buildId": "f49c4070-7c0a-441b-a5fd-4e35b5fe41b7" } } ``` -------------------------------- ### Read a Resource with Custom URI using MCP Source: https://github.com/zuplo/docs/blob/main/docs/mcp-server/resources.mdx This example demonstrates reading a resource using a custom URI scheme, such as `ui://css`. This allows for more specific resource identification. ```bash curl https://my-gateway.zuplo.dev/mcp \ -X POST \ -H 'accept: application/json, text/event-stream' \ -d '{ "jsonrpc": "2.0", "id": "0", "method": "resources/read", "params": { "uri": "ui://css" } }' ``` -------------------------------- ### Navigate to Docs Directory Source: https://github.com/zuplo/docs/blob/main/docs/dev-portal/local-development.mdx Change your current directory to the 'docs' folder to work on documentation files. ```bash cd docs ``` -------------------------------- ### Consumer Metadata Example Source: https://github.com/zuplo/docs/blob/main/docs/articles/api-key-management.mdx Example of JSON object that can be assigned as metadata to a consumer. This information is available to the runtime when a user accesses your API using that key. ```json { "companyId": 123, "plan": "gold" } ``` -------------------------------- ### Simple Flow Diagram Example Source: https://github.com/zuplo/docs/blob/main/DIAGRAMS.md A straightforward example demonstrating a sequence of steps using basic nodes and edges. This is useful for illustrating linear processes. ```tsx Step 1 Step 2 Step 3 ```