Skip to content

Commit 580fc15

Browse files
committed
Add docs for procedures
In the spirit of our planned move to concept-based documentation rather than language-based documentation, I've chosen to add a quick section to the overview, and then a new page for documentation about procedures. I have not updated any tutorials or reference pages.
1 parent 507b087 commit 580fc15

17 files changed

Lines changed: 462 additions & 0 deletions

docs/docs/01-Intro/01-overview.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,115 @@ or at a specific time.
279279
</TabItem>
280280
</Tabs>
281281

282+
### Procedure
283+
284+
A **procedure** is a function exported by a [database](#database), similar to a [reducer](#reducer).
285+
Connected [clients](#client-side-sdks) can call procedures.
286+
Procedures can perform additional operations not possible in reducers, including making HTTP requests to external services.
287+
However, procedures don't automatically run in database transactions,
288+
and must manually open and commit a transaction in order to read from or modify the database state.
289+
290+
<Tabs grouId="syntax" queryString>
291+
<TabItem value="rust" label="Rust">
292+
293+
A procedure can be defined in a Rust module:
294+
295+
```rust
296+
#[spacetimedb::procedure]
297+
pub fn make_request(ctx: &mut spacetimedb::ProcedureContext) -> String {
298+
// ...
299+
}
300+
```
301+
302+
And a Rust [client](#client) can call that procedure:
303+
304+
```rust
305+
fn main() {
306+
// ...setup code, then...
307+
ctx.procedures.make_request();
308+
}
309+
```
310+
311+
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:
312+
313+
```rust
314+
fn main() {
315+
// ...setup code, then...
316+
ctx.procedures.make_request_then(|ctx, res| {
317+
match res {
318+
Ok(string) => log::info!("Procedure `make_request` returned {string}"),
319+
Err(e) => log::error!("Procedure `make_request` failed! {e:?}"),
320+
}
321+
})
322+
}
323+
```
324+
325+
</TabItem>
326+
<TabItem value="csharp" label="C#">
327+
328+
C# modules currently cannot define procedures. Support for defining procedures in C# modules will be released shortly.
329+
330+
A C# [client](#client) can call a procedure defined by a Rust or TypeScript module:
331+
332+
```csharp
333+
void Main()
334+
{
335+
// ...setup code, then...
336+
ctx.Procedures.MakeRequest();
337+
}
338+
```
339+
340+
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:
341+
342+
```csharp
343+
void Main()
344+
{
345+
// ...setup code, then...
346+
ctx.Procedures.MakeRequestThen((ctx, res) =>
347+
{
348+
if (res.IsSuccess)
349+
{
350+
Log.Debug("Procedure `make_request` returned {Value}", res.Value);
351+
}
352+
else
353+
{
354+
throw new Exception(res.Error, "Procedure `make_request` failed!");
355+
}
356+
});
357+
}
358+
```
359+
360+
</TabItem>
361+
<TabItem value="typescript" label="TypeScript">
362+
363+
A procedure can be defined in a TypeScript module:
364+
365+
```typescript
366+
spacetimedb.procedure("make_request", t.string(), ctx => {
367+
// ...
368+
})
369+
```
370+
371+
And a TypeScript [client](#client) can call that procedure:
372+
373+
```typescript
374+
ctx.procedures.makeRequest();
375+
```
376+
377+
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:
378+
379+
```typescript
380+
ctx.procedures.makeRequest().then(
381+
res => console.log(`Procedure make_request returned ${res}`),
382+
err => console.error(`Procedure make_request failed! ${err}`),
383+
);
384+
```
385+
386+
</TabItem>
387+
</Tabs>
388+
389+
See [Procedures](/procedures) for more details about procedures.
390+
282391
### Client
283392

284393
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).

0 commit comments

Comments
 (0)