ZuploZuplo
LoginSign Up
  • Documentation
  • API Reference
Introduction
Getting Started
    Develop using the Portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingMCP - Quick start
    Develop Locally
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth
Concepts
Development
    CORSEnvironment VariablesBranch-Based DeploymentsTestingTroubleshootingGitOps vs TerraformCustom Code
    Local Development
    Guides
      Advanced Path MatchingAPI VersioningOpenAPI Server URLsConvert URLs to OpenAPIOpenAPI Extension DataPath Modification ScriptsOpenAPI OverlaysCanary Routing for EmployeesGeolocation Backend RoutingUser-Based Backend RoutingBypass a PolicyTesting GraphQL QueriesHealth ChecksPerformance TestingTroubleshooting Slow ResponsesNon-Standard PortsHandling FormDataS3 Signed URL UploadsCheck IP AddressLazy Load ConfigurationSharing Code Across ProjectsBackstage IntegrationGitHub Action Automation
Policies
Handlers
API Keys
MCP Server
MCP Gateway
AI Gateway
Developer Portal
Monetization
Deploying & Source Control
Observability
Networking & Infrastructure
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
Platform LimitsSecuritySupportTrust & ComplianceChangelog
powered by Zudoku
Guides

Handling FormData

Zuplo supports working with FormData including multipart/form-data. In this simple example we show how you can parse a multipart entry and read the stream into memory for use in the Zuplo runtime.

In this case, we upload a JSON file as a multipart/form-data entry using Insomnia, with a key foo

Insomnia multipart/form-data

We can then handle this programmatically inside Zuplo using a function handler. We also modify the JSON before forwarding on to the target backend server.

Code
import { ZuploContext, ZuploRequest } from "@zuplo/runtime"; // FormData can return different types in different circumstances // use this function to convert both to strings async function readFileOrStringContent(data: unknown) { if (data.constructor.name === "File") { return await (data as File).text(); } return data as string; } export default async function (request: ZuploRequest, context: ZuploContext) { const formData = await request.formData(); // read the form-data entry as a 'Blob' type const blob = formData.get("foo"); // stream the body into memory const json = await readFileOrStringContent(blob); // parse the JSON document const object = JSON.parse(json); // Modify the document somehow before forwarding on to the backend object.newKey = "newValue"; // Make a standard POST to a backend with a JSON body const response = fetch("https://backend-origin.com/example", { method: "POST", headers: { "content-type": "application/json", }, body: JSON.stringify(object, null, 2), }); return response; }
Edit this page
Last modified on November 17, 2025
Non-Standard PortsS3 Signed URL Uploads
TypeScript