Atomic Six languages
Write functions in Go, Python, Node.js, Ruby, PHP, or Rust. The CLI detects the language from your source and handles the build, compiling Go and Rust, installing dependencies and bundling the rest. The same “save an item” handler in Python and Node:
import drift
# @atomic http=post:items auth=none
def post_items(body, req):
item_id = drift.backbone.nosql.collection("items").insert(body)
return 201, "Created", {"id": item_id}const drift = require("@ondrift/sdk");
// @atomic http=post:items auth=none
async function postItems(body, req) {
const id = await drift.backbone.nosql.collection("items").insert(body);
return [201, "Created", { id }];
}
module.exports = { postItems };
The generated entry point requires your Node module and calls the handler off it, so the
module.exports line above is not optional. Python, Ruby and PHP wrappers import the file and
call the function directly, so a plain top-level definition is enough. Everything your function needs
(data, queues, secrets) is one drift.* call away.
See the SDK reference →
Declaring the SDK
The CLI does not pin or override an SDK version. Two languages provision it for you; four expect your function's own manifest to declare it:
| Language | Where the SDK comes from |
|---|---|
| Go | The build runs go get github.com/ondrift/cloud/sdk@latest in a staged copy of your package, then go mod tidy. Nothing to declare. |
| Rust | A Cargo.toml is generated only when the function ships none. A function with its own Cargo.toml chooses the version. |
| Python | requirements.txt must name drift-sdk. |
| Node | package.json must name @ondrift/sdk. |
| Ruby | Gemfile must name drift-sdk. |
| PHP | composer.json must name ondrift/sdk. |
For those four, a source file that imports the SDK with no manifest, or a manifest that exists but
doesn't name it, is refused before the build, with the exact line to add.
drift atomic new writes the manifest for you, and drift atomic fetch resolves
dependencies for every function under a path.
How a function runs
Python and Node functions are served by a persistent language server inside the slice: one warm interpreter handling calls with no per-request process. It is spawned on the first invocation and reaped after five minutes with no traffic, so a slice with recent traffic never pays a cold start and a dormant one returns its interpreter memory to the host. While a server is starting, calls fall back to the subprocess path rather than queueing.
Go, Rust, Ruby and PHP run one subprocess per invocation: the compiled binary or the interpreter, sandboxed, fed the request on stdin. A function may not spawn subprocesses of its own.