diff --git a/content/cloud/develop.md b/content/cloud/develop.md index 2cac86504..8491ddc9c 100644 --- a/content/cloud/develop.md +++ b/content/cloud/develop.md @@ -277,7 +277,7 @@ component = "hello-rust" [component.hello-rust] source = "target/wasm32-wasi/release/hello_rust.wasm" -allowed_http_hosts = [] +allow_outbound_hosts = [] [component.hello-rust.build] command = "cargo build --target wasm32-wasi --release" watch = ["src/**/*.rs", "Cargo.toml"] @@ -407,7 +407,7 @@ component = "hello-go" [component.hello-go] source = "main.wasm" -allowed_http_hosts = [] +allow_outbound_hosts = [] [component.hello-go.build] command = "tinygo build -target=wasi -gc=leaking -no-debug -o main.wasm main.go" watch = ["**/*.go", "go.mod"] diff --git a/content/cloud/faq.md b/content/cloud/faq.md index f3788daf1..a09177974 100644 --- a/content/cloud/faq.md +++ b/content/cloud/faq.md @@ -51,6 +51,8 @@ The following are the quota for users based, stratified by the three [Subscripti | **Regions** | | Region count| 1 | 1 | Contact us +> Note: The above quota numbers are per month and are spread across all apps for a single Cloud account. + ## Known Limitations ### Fermyon Cloud Limitations diff --git a/content/cloud/variables.md b/content/cloud/variables.md index a4bb8cee8..408167cb9 100644 --- a/content/cloud/variables.md +++ b/content/cloud/variables.md @@ -118,7 +118,7 @@ secret = { required = true } [component.pw-checker] source = "target/wasm32-wasi/release/pw_checker.wasm" -allowed_http_hosts = [] +allow_outbound_hosts = [] [component.pw-checker.build] command = "cargo build --target wasm32-wasi --release" diff --git a/content/spin/v2/ai-sentiment-analysis-api-tutorial.md b/content/spin/v2/ai-sentiment-analysis-api-tutorial.md index 6fa17608c..095262cc1 100644 --- a/content/spin/v2/ai-sentiment-analysis-api-tutorial.md +++ b/content/spin/v2/ai-sentiment-analysis-api-tutorial.md @@ -1010,7 +1010,7 @@ component = "sentiment-analysis-rust" [component.sentiment-analysis-rust] source = "target/wasm32-wasi/release/sentiment_analysis_rust.wasm" -allowed_http_hosts = [] +allow_outbound_hosts = [] ai_models = ["llama2-chat"] key_value_stores = ["default"] [component.sentiment-analysis-rust.build] diff --git a/content/spin/v2/cli-reference.md b/content/spin/v2/cli-reference.md index 141daa39d..206d97a50 100644 --- a/content/spin/v2/cli-reference.md +++ b/content/spin/v2/cli-reference.md @@ -90,6 +90,43 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin add --help +spin-add +Scaffold a new component into an existing application + +USAGE: + spin add [OPTIONS] [NAME] + +ARGS: + The name of the new application or component + +OPTIONS: + -a, --accept-defaults An optional argument that allows to skip prompts for the + manifest file by accepting the defaults if available on the + template + -f, --file Path to spin.toml + -h, --help Print help information + --init Create the new application or component in the current + directory + -o, --output The directory in which to create the new application or + component. The default is the name argument + -t, --template The template from which to create the new application or + component. Run `spin templates list` to see available options + --tag Filter templates to select by tags + -v, --value Parameter values to be passed to the template (in name=value + format) + --values-file A TOML file which contains parameter values in name = "value" + format. Parameters passed as CLI option overwrite parameters + specified in the file +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -130,6 +167,39 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin build --help +spin-build +Build the Spin application + +USAGE: + spin build [OPTIONS] [--] [UP_ARGS]... + +ARGS: + ... + +OPTIONS: + -c, --component-id ... + Component ID to build. This can be specified multiple times. The default is all + components + + -f, --from + The application to build. This may be a manifest (spin.toml) file, or a directory + containing a spin.toml file. If omitted, it defaults to "spin.toml" [default: spin.toml] + + -h, --help + Print help information + + -u, --up + Run the application after building +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -143,6 +213,12 @@ The `spin cloud` command is implemented by the [Fermyon Cloud Plugin](../cloud/c {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference). + +{{ blockEnd }} + {{ blockEnd }} @@ -156,6 +232,12 @@ The `spin cloud apps` command is implemented by the [Fermyon Cloud Plugin](../cl {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud apps` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference#spin-cloud-apps). + +{{ blockEnd }} + {{ blockEnd }} @@ -169,6 +251,12 @@ The `spin cloud deploy` command is implemented by the [Fermyon Cloud Plugin](../ {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud deploy` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference#spin-cloud-deploy). + +{{ blockEnd }} + {{ blockEnd }} @@ -182,6 +270,12 @@ The `spin cloud link` command is implemented by the [Fermyon Cloud Plugin](../cl {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud link` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference#spin-cloud-link). + +{{ blockEnd }} + {{ blockEnd }} @@ -195,6 +289,12 @@ The `spin cloud login` command is implemented by the [Fermyon Cloud Plugin](../c {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud login` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference#spin-cloud-login). + +{{ blockEnd }} + {{ blockEnd }} @@ -208,6 +308,12 @@ The `spin cloud sqlite` command is implemented by the [Fermyon Cloud Plugin](../ {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud sqlite` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference#spin-cloud-sqlite). + +{{ blockEnd }} + {{ blockEnd }} @@ -221,6 +327,12 @@ The `spin cloud unlink` command is implemented by the [Fermyon Cloud Plugin](../ {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud unlink` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference#spin-cloud-unlink). + +{{ blockEnd }} + {{ blockEnd }} @@ -234,6 +346,12 @@ The `spin cloud variables` command is implemented by the [Fermyon Cloud Plugin]( {{ blockEnd }} +{{ startTab "v2.1"}} + +The `spin cloud variables` command is implemented by the [Fermyon Cloud Plugin](../cloud/cloud-command-reference#spin-cloud-variables). + +{{ blockEnd }} + {{ blockEnd }} @@ -268,6 +386,28 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin doctor --help + +spin-doctor +Detect and fix problems with Spin applications + +USAGE: + spin doctor [OPTIONS] + +OPTIONS: + -f, --from The application to check. This may be a manifest (spin.toml) + file, or a directory containing a spin.toml file. If omitted, + it defaults to "spin.toml" [default: spin.toml] + -h, --help Print help information +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -281,6 +421,12 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + +> Please note: Spin `help` is a convenient way to access help using a subcommand, instead of using the `--help` option. For example, `spin help cloud` will give you the same output as `spin cloud --help`. Similarly, `spin help build` will give you the same output as `spin build --help` and so forth. + +{{ blockEnd }} + {{ blockEnd }} @@ -330,6 +476,43 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin new --help + +spin-new +Scaffold a new application based on a template + +USAGE: + spin new [OPTIONS] [NAME] + +ARGS: + The name of the new application or component + +OPTIONS: + -a, --accept-defaults An optional argument that allows to skip prompts for the + manifest file by accepting the defaults if available on the + template + -h, --help Print help information + --init Create the new application or component in the current + directory + -o, --output The directory in which to create the new application or + component. The default is the name argument + -t, --template The template from which to create the new application or + component. Run `spin templates list` to see available options + --tag Filter templates to select by tags + -v, --value Parameter values to be passed to the template (in name=value + format) + --values-file A TOML file which contains parameter values in name = "value" + format. Parameters passed as CLI option overwrite parameters + specified in the file +``` + +{{ blockEnd }} + {{ blockEnd }} **Please note: `spin new` vs `spin add`**. These commands are similar except that: @@ -370,6 +553,34 @@ SUBCOMMANDS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin plugins --help + +spin-plugins +Install/uninstall Spin plugins + +USAGE: + spin plugins + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + help Print this message or the help of the given subcommand(s) + install Install plugin from a manifest + list List available or installed plugins + search Search for plugins by name + uninstall Remove a plugin from your installation + update Fetch the latest Spin plugins from the spin-plugins repository + upgrade Upgrade one or all plugins +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -418,6 +629,47 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin plugins install --help + +spin-plugins-install +Install plugin from a manifest. + +The binary file and manifest of the plugin is copied to the local Spin plugins directory. + +USAGE: + spin plugins install [OPTIONS] [PLUGIN_NAME] + +ARGS: + + Name of Spin plugin + +OPTIONS: + -f, --file + Path to local plugin manifest + + -h, --help + Print help information + + --override-compatibility-check + Overrides a failed compatibility check of the plugin with the current version of Spin + + -u, --url + URL of remote plugin manifest to install + + -v, --version + Specific version of a plugin to be install from the centralized plugins repository + + -y, --yes + Skips prompt to accept the installation of the plugin +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -446,27 +698,69 @@ OPTIONS: {{ blockEnd }} -{{ blockEnd }} - - -## spin plugins search - -{{ tabs "spin-version" }} - -{{ startTab "v2.0"}} +{{ startTab "v2.1"}} ```console -$ spin plugins search --help -spin-plugins-search -Search for plugins by name +$ spin plugins list --help + +spin-plugins-list +List available or installed plugins USAGE: - spin plugins search [FILTER] + spin plugins list [OPTIONS] -ARGS: - The text to search for. If omitted, all plugins are returned +OPTIONS: + --filter Filter the list to plugins containing this string + -h, --help Print help information + --installed List only installed plugins +``` + +{{ blockEnd }} + +{{ blockEnd }} + + +## spin plugins search + +{{ tabs "spin-version" }} + +{{ startTab "v2.0"}} + + + +```console +$ spin plugins search --help +spin-plugins-search +Search for plugins by name + +USAGE: + spin plugins search [FILTER] + +ARGS: + The text to search for. If omitted, all plugins are returned + +OPTIONS: + -h, --help Print help information +``` + +{{ blockEnd }} + +{{ startTab "v2.1"}} + + + +```console +$ spin plugins search --help +spin-plugins-search +Search for plugins by name + +USAGE: + spin plugins search [FILTER] + +ARGS: + The text to search for. If omitted, all plugins are returned OPTIONS: -h, --help Print help information @@ -503,6 +797,28 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin plugins uninstall --help + +spin-plugins-uninstall +Remove a plugin from your installation + +USAGE: + spin plugins uninstall + +ARGS: + Name of Spin plugin + +OPTIONS: + -h, --help Print help information +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -529,6 +845,25 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin plugins update --help + +spin-plugins-update +Fetch the latest Spin plugins from the spin-plugins repository + +USAGE: + spin plugins update + +OPTIONS: + -h, --help Print help information +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -580,6 +915,50 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin plugins upgrade --help + +spin-plugins-upgrade +Upgrade one or all plugins + +USAGE: + spin plugins upgrade [OPTIONS] [PLUGIN_NAME] + +ARGS: + Name of Spin plugin to upgrade + +OPTIONS: + -a, --all + Upgrade all plugins + + -d, --downgrade + Allow downgrading a plugin's version + + -f, --file + Path to local plugin manifest + + -h, --help + Print help information + + --override-compatibility-check + Overrides a failed compatibility check of the plugin with the current version of Spin + + -u, --url + Path to remote plugin manifest + + -v, --version + Specific version of a plugin to be install from the centralized plugins repository + + -y, --yes + Skips prompt to accept the installation of the plugin[s] +``` + +{{ blockEnd }} + {{ blockEnd }} **Note:** For additional information, please see the [Managing Plugins](/spin/managing-plugins) and/or [Creating Plugins](/spin/plugin-authoring) sections of the documentation. @@ -613,6 +992,30 @@ SUBCOMMANDS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin registry --help +spin-registry +Commands for working with OCI registries to distribute applications + +USAGE: + spin registry + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + help Print this message or the help of the given subcommand(s) + login Log in to a registry + pull Pull a Spin application from a registry + push Push a Spin application to a registry +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -645,6 +1048,31 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin registry login --help + +spin-registry-login +Log in to a registry + +USAGE: + spin registry login [OPTIONS] + +ARGS: + OCI registry server (e.g. ghcr.io) + +OPTIONS: + -h, --help Print help information + -p, --password Password for the registry + --password-stdin Take the password from stdin + -u, --username Username for the registry +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -675,6 +1103,32 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin registry pull --help + +spin-registry-pull +Pull a Spin application from a registry + +USAGE: + spin registry pull [OPTIONS] + +ARGS: + Reference in the registry of the published Spin application. This is a string + whose format is defined by the registry standard, and generally consists of + //:. E.g. + ghcr.io/ogghead/spin-test-app:0.1.0 + +OPTIONS: + -h, --help Print help information + -k, --insecure Ignore server certificate errors +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -710,6 +1164,37 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin registry push --help + +spin-registry-push +Push a Spin application to a registry + +USAGE: + spin registry push [OPTIONS] + +ARGS: + Reference in the registry of the Spin application. This is a string whose + format is defined by the registry standard, and generally consists of + //:. E.g. + ghcr.io/ogghead/spin-test-app:0.1.0 + +OPTIONS: + --build Specifies to perform `spin build` before pushing the + application [env: SPIN_ALWAYS_BUILD=] + -f, --from The application to push. This may be a manifest (spin.toml) + file, or a directory containing a spin.toml file. If omitted, + it defaults to "spin.toml" [default: spin.toml] + -h, --help Print help information + -k, --insecure Ignore server certificate errors +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -743,6 +1228,32 @@ SUBCOMMANDS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin templates --help + +spin-templates +Commands for working with WebAssembly component templates + +USAGE: + spin templates + +OPTIONS: + -h, --help Print help information + +SUBCOMMANDS: + help Print this message or the help of the given subcommand(s) + install Install templates from a Git repository or local directory + list List the installed templates + uninstall Remove a template from your installation + upgrade Upgrade templates to match your current version of Spin +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -786,6 +1297,42 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin templates install --help + +spin-templates-install +Install templates from a Git repository or local directory. + +The files of the templates are copied to the local template store: a directory in your data or home +directory. + +USAGE: + spin templates install [OPTIONS] + +OPTIONS: + --branch + The optional branch of the git repository + + --dir + Local directory containing the template(s) to install + + --git + The URL of the templates git repository. The templates must be in a git repository in a + "templates" directory + + -h, --help + Print help information + + --upgrade + If present, updates existing templates instead of skipping +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -814,6 +1361,27 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin templates list --help + +spin-templates-list +List the installed templates + +USAGE: + spin templates list [OPTIONS] + +OPTIONS: + -h, --help Print help information + --tag Filter templates matching all provided tags + --verbose Whether to show additional template details in the list +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -845,6 +1413,28 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin templates uninstall --help + +spin-templates-uninstall +Remove a template from your installation + +USAGE: + spin templates uninstall + +ARGS: + The template to uninstall + +OPTIONS: + -h, --help Print help information +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -886,6 +1476,40 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin templates upgrade --help +spin-templates-upgrade +Upgrade templates to match your current version of Spin. + +The files of the templates are copied to the local template store: a directory in your data or home +directory. + +USAGE: + spin templates upgrade [OPTIONS] + +OPTIONS: + --all + By default, Spin displays the list of installed repositories and prompts you to choose + which to upgrade. Pass this flag to upgrade all repositories without prompting + + --branch + The optional branch of the git repository, if a specific repository is given + + -h, --help + Print help information + + --repo + By default, Spin displays the list of installed repositories and prompts you to choose + which to upgrade. Pass this flag to upgrade only the specified repository without + prompting +``` + +{{ blockEnd }} + {{ blockEnd }} **Note:** For additional information, please see the [Managing Templates](/spin/managing-templates) and/or [Creating Templates](/spin/template-authoring) sections of the documentation. @@ -975,6 +1599,82 @@ TRIGGER OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin up --help + +spin-up +Start the Spin application + +USAGE: + spin up [OPTIONS] + +OPTIONS: + --build For local apps, specifies to perform `spin build` before running the + application [env: SPIN_ALWAYS_BUILD=] + --direct-mounts For local apps with directory mounts and no excluded files, mount + them directly instead of using a temporary directory + -e, --env Pass an environment variable (key=value) to all components of the + application + -f, --from The application to run. This may be a manifest (spin.toml) file, a + directory containing a spin.toml file, or a remote registry + reference. If omitted, it defaults to "spin.toml" + -h, --help + -k, --insecure Ignore server certificate errors from a registry + --temp Temporary directory for the static assets of the components + +TRIGGER OPTIONS: + --allow-transient-write + Set the static assets of the components in the temporary directory as writable + + --cache + Wasmtime cache configuration file + + [env: WASMTIME_CACHE_FILE=] + + --disable-cache + Disable Wasmtime cache + + [env: DISABLE_WASMTIME_CACHE=] + + --disable-pooling + Enable Wasmtime's pooling instance allocator + + --follow + Print output to stdout/stderr only for given component(s) + + --key-value + Set a key/value pair (key=value) in the application's default store. Any existing value + will be overwritten. Can be used multiple times + + -L, --log-dir + Log directory for the stdout and stderr of components + + -q, --quiet + Silence all component output to stdout/stderr + + --runtime-config-file + Configuration file for config providers and wasmtime config + + [env: RUNTIME_CONFIG_FILE=] + + --sqlite + Run a SQLite statement such as a migration against the default database. To run from a + file, prefix the filename with @ e.g. spin up --sqlite @migration.sql + + --state-dir + Set the application state directory path. This is used in the default locations for + logs, key value stores, etc. + + For local apps, this defaults to `.spin/` relative to the `spin.toml` file. For remote + apps, this has no default (unset). Passing an empty value forces the value to be unset. +``` + +{{ blockEnd }} + {{ blockEnd }} > **Please note:** If the `-f` or `--from` options do not accurately infer the intended registry or `.toml` file for your application, then you can explicitly specify either the `--from-registry` or `--from-file` options to clarify this. @@ -1011,6 +1711,31 @@ The following additional trigger options are available for the [spin up](#spin-u {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +--listen
+ IP address and port to listen on + + [default: 127.0.0.1:3000] + +--tls-cert + The path to the certificate to use for https, if this is not set, normal http will be + used. The cert should be in PEM format + + [env: SPIN_TLS_CERT=] + +--tls-key + The path to the certificate key to use for https, if this is not set, normal http will + be used. The key should be in PKCS#8 format + + [env: SPIN_TLS_KEY=] +``` + +{{ blockEnd }} + {{ blockEnd }} @@ -1047,6 +1772,35 @@ OPTIONS: {{ blockEnd }} +{{ startTab "v2.1"}} + + + +```console +$ spin watch --help +spin-watch +Build and run the Spin application, rebuilding and restarting it when files change + +USAGE: + spin watch [OPTIONS] [UP_ARGS]... + +ARGS: + ... Arguments to be passed through to spin up + +OPTIONS: + -c, --clear Clear the screen before each run + -d, --debounce Set the timeout between detected change and re-execution, in + milliseconds [default: 100] + -f, --from The application to watch. This may be a manifest (spin.toml) + file, or a directory containing a spin.toml file. If omitted, + it defaults to "spin.toml" [default: spin.toml] + -h, --help Print help information + --skip-build Only run the Spin application, restarting it when build + artifacts change +``` + +{{ blockEnd }} + {{ blockEnd }} ## Stability Table @@ -1078,4 +1832,22 @@ CLI commands have four phases that indicate levels of stability: {{ blockEnd }} +{{ startTab "v2.1"}} + +| Command | Stability | +| ------------------------------------------------------------------------------------- | ------------ | +| spin add | Stable | +| spin build | Stable | +| spin new | Stable | +| spin plugins | Stable | +| spin templates | Stable | +| spin up | Stable | +| spin cloud | Stabilizing | +| spin registry | Stabilizing | +| spin doctor | Experimental | +| spin watch | Experimental | +| spin bindle | Deprecated | + +{{ blockEnd }} + {{ blockEnd }} diff --git a/content/spin/v2/javascript-components.md b/content/spin/v2/javascript-components.md index ad4d691ce..c9fa292a7 100644 --- a/content/spin/v2/javascript-components.md +++ b/content/spin/v2/javascript-components.md @@ -298,6 +298,7 @@ Let's see how we can use the JS/TS SDK to connect to Redis: import { HandleRequest, HttpRequest, HttpResponse, Redis } from "@fermyon/spin-sdk" const decoder = new TextDecoder() +const encoder = new TextEncoder() const redisAddress = "redis://localhost:6379/" diff --git a/content/spin/v2/kv-store-api-guide.md b/content/spin/v2/kv-store-api-guide.md index 1b9549579..9dbec2f24 100644 --- a/content/spin/v2/kv-store-api-guide.md +++ b/content/spin/v2/kv-store-api-guide.md @@ -47,17 +47,21 @@ Key value functions are available in the `spin_sdk::key_value` module. The funct ```rust use anyhow::Result; use spin_sdk::{ - http::{IntoResponse, Request}, + http::{IntoResponse, Request, Response}, http_component, key_value::{Store}, }; #[http_component] fn handle_request(_req: Request) -> Result { let store = Store::open_default()?; - store.set("mykey", "myvalue")?; + store.set("mykey", b"myvalue")?; let value = store.get("mykey")?; let response = value.unwrap_or_else(|| "not found".into()); - Ok(http::Response::builder().status(200).body(response)?) + Ok(Response::builder() + .status(200) + .header("content-type", "text/plain") + .body(response) + .build()) } ``` @@ -86,6 +90,8 @@ With Typescript, the key value functions can be accessed after opening a store u ```javascript import { HandleRequest, HttpRequest, HttpResponse, Kv } from "@fermyon/spin-sdk" +const encoder = new TextEncoder() + export const handleRequest: HandleRequest = async function (request: HttpRequest): Promise { let store = Kv.openDefault() store.set("mykey", "myvalue") diff --git a/content/spin/v2/quickstart.md b/content/spin/v2/quickstart.md index 76830dc0e..98f8b06c3 100644 --- a/content/spin/v2/quickstart.md +++ b/content/spin/v2/quickstart.md @@ -325,17 +325,18 @@ annotated with the `http_component` macro which identifies it as the entry point for HTTP requests: ```rust -use spin_sdk::http::{IntoResponse, Request}; +use spin_sdk::http::{IntoResponse, Request, Response}; use spin_sdk::http_component; /// A simple Spin HTTP component. #[http_component] fn handle_hello_rust(req: Request) -> anyhow::Result { println!("Handling request to {:?}", req.header("spin-full-url")); - Ok(http::Response::builder() + Ok(Response::builder() .status(200) .header("content-type", "text/plain") - .body("Hello, Fermyon")?) + .body("Hello, Fermyon") + .build()) } ``` diff --git a/content/spin/v2/redis-trigger.md b/content/spin/v2/redis-trigger.md index 48d5da066..1953642ae 100644 --- a/content/spin/v2/redis-trigger.md +++ b/content/spin/v2/redis-trigger.md @@ -30,7 +30,7 @@ component = "my-application" # the name of the component to handle this route Such a trigger says that Redis messages on the specified _channel_ should be handled by the specified _component_. The `component` field works the same way across all triggers - see [Triggers](triggers) for the details. -> Spin subscribes only to the channels that are mapped to components. Other channels are ignored. +> Spin subscribes only to the channels that are mapped to components. Other channels are ignored. If multiple components subscribe to the same channel, a message on that channel will activate all of the components. ## Redis Trigger Application Settings diff --git a/content/spin/v2/running-apps.md b/content/spin/v2/running-apps.md index 85491f36b..97d28349d 100644 --- a/content/spin/v2/running-apps.md +++ b/content/spin/v2/running-apps.md @@ -74,6 +74,14 @@ To control logging, pass the `--log-dir` flag. The logs will be saved to the sp $ spin up --log-dir ~/dev/bugbash ``` +If you prefer **not** to have the `stdout` and `stderr` of your application's components written to disk (as in the example above), you can pass the `--log-dir` flag with an empty string, like this: + + + +```bash +$ spin up --log-dir "" +``` + ## Trigger-Specific Options Some trigger types support additional `spin up` flags. For example, HTTP applications can have a `--listen` flag to specify an address and port to listen on. See the [HTTP trigger](http-trigger) and [Redis trigger](redis-trigger) pages for more details. diff --git a/content/spin/v2/rust-components.md b/content/spin/v2/rust-components.md index 804be3bd3..58ccb8c31 100644 --- a/content/spin/v2/rust-components.md +++ b/content/spin/v2/rust-components.md @@ -11,12 +11,14 @@ url = "https://github.com/fermyon/developer/blob/main/content/spin/v2/rust-compo - [HTTP Components](#http-components) - [Redis Components](#redis-components) - [Sending Outbound HTTP Requests](#sending-outbound-http-requests) +- [Routing in a Component](#routing-in-a-component) - [Storing Data in Redis From Rust Components](#storing-data-in-redis-from-rust-components) - [Storing Data in the Spin Key-Value Store](#storing-data-in-the-spin-key-value-store) - [Serializing Objects to the Key-Value Store](#serializing-objects-to-the-key-value-store) - [Storing Data in SQLite](#storing-data-in-sqlite) - [Storing Data in Relational Databases](#storing-data-in-relational-databases) - [Using External Crates in Rust Components](#using-external-crates-in-rust-components) + - [Using the `http` crate](#using-the-http-crate) - [AI Inferencing From Rust Components](#ai-inferencing-from-rust-components) - [Troubleshooting](#troubleshooting) - [Manually Creating New Projects With Cargo](#manually-creating-new-projects-with-cargo) @@ -289,6 +291,45 @@ proxies or URL shorteners. > The Spin SDK for Rust provides more flexibility than we show here, including allowing streaming uploads or downloads. See the [Outbound HTTP API Guide](./http-outbound.md) for more information. +## Routing in a Component + +The Rust SDK [provides a router](https://github.com/fermyon/spin/tree/main/examples/http-rust-router) that makes it easier to handle routing within a component: + +```rust +use anyhow::Result; +use spin_sdk::{ + http::{IntoResponse, Params, Request, Response, Router}, + http_component, +}; + +/// A Spin HTTP component that internally routes requests. +#[http_component] +fn handle_route(req: Request) -> Response { + let mut router = Router::new(); + router.get("/goodbye/:planet", api::goodbye_planet); + router.any_async("/*", api::echo_wildcard); + router.handle(req) +} + +mod api { + use super::*; + + // /goodbye/:planet + pub fn goodbye_planet(_req: Request, params: Params) -> Result { + let planet = params.get("planet").expect("PLANET"); + Ok(Response::new(200, planet.to_string())) + } + + // /* + pub async fn echo_wildcard(_req: Request, params: Params) -> Result { + let capture = params.wildcard().unwrap_or_default(); + Ok(Response::new(200, capture.to_string())) + } +} +``` + +> For further reference, see the [Spin SDK HTTP router](https://fermyon.github.io/rust-docs/spin/main/spin_sdk/http/struct.Router.html). + ## Storing Data in Redis From Rust Components Using the Spin's Rust SDK, you can use the Redis key/value store and to publish @@ -298,9 +339,9 @@ components. Let's see how we can use the Rust SDK to connect to Redis: ```rust -use anyhow::{Context, Result}; +use anyhow::Context; use spin_sdk::{ - http::{responses::internal_server_error, Request, Response}, + http::{responses::internal_server_error, IntoResponse, Request, Response}, http_component, redis::Connection, }; @@ -319,7 +360,7 @@ const REDIS_CHANNEL_ENV: &str = "REDIS_CHANNEL"; /// to a Redis channel. The component is triggered by an HTTP /// request served on the route configured in the `spin.toml`. #[http_component] -fn publish(_req: Request) -> Result { +fn publish(_req: Request) -> anyhow::Result { let address = std::env::var(REDIS_ADDRESS_ENV)?; let channel = std::env::var(REDIS_CHANNEL_ENV)?; @@ -386,6 +427,13 @@ serde = { version = "1.0.163", features = ["derive"] } // --snip -- ``` +We configure our application to provision the default `key_value_stores` by adding the following line to our application's manifest (the `spin.toml` file), at the component level: + +``` +[component.redis-test] +key_value_stores = ["default"] +``` + The Rust code below shows how to store and retrieve serializable objects from the key-value store (note how the example below implements Serde's `derive` feature): ```rust diff --git a/content/spin/v2/serverless-ai-api-guide.md b/content/spin/v2/serverless-ai-api-guide.md index 31571b420..1a047e0fc 100644 --- a/content/spin/v2/serverless-ai-api-guide.md +++ b/content/spin/v2/serverless-ai-api-guide.md @@ -70,13 +70,13 @@ To use Serverless AI functions, the `llm` module from the Spin SDK provides the ```rust use spin_sdk::{ - http::{Request, Response}, + http::{IntoResponse, Request, Response}, llm, }; // -- snip -- -fn handle_code(req: Request) -> Result { +fn handle_code(req: Request) -> anyhow::Result { // -- snip -- let result = llm::infer_with_options( diff --git a/content/spin/v2/serverless-ai-hello-world.md b/content/spin/v2/serverless-ai-hello-world.md index 2b9591a02..ae12e2042 100644 --- a/content/spin/v2/serverless-ai-hello-world.md +++ b/content/spin/v2/serverless-ai-hello-world.md @@ -224,15 +224,17 @@ Now let's use the Spin SDK to access the model from our app. Executing inference {{ startTab "Rust"}} ```rust -use spin_sdk::{http::{IntoResponse, Request}, http_component, llm}; +use spin_sdk::{http::{IntoResponse, Request, Response}, http_component, llm}; #[http_component] fn hello_world(_req: Request) -> anyhow::Result { let model = llm::InferencingModel::Llama2Chat; let inference = llm::infer(model, "Can you tell me a joke about cats"); - Ok(http::Response::builder() - .status(200) - .body(format!("{:?}", inference))?) + Ok(Response::builder() + .status(200) + .header("content-type", "text/plain") + .body(format!("{:?}", inference)) + .build()) } ``` diff --git a/content/spin/v2/spin-application-structure.md b/content/spin/v2/spin-application-structure.md index de192ac90..408f096e3 100644 --- a/content/spin/v2/spin-application-structure.md +++ b/content/spin/v2/spin-application-structure.md @@ -72,22 +72,30 @@ After adding two new components, we can see the visual representation of our app To customize each of the two components, we can modify the `lib.rs` (Rust source code) of each component: ```rust +use spin_sdk::http::{IntoResponse, Request, Response}; +use spin_sdk::http_component; + +/// A simple Spin HTTP component. #[http_component] -fn handle_first_http_rust_component(req: Request) -> Result { - Ok(http::Response::builder() +fn handle_first_http_rust_component(req: Request) -> anyhow::Result { + println!("Handling request to {:?}", req.header("spin-full-url")); + Ok(Response::builder() .status(200) .header("content-type", "text/plain") - .body("Hello, First Component")?) + .body("Hello, First Component") + .build()) } ``` ```rust #[http_component] -fn handle_second_http_rust_component(req: Request) -> Result { - Ok(http::Response::builder() +fn handle_second_http_rust_component(req: Request) -> anyhow::Result { + println!("Handling request to {:?}", req.header("spin-full-url")); + Ok(Response::builder() .status(200) .header("content-type", "text/plain") - .body("Hello, Second Component")?) + .body("Hello, Second Component") + .build()) } ``` diff --git a/content/spin/v2/sqlite-api-guide.md b/content/spin/v2/sqlite-api-guide.md index c127ecc9e..34a58b462 100644 --- a/content/spin/v2/sqlite-api-guide.md +++ b/content/spin/v2/sqlite-api-guide.md @@ -45,6 +45,14 @@ The exact detail of calling these operations from your application depends on yo {{ startTab "Rust"}} +Please note, we use `serde` in this Rust example, so please add `serde` as a dependency in your application's `Cargo.toml` file: + +```toml +[dependencies] +serde = {version = "1.0", features = ["derive"]} +serde_json = "1.0" +``` + > [**Want to go straight to the reference documentation?** Find it here.](https://fermyon.github.io/rust-docs/spin/main/spin_sdk/sqlite/index.html) SQLite functions are available in the `spin_sdk::sqlite` module. The function names match the operations above. For example: @@ -53,7 +61,7 @@ SQLite functions are available in the `spin_sdk::sqlite` module. The function na use anyhow::Result; use serde::Serialize; use spin_sdk::{ - http::{Request, IntoResponse}, + http::{Request, Response, IntoResponse}, http_component, sqlite::{Connection, Value}, }; @@ -85,7 +93,11 @@ fn handle_request(req: Request) -> Result { ).collect(); let body = serde_json::to_vec(&todos)?; - Ok(http::Response::builder().status(200).body(Some(body.into()))?) + Ok(Response::builder() + .status(200) + .header("content-type", "text/plain") + .body(body) + .build()) } // Helper for returning the query results as JSON diff --git a/content/spin/v2/variables.md b/content/spin/v2/variables.md index 1bcef6361..ccf306233 100644 --- a/content/spin/v2/variables.md +++ b/content/spin/v2/variables.md @@ -90,7 +90,7 @@ The interface is available in the `spin_sdk::variables` module and is named `get ```rust use anyhow::Result; use spin_sdk::{ - http::{IntoResponse, Request}, + http::{IntoResponse, Request, Response}, http_component, variables, }; @@ -105,10 +105,11 @@ fn handle_spin_example(req: Request) -> Result { "denied" }; let response_json = format!("\{{\"authentication\": \"{}\"}}", response); - Ok(http::Response::builder() + Ok(Response::builder() .status(200) - .header("Content-Type", "application/json") - .body(response_json)?) + .header("content-type", "application/json") + .body(response_json) + .build()) } ``` diff --git a/content/spin/v2/writing-apps.md b/content/spin/v2/writing-apps.md index 81ba716fe..4f90fc584 100644 --- a/content/spin/v2/writing-apps.md +++ b/content/spin/v2/writing-apps.md @@ -139,15 +139,22 @@ Multiple components can have the same source. An example is a document archive, At the Wasm level, a Spin component is a Wasm component or module that exports a handler for the application trigger. At the developer level, a Spin component is a library or program that implements your event handling logic, and uses Spin interfaces, libraries, or tools to associate that with the events handled by Spin. -See the Language Guides section for how to do this in your preferred language. As an example, this is a component written in the Rust language. The `hello_world` function uses an attribute `#[http_component]` to identify the function as handling a Spin HTTP event. The function takes a `Request` and returns a `Result`: +See the Language Guides section for how to do this in your preferred language. As an example, this is a component written in the Rust language. The `hello_world` function uses an attribute `#[http_component]` to identify the function as handling a Spin HTTP event. The function takes a `Request` and returns a `anyhow::Result`. ```rust -#[http_component]​ -fn hello_world(_req: Request) -> Result {​ - Ok(http::Response::builder()​ - .status(200)​ - .body("Hello, Fermyon!")?)​ -}​ +use spin_sdk::http::{IntoResponse, Request, Response}; +use spin_sdk::http_component; + +/// A simple Spin HTTP component. +#[http_component] +fn hello_world(req: Request) -> anyhow::Result { + println!("Handling request to {:?}", req.header("spin-full-url")); + Ok(Response::builder() + .status(200) + .header("content-type", "text/plain") + .body("Hello, Fermyon") + .build()) +}​​ ``` ## Creating an Application From a Template @@ -295,13 +302,18 @@ The field accepts a map of environment variable key/value pairs. They are mapped The environment variables can then be accessed inside the component. For example, in Rust: -```rs +```rust +use spin_sdk::http::{IntoResponse, Request, Response}; +use spin_sdk::http_component; + #[http_component] -fn handle_hello_rust(req: Request) -> Result { +fn handle_hello_rust(req: Request) -> anyhow::Result { let response = format!("My {} likes to eat {}", std::env::var("PET")?, std::env::var("FOOD")?); - Ok(http::Response::builder() + Ok(Response::builder() .status(200) - .body(response)?) + .header("content-type", "text/plain") + .body(response) + .build()) } ```