Skip to content

Languages

A function exports a handler that answers every HTTP request to its URL, and optionally a scheduled function for its schedules. Each language uses the hivekit SDK, which DockHive provides at build time.

Your handler receives the request as JSON:

{
"method": "POST",
"path": "/items",
"query": { "page": "2" },
"headers": { "content-type": "application/json", "user-agent": "curl/8.7.1" },
"body": "{\"name\":\"pen\"}",
"ip": "203.0.113.7",
"region": "eu",
"function": { "name": "orders-k3x9", "version": 3 },
"env": { "STORE_NAME": "Main street" }
}
  • Header names are lower-case.
  • body is a string. When the body isn’t UTF-8 text, it’s base64 and the request has "body_encoding": "base64".
  • env holds the function’s environment variables.

Return one of:

You return The caller gets
A string 200 with text/plain, or application/json if the string is valid JSON
Any other JSON value 200 with application/json
{"status", "headers", "body"} That status, those headers and that body. A body that’s an object or array is sent as JSON; add "body_encoding": "base64" to send binary data.

If your code throws or returns an error, the caller gets 500 with {"error": "function_error", "message": "..."} and your message (up to 1 KB). See Limits for the other error responses.

Each starter below is the one the console and dockhive functions init give you, shortened. In every language, storage persists across requests and new versions.

One file, handler.js. Handlers receive the request as an object and return any value.

const { hive, db } = require('hivekit')
hive.define('handler', (request) => {
const visits = (db.get('visits') || 0) + 1
db.set('visits', visits)
console.log('handled', request.method, request.path, 'visit', visits)
return {
status: 200,
headers: { 'content-type': 'application/json' },
body: { message: 'Hello from Hive Functions', visits, query: request.query },
}
})
hive.define('scheduled', (event) => {
const runs = (db.get('runs') || 0) + 1
db.set('runs', runs)
return { runs }
})

The hivekit package is built in; packages from your own node_modules aren’t used.

One file, handler.ts. TypeScript is compiled ahead of time with a strictly typed subset (AssemblyScript): handlers take the request as a JSON string and return a string (plain text, JSON, or a full {"status","headers","body"} response). Use explicit number types such as i64.

import { hive, storage } from 'hivekit'
function handler(input: string): string {
const prev = storage.get("visits");
const visits: i64 = (prev.length == 0 ? 0 : I64.parseInt(prev)) + 1;
storage.set("visits", visits.toString());
hive.log("handled a request, visit " + visits.toString());
return "{\"status\":200,\"headers\":{\"content-type\":\"application/json\"}," +
"\"body\":{\"visits\":" + visits.toString() + ",\"request\":" + input + "}}";
}
function scheduled(input: string): string {
return "{\"ok\":true}";
}
hive.define("handler", handler);
hive.define("scheduled", scheduled);

If you’d rather work with objects, JavaScript gives you plain objects in and out.

One file, handler.py. Handlers receive the request as a dict and return any value.

from hivekit import hive
@hive.define("handler")
def handler(request):
visits = hive.db.get("visits", 0) + 1
hive.db.set("visits", visits)
hive.log("handled", request["method"], request["path"], "visit", visits)
return {
"status": 200,
"headers": {"content-type": "application/json"},
"body": {"message": "Hello from Hive Functions", "visits": visits, "query": request["query"]},
}
@hive.define("scheduled")
def scheduled(event):
runs = hive.db.get("runs", 0) + 1
hive.db.set("runs", runs)
return {"runs": runs}

A Go module (main.go, go.mod, go.sum), built with TinyGo. Deploy it with the CLI. Register handlers in init; main is required but never called. Module dependencies in go.mod are fetched during the build.

package main
import hivekit "github.com/Necter-Network/hivekit/hivekit-go"
type request struct {
Method string `json:"method"`
Path string `json:"path"`
Query map[string]any `json:"query"`
}
func init() {
hivekit.DefineJSON("handler", func(req request) (map[string]any, error) {
var visits int64
if _, err := hivekit.StorageGetJSON("visits", &visits); err != nil {
return nil, err
}
visits++
if err := hivekit.StorageSetJSON("visits", visits); err != nil {
return nil, err
}
hivekit.Logf("handled %s %s, visit %d", req.Method, req.Path, visits)
return map[string]any{
"status": 200,
"headers": map[string]string{"content-type": "application/json"},
"body": map[string]any{"message": "Hello from Hive Functions", "visits": visits},
}, nil
})
hivekit.DefineJSON("scheduled", func(event map[string]any) (map[string]int64, error) {
return map[string]int64{"ok": 1}, nil
})
}
func main() {}

A crate with src/lib.rs and Cargo.toml. Deploy it with the CLI. Crates in Cargo.toml are fetched during the build.

use hivekit::prelude::*;
#[hive_export("handler")]
fn handler(request: Value) -> Result<Value, String> {
let visits = storage::get_json::<i64>("visits").unwrap_or(0) + 1;
storage::set_json("visits", &visits);
log(&format!("handled {} {}, visit {}", request["method"], request["path"], visits));
Ok(json!({
"status": 200,
"headers": { "content-type": "application/json" },
"body": { "message": "Hello from Hive Functions", "visits": visits }
}))
}
#[hive_export("scheduled")]
fn scheduled(_event: Value) -> Result<Value, String> {
Ok(json!({ "ok": true }))
}
hive_module!(handler, scheduled);

The starter Cargo.toml depends on hivekit and serde:

[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
hivekit = { git = "https://github.com/Necter-Network/hivekit", tag = "v1.0.0" }
serde = { version = "1", features = ["derive"] }

If you deploy a project without go.mod or Cargo.toml, the starter one is added for you.

  • A build has up to 5 minutes and produces one Hive Bytecode (.hbc) file of up to 20 MB.
  • The project you upload can be up to 20 MB, not counting dependencies and build output.
  • TypeScript, JavaScript and Python build one entry file. Name it handler.ts, handler.js or handler.py when the folder has more than one.
  • The build log is kept with each version and shown when a build fails.

Already have a .hbc file? Upload it as a new version through the API instead of building from source:

Terminal window
curl -X POST "https://api.dockhive.io/api/v1/functions/functions/<function id>/versions?region=eu" \
-H "Authorization: Bearer $DOCKHIVE_API_KEY" \

The file should export handler (or the function’s configured entry) for HTTP requests.

handler is the default. To answer HTTP requests with another exported function, set the function’s entry with PATCH /api/v1/functions/functions/<function id>?region=<region> and {"entry": "my_handler"}.