Server

    Pre-requisites

    1. Install the SDK with :
    1. Import the libraries:
    1. import { DaprServer, CommunicationProtocolEnum } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1"; // Dapr Sidecar Host
    3. const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
    4. const serverHost = "127.0.0.1"; // App Host of this Example Server
    5. const serverPort = "50051"; // App Port of this Example Server
    6. // HTTP Example
    7. const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
    8. // GRPC Example
    9. const server = new DaprServer(serverHost, serverPort, daprHost, daprPort, CommunicationProtocolEnum.GRPC);

    Running

    To run the examples, you can use two different protocols to interact with the Dapr sidecar: HTTP (default) or gRPC.

    1. import { DaprServer } from "@dapr/dapr";
    2. const server = new DaprServer(appHost, appPort, daprHost, daprPort);
    3. // initialize subscribtions, ... before server start
    4. // the dapr sidecar relies on these
    5. await server.start();
    1. # Using dapr run
    2. dapr run --app-id example-sdk --app-port 50051 --app-protocol http -- npm run start
    3. # or, using npm script
    4. npm run start:dapr-http

    Using gRPC

    Since HTTP is the default, you will have to adapt the communication protocol to use gRPC. You can do this by passing an extra argument to the client or server constructor.

    1. # Using dapr run
    2. dapr run --app-id example-sdk --app-port 50051 --app-protocol grpc -- npm run start
    3. # or, using npm script
    4. npm run start:dapr-grpc

    ℹ️ Note: The app-port is required here, as this is where our server will need to bind to. Dapr will check for the application to bind to this port, before finishing start-up.

    The JavaScript Server SDK allows you to interface with all of the Dapr building blocks focusing on Sidecar to App features.

    Listen to an Invocation

    1. import { DaprServer, DaprInvokerCallbackContent } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1"; // Dapr Sidecar Host
    3. const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
    4. const serverHost = "127.0.0.1"; // App Host of this Example Server
    5. const serverPort = "50051"; // App Port of this Example Server "
    6. async function start() {
    7. const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
    8. const callbackFunction = (data: DaprInvokerCallbackContent) => {
    9. console.log("Received body: ", data.body);
    10. console.log("Received metadata: ", data.metadata);
    11. console.log("Received headers: ", data.headers); // only available in HTTP
    12. };
    13. await server.invoker.listen("hello-world", callbackFunction, { method: HttpMethod.GET });
    14. // You can now invoke the service with your app id and method "hello-world"
    15. await server.start();
    16. }
    17. start().catch((e) => {
    18. console.error(e);
    19. process.exit(1);
    20. });

    PubSub API

    Subscribe to messages

    Subscribing to messages can be done in several ways to offer flexibility of receiving messages on your topics:

    • Direct subscription through the subscribe method
    • Direct susbcription with options through the subscribeWithOptions method
    • Subscription afterwards through the susbcribeOnEvent method

    Each time an event arrives, we pass its body as and the headers as headers, which can contain properties of the event publisher (e.g., a device ID from IoT Hub)

    Dapr requires subscriptions to be set up on startup, but in the JS SDK we allow event handlers to be added afterwards as well, providing you the flexibility of programming.

    An example is provided below

    1. import { DaprServer } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1"; // Dapr Sidecar Host
    3. const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
    4. const serverHost = "127.0.0.1"; // App Host of this Example Server
    5. const serverPort = "50051"; // App Port of this Example Server "
    6. async function start() {
    7. const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
    8. const pubSubName = "my-pubsub-name";
    9. const topic = "topic-a";
    10. // Configure Subscriber for a Topic
    11. // Method 1: Direct subscription through the `subscribe` method
    12. await server.pubsub.subscribe(pubSubName, topic, async (data: any, headers: object) =>
    13. console.log(`Received Data: ${JSON.stringify(data)} with headers: ${JSON.stringify(headers)}`),
    14. );
    15. // Method 2: Direct susbcription with options through the `subscribeWithOptions` method
    16. await server.pubsub.subscribeWithOptions(pubSubName, topic, {
    17. callback: async (data: any, headers: object) =>
    18. console.log(`Received Data: ${JSON.stringify(data)} with headers: ${JSON.stringify(headers)}`),
    19. });
    20. // Method 3: Subscription afterwards through the `susbcribeOnEvent` method
    21. // Note: we use default, since if no route was passed (empty options) we utilize "default" as the route name
    22. await server.pubsub.subscribeWithOptions("pubsub-redis", "topic-options-1", {});
    23. server.pubsub.subscribeToRoute("pubsub-redis", "topic-options-1", "default", async (data: any, headers: object) => {
    24. console.log(`Received Data: ${JSON.stringify(data)} with headers: ${JSON.stringify(headers)}`);
    25. });
    26. // Start the server
    27. await server.start();
    28. }

    Subscribe to messages rule based

    E.g., you are writing an application that needs to handle messages depending on their “type” with Dapr, you can send them to different routes handlerType1 and handlerType2 with the default route being handlerDefault

    Dead Letter Topics

    Dapr supports . This means that when a message fails to be processed, it gets sent to a dead letter queue. E.g., when a message fails to be handled on /my-queue it will be sent to /my-queue-failed. E.g., when a message fails to be handled on /my-queue it will be sent to /my-queue-failed.

    You can use the following options with subscribeWithOptions method:

    • deadletterTopic: Specify a deadletter topic name (note: if none is provided we create one named deadletter)
    • deadletterCallback: The method to trigger as handler for our deadletter

    Implementing Deadletter support in the JS SDK can be done by either

    • Passing the deadletterCallback as an option
    • By subscribing to route manually with subscribeToRoute

    An example is provided below

    1. import { DaprServer } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1"; // Dapr Sidecar Host
    3. const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
    4. const serverHost = "127.0.0.1"; // App Host of this Example Server
    5. const serverPort = "50051"; // App Port of this Example Server "
    6. async function start() {
    7. const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
    8. const pubSubName = "my-pubsub-name";
    9. await server.pubsub.subscribeWithOptions("pubsub-redis", "topic-options-5", {
    10. callback: async (data: any) => {
    11. throw new Error("Triggering Deadletter");
    12. },
    13. deadLetterCallback: async (data: any) => {
    14. console.log("Handling Deadletter message");
    15. },
    16. });
    17. // Method 2 (subscribe afterwards)
    18. await server.pubsub.subscribeWithOptions("pubsub-redis", "topic-options-1", {
    19. deadletterTopic: "my-deadletter-topic",
    20. });
    21. server.pubsub.subscribeToRoute("pubsub-redis", "topic-options-1", "default", async () => {
    22. throw new Error("Triggering Deadletter");
    23. });
    24. server.pubsub.subscribeToRoute("pubsub-redis", "topic-options-1", "my-deadletter-topic", async () => {
    25. console.log("Handling Deadletter message");
    26. });
    27. // Start server
    28. await server.start();
    29. }

    Receive an Input Binding

    1. import { DaprServer } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1";
    3. const daprPort = "3500";
    4. const serverHost = "127.0.0.1";
    5. const serverPort = "5051";
    6. async function start() {
    7. const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
    8. const bindingName = "my-binding-name";
    9. const response = await server.binding.receive(bindingName, async (data: any) =>
    10. console.log(`Got Data: ${JSON.stringify(data)}`),
    11. );
    12. await server.start();
    13. }
    14. start().catch((e) => {
    15. console.error(e);
    16. process.exit(1);
    17. });

    Configuration API

    💡 The configuration API is currently only available through gRPC

    Getting a configuration value

    1. import { DaprServer } from "dapr-client";
    2. const daprHost = "127.0.0.1";
    3. const daprPort = "3500";
    4. const serverHost = "127.0.0.1";
    5. const serverPort = "5051";
    6. async function start() {
    7. const client = new DaprClient(daprHost, daprPort, CommunicationProtocolEnum.GRPC);
    8. const config = await client.configuration.get("config-redis", ["myconfigkey1", "myconfigkey2"]);
    9. }
    10. start().catch((e) => {
    11. console.error(e);
    12. process.exit(1);

    Subscribing to Key Changes