Skip to content

Commit

Permalink
Serialization guide for Typescript (#448)
Browse files Browse the repository at this point in the history
* Serialization guide for Typescript

* Update all the other snippets to use the new api for send
  • Loading branch information
slinkydeveloper authored Aug 28, 2024
1 parent 7c31a8a commit 4fe82f7
Show file tree
Hide file tree
Showing 11 changed files with 959 additions and 886 deletions.
1,722 changes: 854 additions & 868 deletions code_snippets/ts/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions code_snippets/ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
},
"dependencies": {
"@restatedev/restate-cdk": "^1.0.0",
"@restatedev/restate-sdk": "^1.0.0",
"@restatedev/restate-sdk-clients": "^1.0.0",
"@restatedev/restate-sdk": "^1.3.0",
"@restatedev/restate-sdk-clients": "^1.3.0",
"express": "^4.19.2"
},
"devDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions code_snippets/ts/src/concepts/invocations/delayed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ async function myRestateHandler(ctx: restate.Context) {
// focus
ctx
// focus
.serviceSendClient(greeter, { delay: 1000 })
.serviceSendClient(greeter)
// focus
.greet({ greeting: "Hi" });
.greet({ greeting: "Hi" }, restate.rpc.sendOpts({ delay: 1000 }));
}
// <end_delayed_call>
5 changes: 2 additions & 3 deletions code_snippets/ts/src/concepts/invocations/ingress/delayed.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as restate from "@restatedev/restate-sdk-clients";
import { greetCounter, greeter } from "../utils";
import { SendOpts } from "@restatedev/restate-sdk-clients";
import { greeter } from "../utils";

// <start_delayed_call_node>
const myPlainTSFunction = async () => {
Expand All @@ -11,6 +10,6 @@ const myPlainTSFunction = async () => {
// focus
.serviceSendClient(greeter)
// focus
.greet({ greeting: "Hi" }, SendOpts.from({ delay: 1000 }));
.greet({ greeting: "Hi" }, restate.rpc.sendOpts({ delay: 1000 }));
};
// <end_delayed_call_node>
9 changes: 4 additions & 5 deletions code_snippets/ts/src/develop/clients/ingress.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { greetCounterObject, greeterService } from "./utils";
import { SendOpts } from "@restatedev/restate-sdk-clients";
import { myWorkflow } from "../../concepts/invocations/utils";
import * as clients from "@restatedev/restate-sdk-clients";

Expand Down Expand Up @@ -35,11 +34,11 @@ const myPlainTSFunction3 = async () => {
const rs = clients.connect({ url: "http://localhost:8080" });
await rs
.serviceSendClient(greeterService)
.greet({ greeting: "Hi" }, SendOpts.from({ delay: 1000 }));
.greet({ greeting: "Hi" }, clients.rpc.sendOpts({ delay: 1000 }));

await rs
.objectSendClient(greetCounterObject, "Mary")
.greet({ greeting: "Hi" }, SendOpts.from({ delay: 1000 }));
.greet({ greeting: "Hi" }, clients.rpc.sendOpts({ delay: 1000 }));
// <end_delayed_call_node>
};

Expand All @@ -50,7 +49,7 @@ const servicesIdempotent = async () => {
await rs
.serviceSendClient(greeterService)
// withClass highlight-line
.greet(request, SendOpts.from({ idempotencyKey: "abcde" }));
.greet(request, clients.rpc.sendOpts({ idempotencyKey: "abcde" }));
// <end_service_idempotent>
};

Expand All @@ -63,7 +62,7 @@ const servicesAttach = async () => {
const handle = await rs
.serviceSendClient(greeterService)
// mark
.greet(request, SendOpts.from({ idempotencyKey: "abcde" }));
.greet(request, clients.rpc.sendOpts({ idempotencyKey: "abcde" }));

// ... do something else ...

Expand Down
46 changes: 46 additions & 0 deletions code_snippets/ts/src/develop/serialization.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as restate from "@restatedev/restate-sdk";
import {Context, WorkflowContext} from "@restatedev/restate-sdk";

// <start_service_definition>
const myService = restate.service({
name: "MyService",
handlers: {
myHandler: restate.handlers.handler({
// Set the input serde here
input: restate.serde.binary,
// Set the output serde here
output: restate.serde.binary
}, async (ctx: Context, data: Uint8Array): Promise<Uint8Array> => {
// Process the request
return data;
}),
},
});
// <end_service_definition>

let ctx: WorkflowContext = undefined as unknown as WorkflowContext;
let input = new Uint8Array();

// <start_client>
ctx.serviceClient(myService)
.myHandler(
input,
restate.rpc.opts({
input: restate.serde.binary,
output: restate.serde.binary
})
);
// <end_client>

// <start_state>
ctx.get("my-binary-data", restate.serde.binary);
ctx.set("my-binary-data", new Uint8Array(), restate.serde.binary);
// <end_state>

// <start_awakeable>
ctx.awakeable(restate.serde.binary)
// <end_awakeable>

// <start_run>
ctx.run("my-side-effect", () => new Uint8Array(), { serde: restate.serde.binary });
// <end_run>
6 changes: 3 additions & 3 deletions code_snippets/ts/src/develop/service_communication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ const service = restate.service({
// <end_one_way_object>

// <start_delayed_service>
ctx.serviceSendClient(MyService, { delay: 5000 }).myHandler("Hi");
ctx.serviceSendClient(MyService).myHandler("Hi", restate.rpc.sendOpts({ delay: 5000 }));
// <end_delayed_service>

// <start_delayed_object>
ctx
.objectSendClient(MyVirtualObject, "Mary", { delay: 5000 })
.myHandler("Hi");
.objectSendClient(MyVirtualObject, "Mary")
.myHandler("Hi", restate.rpc.sendOpts({ delay: 5000 }));
// <end_delayed_object>

// <start_ordering>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ async function submitAndAwaitTask(task: TaskOpts) {
.runTask(
task,
// <mark_2>
SendOpts.from({ idempotencyKey: "dQw4w9WgXcQ" })
restate.rpc.sendOpts({ idempotencyKey: "dQw4w9WgXcQ" })
// </mark_2>
);
// </mark_1>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const eventEnricher = restate.object({
ctx.set("user", event);
// </mark_1>
// <mark_3>
ctx.objectSendClient(EventEnricher, ctx.key, { delay: 1000 }).emit();
ctx.objectSendClient(EventEnricher, ctx.key).emit(restate.rpc.sendOpts({ delay: 1000 }));
// </mark_3>
},

Expand Down
43 changes: 43 additions & 0 deletions docs/develop/ts/serialization.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
sidebar_position: 9
description: "How to serialize and deserialize data with the Restate SDK."
---

# Serialization

Restate sends data over the network for storing state, journaling actions, awakeables, etc.

By default, Typescript SDK uses the built-in [JSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON)
support to perform (de)serialization, but it is possible to override this behavior using the `Serde` interface.

For example, to customize the `Serde` to use for the handler input and output:

```typescript
CODE_LOAD::ts/src/develop/serialization.ts#service_definition
```

To customize the serde to use on requests:

```typescript
CODE_LOAD::ts/src/develop/serialization.ts#client
```

When sending a request to a handler configured with custom serde(s) you always need to manually specify them, because the client does not automatically infer what serde(s) should be used.

To customize the serde to use for state:

```typescript
CODE_LOAD::ts/src/develop/serialization.ts#state
```

For awakeables:

```typescript
CODE_LOAD::ts/src/develop/serialization.ts#awakeable
```

For `run`:

```typescript
CODE_LOAD::ts/src/develop/serialization.ts#run
```
2 changes: 1 addition & 1 deletion restate.config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"RESTATE_VERSION": "1.0",
"TYPESCRIPT_SDK_VERSION": "1.1.2",
"TYPESCRIPT_SDK_VERSION": "1.3.0",
"JAVA_SDK_VERSION": "1.0.1"
}

0 comments on commit 4fe82f7

Please sign in to comment.