Skip to content
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
3f61a28
Implement HTTP handlers / webhooks in Rust modules
gefjon Apr 8, 2026
8be80a2
Add a smoketest
gefjon Apr 9, 2026
ad560f1
fmt
gefjon Apr 9, 2026
690bf66
Reorganize imports to correct feature gates
gefjon Apr 10, 2026
7ac412a
Update bindings deps snapshot with `bytes`
gefjon Apr 10, 2026
77057cc
Update smoketest modules Cargo.lock for `bytes` dependency
gefjon Apr 10, 2026
977c1a0
Add additional smoketest with example from PR description
gefjon Apr 10, 2026
1a42332
Merge branch 'master' into phoebe/http-handlers-webhooks
gefjon Apr 10, 2026
ae3dfa3
fmt
gefjon Apr 10, 2026
f527c10
Regen C# moduledef to make `check-diff.sh` test pass
gefjon Apr 13, 2026
3df5ab2
Add bindings UI test for HTTP handlers
gefjon Apr 14, 2026
797f3dc
Remove unnecessary duplicated binding in macro output
gefjon Apr 14, 2026
151f224
Be more restrictive about characters allowed in HTTP routes
gefjon Apr 15, 2026
9892e9b
fmt
gefjon Apr 15, 2026
f976a00
clippy
gefjon Apr 15, 2026
c60824e
Merge origin/master into phoebe/http-handlers-webhooks
clockwork-labs-bot Apr 16, 2026
14e840e
Merge branch 'master' into phoebe/http-handlers-webhooks
gefjon Apr 17, 2026
7e20eda
Use updated Axum syntax for wildcards
gefjon Apr 17, 2026
999a7c3
Fix name collision with `const index` or `const name` colocated with …
gefjon Apr 21, 2026
847f989
Accept the empty route path; distinguish between empty and root
gefjon Apr 21, 2026
0788247
Silence warning on non-upper-case global emitted by `#[handler]`
gefjon Apr 21, 2026
c02f795
Expose full URI to handlers, incl. protocol and authority
gefjon Apr 22, 2026
0dde205
Simplify passing path into handler impl
gefjon Apr 22, 2026
4a4da89
Move `HandlerContext` to `spacetimedb::http::HandlerContext`.
gefjon Apr 24, 2026
86e6b6f
Add docs for HTTP handlers and router
gefjon Apr 24, 2026
b5e6e1a
Add smoketest that examples in docs work
gefjon Apr 24, 2026
6a98071
Merge remote-tracking branch 'origin/master' into phoebe/http-handler…
gefjon Apr 24, 2026
6c691ae
Axum 0.7 syntax for routes
gefjon Apr 24, 2026
df07ba9
Add forgotten file
gefjon Apr 24, 2026
163f6af
Correct (?) link
gefjon Apr 24, 2026
d296a17
Add a smoketest that inspects the request body
gefjon Apr 28, 2026
5f8e544
Expand comment re: unstable feature in CI
gefjon Apr 30, 2026
e832d2e
Separate request/response body from metadata at ABI level
gefjon Apr 30, 2026
7c54b94
Unify the "standard" and "extra" bytes sinks
gefjon Apr 30, 2026
af880fc
fmt
gefjon May 1, 2026
5999b64
Add doc comment to `Router`, amend doc comments on route register met…
gefjon May 1, 2026
5fab877
Add doc comments for `handler` and `router` macros
gefjon May 1, 2026
5c233e6
Respond to Mazdak's review
gefjon May 11, 2026
db472dc
Merge remote-tracking branch 'origin/master' into phoebe/http-handler…
gefjon May 11, 2026
032e23b
Merge remote-tracking branch 'origin/master' into phoebe/http-handler…
gefjon May 18, 2026
b258f95
fmt, clippy
gefjon May 18, 2026
a7c02cc
Put HTTP handler routes in `DatabaseRoutes`
gefjon May 19, 2026
cadc224
Add missing comma in merged autogen file
gefjon May 19, 2026
67c6890
C# HTTP handlers - Module Bindings (#5024)
JasonAtClockwork May 21, 2026
5f4180e
Merge remote-tracking branch 'origin/master' into phoebe/http-handler…
gefjon May 22, 2026
ac16512
fmt
gefjon May 22, 2026
6d4c323
Fix some merge mistakes
gefjon May 22, 2026
6b37954
And some more merge mistakes
gefjon May 22, 2026
c66379d
Regen module def for C#
JasonAtClockwork May 22, 2026
7f37ff6
TypeScript HTTP handlers (#4931)
gefjon May 22, 2026
f342524
Fix TS router path join for CodeQL alert
JasonAtClockwork May 22, 2026
6307a68
C++ HTTP handlers - Module Bindings (#5023)
JasonAtClockwork May 22, 2026
04771f6
Merge branch 'master' into phoebe/http-handlers-webhooks
gefjon May 28, 2026
ffb3fb0
Add basic troubleshooting guide
gefjon May 28, 2026
e84737c
Revert "Add basic troubleshooting guide"
gefjon May 28, 2026
5484877
Merge remote-tracking branch 'origin/master' into phoebe/http-handler…
gefjon May 29, 2026
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
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
}
},
{/*
SpacetimeDB.Internal.Module.RegisterTable<global::TestUniqueNotEquatable, SpacetimeDB.Internal.TableHandles.TestUniqueNotEquatable>();
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_FILTER);
^^^^^^^^^
SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(global::Module.MY_FOURTH_FILTER);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public readonly partial struct QueryBuilder
new("DemoTable", new DemoTableCols("DemoTable"), new DemoTableIxCols("DemoTable"));
}

public static class Handlers { }

public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
{
public readonly Identity Sender;
Expand Down Expand Up @@ -210,6 +212,46 @@ public Uuid NewUuidV7()
}
}

public sealed partial class HandlerContext : global::SpacetimeDB.HandlerContextBase
{
private readonly Local _db = new();

internal HandlerContext(Random random, Timestamp time)
: base(random, time) { }

protected override global::SpacetimeDB.LocalBase CreateLocal() => _db;

protected override global::SpacetimeDB.HandlerTxContextBase CreateTxContext(
Internal.TxContext inner
) => _cached ??= new HandlerTxContext(inner);

private HandlerTxContext? _cached;

[Experimental("STDB_UNSTABLE")]
public TResult WithTx<TResult>(Func<HandlerTxContext, TResult> body) =>
base.WithTx(tx => body((HandlerTxContext)tx));

[Experimental("STDB_UNSTABLE")]
public TxOutcome<TResult> TryWithTx<TResult, TError>(
Func<HandlerTxContext, Result<TResult, TError>> body
)
where TError : Exception => base.TryWithTx(tx => body((HandlerTxContext)tx));

public Uuid NewUuidV4()
{
var bytes = new byte[16];
Rng.NextBytes(bytes);
return Uuid.FromRandomBytesV4(bytes);
}

public Uuid NewUuidV7()
{
var bytes = new byte[4];
Rng.NextBytes(bytes);
return Uuid.FromCounterV7(ref CounterUuid, Timestamp, bytes);
}
}

[Experimental("STDB_UNSTABLE")]
public sealed class ProcedureTxContext : global::SpacetimeDB.ProcedureTxContextBase
{
Expand All @@ -219,6 +261,15 @@ internal ProcedureTxContext(Internal.TxContext inner)
public new Local Db => (Local)base.Db;
}

[Experimental("STDB_UNSTABLE")]
public sealed class HandlerTxContext : global::SpacetimeDB.HandlerTxContextBase
{
internal HandlerTxContext(Internal.TxContext inner)
: base(inner) { }

public new Local Db => (Local)base.Db;
}

public sealed class Local : global::SpacetimeDB.LocalBase
{
public global::SpacetimeDB.Internal.TableHandles.DemoTable DemoTable => new();
Expand Down Expand Up @@ -560,6 +611,9 @@ public static void Main()
"canonical_index"
);

SpacetimeDB.Internal.Module.SetHandlerContextConstructor(
(random, time) => new SpacetimeDB.HandlerContext(random, time)
);
var __memoryStream = new MemoryStream();
var __writer = new BinaryWriter(__memoryStream);

Expand Down Expand Up @@ -635,6 +689,24 @@ SpacetimeDB.Internal.BytesSink result_sink
result_sink
);

[UnmanagedCallersOnly(EntryPoint = "__call_http_handler__")]
public static SpacetimeDB.Internal.Errno __call_http_handler__(
uint id,
SpacetimeDB.Timestamp timestamp,
SpacetimeDB.Internal.BytesSource request,
SpacetimeDB.Internal.BytesSource request_body,
SpacetimeDB.Internal.BytesSink response_sink,
SpacetimeDB.Internal.BytesSink response_body_sink
) =>
SpacetimeDB.Internal.Module.__call_http_handler__(
id,
timestamp,
request,
request_body,
response_sink,
response_body_sink
);

[UnmanagedCallersOnly(EntryPoint = "__call_view__")]
public static SpacetimeDB.Internal.Errno __call_view__(
uint id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ public readonly partial struct QueryBuilder
);
}

public static class Handlers { }

public sealed record ReducerContext : DbContext<Local>, Internal.IReducerContext
{
public readonly Identity Sender;
Expand Down Expand Up @@ -652,6 +654,46 @@ public Uuid NewUuidV7()
}
}

public sealed partial class HandlerContext : global::SpacetimeDB.HandlerContextBase
{
private readonly Local _db = new();

internal HandlerContext(Random random, Timestamp time)
: base(random, time) { }

protected override global::SpacetimeDB.LocalBase CreateLocal() => _db;

protected override global::SpacetimeDB.HandlerTxContextBase CreateTxContext(
Internal.TxContext inner
) => _cached ??= new HandlerTxContext(inner);

private HandlerTxContext? _cached;

[Experimental("STDB_UNSTABLE")]
public TResult WithTx<TResult>(Func<HandlerTxContext, TResult> body) =>
base.WithTx(tx => body((HandlerTxContext)tx));

[Experimental("STDB_UNSTABLE")]
public TxOutcome<TResult> TryWithTx<TResult, TError>(
Func<HandlerTxContext, Result<TResult, TError>> body
)
where TError : Exception => base.TryWithTx(tx => body((HandlerTxContext)tx));

public Uuid NewUuidV4()
{
var bytes = new byte[16];
Rng.NextBytes(bytes);
return Uuid.FromRandomBytesV4(bytes);
}

public Uuid NewUuidV7()
{
var bytes = new byte[4];
Rng.NextBytes(bytes);
return Uuid.FromCounterV7(ref CounterUuid, Timestamp, bytes);
}
}

[Experimental("STDB_UNSTABLE")]
public sealed class ProcedureTxContext : global::SpacetimeDB.ProcedureTxContextBase
{
Expand All @@ -661,6 +703,15 @@ internal ProcedureTxContext(Internal.TxContext inner)
public new Local Db => (Local)base.Db;
}

[Experimental("STDB_UNSTABLE")]
public sealed class HandlerTxContext : global::SpacetimeDB.HandlerTxContextBase
{
internal HandlerTxContext(Internal.TxContext inner)
: base(inner) { }

public new Local Db => (Local)base.Db;
}

public sealed class Local : global::SpacetimeDB.LocalBase
{
internal global::SpacetimeDB.Internal.TableHandles.BTreeMultiColumn BTreeMultiColumn =>
Expand Down Expand Up @@ -2450,6 +2501,9 @@ public static void Main()
(identity, connectionId, random, time) =>
new SpacetimeDB.ProcedureContext(identity, connectionId, random, time)
);
SpacetimeDB.Internal.Module.SetHandlerContextConstructor(
(random, time) => new SpacetimeDB.HandlerContext(random, time)
);
var __memoryStream = new MemoryStream();
var __writer = new BinaryWriter(__memoryStream);

Expand Down Expand Up @@ -2499,6 +2553,7 @@ public static void Main()
global::Timers.SendMessageTimer,
SpacetimeDB.Internal.TableHandles.SendMessageTimer
>();

SpacetimeDB.Internal.Module.RegisterClientVisibilityFilter(
global::Module.ALL_PUBLIC_TABLES
);
Expand Down Expand Up @@ -2562,6 +2617,24 @@ SpacetimeDB.Internal.BytesSink result_sink
result_sink
);

[UnmanagedCallersOnly(EntryPoint = "__call_http_handler__")]
public static SpacetimeDB.Internal.Errno __call_http_handler__(
uint id,
SpacetimeDB.Timestamp timestamp,
SpacetimeDB.Internal.BytesSource request,
SpacetimeDB.Internal.BytesSource request_body,
SpacetimeDB.Internal.BytesSink response_sink,
SpacetimeDB.Internal.BytesSink response_body_sink
) =>
SpacetimeDB.Internal.Module.__call_http_handler__(
id,
timestamp,
request,
request_body,
response_sink,
response_body_sink
);

[UnmanagedCallersOnly(EntryPoint = "__call_view__")]
public static SpacetimeDB.Internal.Errno __call_view__(
uint id,
Expand Down
Loading
Loading