# Functions

A function is a unit of deployed backend logic (JavaScript/TypeScript, Python, or Ruby) that Volcano builds, packages, and runs on a managed runtime.

## What it is

A function is a unit of deployed backend logic (JavaScript/TypeScript, Python,
or Ruby) that Volcano builds, packages, and runs on a managed **runtime**. It
is invoked over HTTP, by name/alias, or on a schedule.

## How it relates

- Belongs to a **project**.
- Reads configuration and secrets from **variables**. By default it receives
  every project variable; declare a narrower
  [variable scope](https://docs.volcano.dev/cli/project-configuration.md) to give it only the ones it needs.
- Connects to **databases** and **storage** in the same project.
- Its **visibility** (`private`, `authenticated`, or `public`) and
  **schedulers** can be declared in the
  [declarative config](https://docs.volcano.dev/cli/project-configuration.md) or managed with the CLI.
- A **frontend route** can serve a public function under a path of a
  [frontend](https://docs.volcano.dev/cli/frontends.md).
- Can be given an **alias** so you can invoke it by a friendly name.
- Work that has to run for hours belongs in a
  [durable function](https://docs.volcano.dev/cli/durable-functions.md) instead, which is a separate
  collection with its own commands.

The CLI discovers functions in the `volcano/functions` directory, detects the
runtime from source file extensions, and uploads a packaged archive.

If a `volcano-config.yaml` is present, `functions deploy` also sends the
`variable_scope` and `variables` declared there for each function it uploads.
Functions the manifest does not mention keep their existing scope. The manifest
is only read — deploying never writes it back. See
[variable scope](https://docs.volcano.dev/cli/project-configuration.md).

Because those declarations come from the manifest, a manifest that is present
but cannot be read stops the deploy before anything is uploaded, and the error
says what to fix. That includes a `${VAR}` reference anywhere in the file whose
environment variable is not set in the deploying shell, even in a section
unrelated to functions. Deploying past it would upload a function without the
scope it declared, giving it every project variable. With no
`volcano-config.yaml` at all there is nothing to declare and deploy runs
normally.

## CLI operations

| Operation | Command |
|---|---|
| Deploy one or all | `volcano functions deploy [-a \| -f <name\|path>]` |
| List | `volcano functions list` |
| Get | `volcano functions get <name>` |
| Set visibility | `volcano functions update <name> --visibility private\|authenticated\|public` |
| Delete | `volcano functions delete <name>` |
| Invoke | `volcano functions invoke <name> [--payload …] [--json]` |
| Logs | `volcano functions logs <name>` |
| Search logs across functions | `volcano logs` (see [logs.md](https://docs.volcano.dev/cli/logs.md)) |
| Supported runtimes | `volcano functions runtimes` |
| Deployable regions | `volcano functions regions [--json]` |
| Aliases | `volcano functions alias set\|list\|delete …` |
| Schedulers | `volcano functions schedulers create\|list\|enable\|disable\|delete …` |

Prefix with `cloud` (e.g. `volcano cloud functions deploy`) to target cloud.
Without the prefix, function commands always target local development.

Cloud deploys use latest-wins queueing. If the function is already deploying,
the new source replaces any older queued deploy and runs next. Delete supersedes
queued deploys; later deploys are rejected until deletion finishes.

## Visibility

Visibility decides who can invoke a function:

| Visibility | Who can invoke it |
|---|---|
| `private` | Service keys and schedulers |
| `authenticated` | Also your project's signed-in users, including [anonymous sign-ins](https://docs.volcano.dev/platform/authentication/anonymous-users.md) |
| `public` | Also anon keys with `functions.invoke`, and [frontend routes](https://docs.volcano.dev/cli/frontends.md#function-routes) |

A refused caller gets:

| Function | Caller | Answer |
|---|---|---|
| `private` | Anyone but a service key or scheduler | `404`, the same as for a function that does not exist |
| `authenticated` | Anon key, invoking by ID | `403` |
| `authenticated` | Anon key, invoking by name, as the SDK does | `404` |

If your app gets 404 for a function you deployed, check its visibility with
`volcano cloud functions get <name>`.

New functions start `private`. `functions deploy` says so for each function it
creates and prints the command that lets signed-in users in:

```text
  Deployed notes-summary (new, visibility private)

New functions are private: only service keys and schedulers can invoke them.
To let your project's signed-in users call one, run:
  volcano functions update notes-summary --visibility authenticated
Or declare its visibility in volcano-config.yaml and run volcano config deploy
```

A deploy does not apply the `visibility` in
[`volcano-config.yaml`](https://docs.volcano.dev/cli/project-configuration.md#function-visibility). When the
manifest already declares a level for a new function, the hint points at
`volcano config deploy` instead.

`--public` is the same as `--visibility public`. `--private` is no longer
accepted: it used to let signed-in users in, which is `authenticated` now, so
pick the level you mean. A function that a frontend route forwards to has to
stay `public`; `functions update` lists the routes to delete first.

`functions update` sets the level of standard functions. For a
[durable function](https://docs.volcano.dev/cli/durable-functions.md#visibility), declare `visibility` in
`volcano-config.yaml` and run `volcano cloud config deploy`.

`functions get` shows the level, and under "Routed from" every frontend path
that forwards to the function:

```text
Visibility: public
Routed from: web /api/session
```

## Examples

[`volcano deploy`](https://docs.volcano.dev/cli/deploy.md) deploys the functions together with the
project's variables, durable functions, frontends, and configuration. Use
`functions deploy` to deploy only functions.

```bash
# Deploy everything, or a single function by name or path
volcano functions deploy --all
volcano functions deploy -f get-notes
volcano functions deploy -f volcano/functions/get-notes.js

# Invoke with a JSON payload; --json prints compact machine output
volcano functions invoke hello --payload '{"name":"Ada"}'
volcano functions invoke hello --json
volcano functions invoke --id 33333333-3333-4333-8333-333333333333

# Let signed-in users invoke a function
volcano functions update notes-summary --visibility authenticated

# Tail build/runtime logs
volcano functions logs hello

# Schedule a function (cron), then disable it
volcano functions schedulers create hello --name refresh-cache --cron "*/5 * * * *"
volcano functions schedulers disable hello --name refresh-cache

# Invoke-by-alias
volcano functions alias set hello 44444444-4444-4444-8444-444444444444
volcano functions invoke hello
```

`schedulers list` shows each scheduler's health, how many runs in a row have
failed, and the last error of a failing one. A run fails when Volcano cannot
invoke the function; an error the function itself returns does not count. To be
alerted when a scheduler keeps failing, see [notifications.md](https://docs.volcano.dev/cli/notifications.md).
