Use this reference when the task is clearly about an HTTP Function: REST API, browser-facing endpoint, SSE stream, or WebSocket service.
HTTP Functions are standard web services, not exports.main(event, context) handlers.
- Handle requests through
reqandres. - Listen on port
9000. - Ship an executable
scf_bootstrapfile. - Include runtime dependencies in the package; HTTP Functions do not auto-install
node_modulesfor you.
my-http-function/
├── scf_bootstrap
├── package.json
├── node_modules/
└── index.js
#!/bin/bash
node index.jsRequirements:
- File name must be exactly
scf_bootstrap. - Use LF line endings.
- Make it executable with
chmod +x scf_bootstrap.
const express = require("express");
const app = express();
app.use(express.json());
app.get("/health", (req, res) => {
res.json({ ok: true });
});
app.listen(9000);req.query-> query string values.req.body-> parsed request body, but only after body-parsing middleware is configured.req.headers-> incoming HTTP headers.req.params-> path parameters.- Always send a response with
res.json(),res.send(), orres.status(...).json(). - Return meaningful status codes such as
400,401,404,405,500.
const express = require("express");
const app = express();
app.use(express.json());
app.post("/users", (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: "name and email are required" });
}
return res.status(201).json({ name, email });
});
app.all("/{*splat}", (req, res) => {
res.status(405).json({ error: "Method Not Allowed" });
});
app.listen(9000);Express 5 note: do not use bare * or /* here. Express 5 uses path-to-regexp with named wildcards, so app.all("/{*splat}", ...) is the safe catch-all form when you also need to match the root path /.
Prefer manageFunctions over CLI in agent flows.
manageFunctions({
action: "createFunction",
func: {
name: "myHttpFunction",
type: "HTTP",
protocolType: "HTTP",
timeout: 60
},
functionRootPath: "/absolute/path/to/cloudfunctions"
});For WebSocket workloads, keep the function type as HTTP and switch protocolType:
manageFunctions({
action: "createFunction",
func: {
name: "mySocketFunction",
type: "HTTP",
protocolType: "WS"
},
functionRootPath: "/absolute/path/to/cloudfunctions"
});curl -L "https://{envId}.api.tcloudbasegateway.com/v1/functions/{name}?webfn=true" \
-H "Authorization: Bearer <TOKEN>"This is suitable for authenticated server-to-server access.
Creating the function does not automatically create a browser-facing path. Add gateway access separately when the user actually needs it.
manageGateway({
action: "createAccess",
targetType: "function",
targetName: "myHttpFunction",
type: "HTTP",
path: "/api/hello"
});Keep the public gateway path and the in-function router path as two different layers.
manageGateway(..., path: "/api/hello")creates the external access prefix.- Your HTTP Function still matches its own internal routes such as
/,/health,/users. - Do not rewrite the function router to include the gateway prefix.
Example mapping:
| External URL | Route your HTTP Function should handle |
|---|---|
https://{domain}/api/hello |
/ |
https://{domain}/api/hello/health |
/health |
https://{domain}/api/hello/users |
/users |
For example, if you expose path: "/api/httpDemo", the function code should normally keep handlers like app.get("/") and app.get("/health"). Do not change them to app.get("/api/httpDemo") or app.get("/api/httpDemo/health").
If the external caller reports a 404, verify these two layers separately:
- Use
queryGateway(action="getAccess")to confirm which public path is actually exposed. - Check the HTTP Function router to confirm it handles the internal path after the gateway prefix.
Before enabling anonymous access, confirm both of these:
- The access path exists.
- The function security rule allows the intended caller identity.
If an external caller reports EXCEED_AUTHORITY, inspect the function permission first with queryPermissions(action="getResourcePermission", resourceType="function") before widening access.
res.setHeader("Content-Type", "text/event-stream");
res.write(`data: ${JSON.stringify({ content: "Hello" })}\n\n`);const WebSocket = require("ws");
const wss = new WebSocket.Server({ port: 9000 });
wss.on("connection", (ws) => {
ws.on("message", (message) => ws.send(`Echo: ${message}`));
});- If the task is actually a timer-triggered or SDK-invoked serverless function, reroute to Event Functions.
- If the task needs long-lived containers, custom system packages, or broader service architecture, reroute to
cloudrun-development. - If the task is only about HTTP API calling patterns rather than implementation, reroute to
http-api.