Elements
An element is a single-language backend, Drift's unit of a “service” (what you'd put in one container elsewhere), minus the container. One language, one dependency manifest (go.mod / requirements.txt / package.json / …), and as many functions as you like across flat files in one folder.
The common case is the simplest there is: drop your handlers straight into atomic/ as flat files, with no per-function folders. That flat set is an element (the implicit default one), and a function belongs to it by declaring no element: at all:
-
atomic/one element, one language, one backend
- auth.gopost:signup · post:login · get:me
- groups.gocreate · list · join · get
- lib.goshared helpers, just a sibling file
- go.modone manifest for the whole backend
Need a second language? That's a second element, a second service. Give each its own folder under atomic/ (say atomic/api/ in Go and atomic/ml/ in Python), each with its own manifest, and name it on those functions' entries:
atomic:
functions:
- route: predict
method: post
handler: post_predict
element: ml # lives in ./atomic/mlMixing languages within one element is refused before anything builds; a second language is, by definition, a second element. Elements integrate through Backbone (queues, NoSQL, locks), exactly the way microservices integrate through a broker, never by importing each other.
An element is an authoring + dependency boundary, not a URL one: a route comes from its entry's name, so the element never appears in the path. It is also the scope a handler is looked up in, which is why two elements can each have a handle. Shared code (lib.go, crypto.go) is an ordinary file in the same package and never a copy. Go, Python, Node, Ruby and PHP build as multi-function elements; a Rust element holds one function.