Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions docs/docs/01-intro/01-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,124 @@ or at a specific time.
</TabItem>
</Tabs>

### Procedure

A **procedure** is a function exported by a [database](#database), similar to a [reducer](#reducer).
Connected [clients](#client-side-sdks) can call procedures.
Procedures can perform additional operations not possible in reducers, including making HTTP requests to external services.
However, procedures don't automatically run in database transactions,
and must manually open and commit a transaction in order to read from or modify the database state.

Procedures are currently in beta, and their API may change in upcoming SpacetimeDB releases.

<Tabs groupId="syntax" queryString>
<TabItem value="rust" label="Rust">

Because procedures are unstable, Rust modules that define them must opt in to the `unstable` feature in their `Cargo.toml`:

```toml
[dependencies]
spacetimedb = { version = "1.x", features = ["unstable"] }
```

Then, that module can define a procedure:

```rust
#[spacetimedb::procedure]
pub fn make_request(ctx: &mut spacetimedb::ProcedureContext) -> String {
// ...
}
```

And a Rust [client](#client) can call that procedure:

```rust
fn main() {
// ...setup code, then...
ctx.procedures.make_request();
}
```

A Rust [client](#client) can also register a callback to run when a procedure call finishes, which will be invoked with that procedure's return value:

```rust
fn main() {
// ...setup code, then...
ctx.procedures.make_request_then(|ctx, res| {
match res {
Ok(string) => log::info!("Procedure `make_request` returned {string}"),
Err(e) => log::error!("Procedure `make_request` failed! {e:?}"),
}
})
}
```

</TabItem>
<TabItem value="csharp" label="C#">

C# modules currently cannot define procedures. Support for defining procedures in C# modules will be released shortly.

A C# [client](#client) can call a procedure defined by a Rust or TypeScript module:

```csharp
void Main()
{
// ...setup code, then...
ctx.Procedures.MakeRequest();
}
```

A C# [client](#client) can also register a callback to run when a procedure call finishes, which will be invoked with that procedure's return value:

```csharp
void Main()
{
// ...setup code, then...
ctx.Procedures.MakeRequestThen((ctx, res) =>
{
if (res.IsSuccess)
{
Log.Debug($"Procedure `make_request` returned {res.Value!}");
}
else
{
throw new Exception($"Procedure `make_request` failed: {res.Error!}");
}
});
}
```

</TabItem>
<TabItem value="typescript" label="TypeScript">

A procedure can be defined in a TypeScript module:

```typescript
spacetimedb.procedure("make_request", t.string(), ctx => {
// ...
})
```

And a TypeScript [client](#client) can call that procedure:

```typescript
ctx.procedures.makeRequest();
```

A Rust [client](#client) can also register a callback to run when a procedure call finishes, which will be invoked with that procedure's return value:

```typescript
ctx.procedures.makeRequest().then(
res => console.log(`Procedure make_request returned ${res}`),
err => console.error(`Procedure make_request failed! ${err}`),
);
```

</TabItem>
</Tabs>

See [Procedures](/procedures) for more details about procedures.

### Client

A **client** is an application that connects to a [database](#database). A client logs in using an [identity](#identity) and receives an [connection id](#connectionid) to identify the connection. After that, it can call [reducers](#reducer) and query public [tables](#table).
Expand Down
Loading