Client

    Pre-requisites

    1. Install the SDK with :
    1. Import the libraries:
    1. import { DaprClient, DaprServer, HttpMethod, 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 client = new DaprClient(daprHost, daprPort);
    8. // GRPC Example
    9. const client = new DaprClient(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 { DaprClient } from "@dapr/dapr";
    2. const client = new DaprClient(daprHost, daprPort);
    1. # Using dapr run
    2. dapr run --app-id example-sdk --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. import { DaprClient, CommunicationProtocol } from "@dapr/dapr";
    2. const client = new DaprClient(daprHost, daprPort, CommunicationProtocol.GRPC);

    By proxying requests, we can utilize the unique capabilities that Dapr brings with its sidecar architecture such as service discovery, logging, etc., enabling us to instantly “upgrade” our gRPC services. This feature of gRPC proxying was demonstrated in community call 41.

    Creating a Proxy

    1. // As always, create a client to our dapr sidecar
    2. // this client takes care of making sure the sidecar is started, that we can communicate, ...
    3. const clientSidecar = new DaprClient(daprHost, daprPort, CommunicationProtocolEnum.GRPC);
    4. // Create a Proxy that allows us to use our gRPC code
    5. const clientProxy = await clientSidecar.proxy.create<GreeterClient>(GreeterClient);

    We can now call the methods as defined in our GreeterClient interface (which in this case is from the Hello World example)

    1. The gRPC service gets started in Dapr. We tell Dapr which port this gRPC server is running on through --app-port and give it a unique Dapr app ID with --app-id <APP_ID_HERE>
    2. We can now call the Dapr Sidecar through a client that will connect to the Sidecar
    3. Whilst calling the Dapr Sidecar, we provide a metadata key named dapr-app-id with the value of our gRPC server booted in Dapr (e.g. server in our example)
    4. Dapr will now forward the call to the gRPC server configured

    Building blocks

    The JavaScript Client SDK allows you to interface with all of the focusing on Client to Sidecar features.

    Invocation API

    Invoke a Service

    1. import { DaprClient, HttpMethod } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1";
    3. const daprPort = "3500";
    4. async function start() {
    5. const client = new DaprClient(daprHost, daprPort);
    6. const serviceAppId = "my-app-id";
    7. const serviceMethod = "say-hello";
    8. // POST Request
    9. const response = await client.invoker.invoke(serviceAppId, serviceMethod, HttpMethod.POST, { hello: "world" });
    10. // POST Request with headers
    11. const response = await client.invoker.invoke(
    12. serviceAppId,
    13. serviceMethod,
    14. HttpMethod.POST,
    15. { hello: "world" },
    16. { headers: { "X-User-ID": "123" } },
    17. );
    18. // GET Request
    19. const response = await client.invoker.invoke(serviceAppId, serviceMethod, HttpMethod.GET);
    20. }
    21. start().catch((e) => {
    22. console.error(e);
    23. process.exit(1);
    24. });

    State Management API

    Save, Get and Delete application state

    1. import { DaprClient } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1";
    3. const daprPort = "3500";
    4. async function start() {
    5. const client = new DaprClient(daprHost, daprPort);
    6. const serviceStoreName = "my-state-store-name";
    7. // Save State
    8. const response = await client.state.save(serviceStoreName, [
    9. {
    10. key: "first-key-name",
    11. value: "hello",
    12. },
    13. {
    14. key: "second-key-name",
    15. value: "world",
    16. },
    17. // Get State
    18. const response = await client.state.get(serviceStoreName, "first-key-name");
    19. // Get Bulk State
    20. const response = await client.state.getBulk(serviceStoreName, ["first-key-name", "second-key-name"]);
    21. // State Transactions
    22. await client.state.transaction(serviceStoreName, [
    23. {
    24. operation: "upsert",
    25. request: {
    26. key: "first-key-name",
    27. value: "new-data",
    28. },
    29. },
    30. {
    31. operation: "delete",
    32. request: {
    33. key: "second-key-name",
    34. },
    35. },
    36. ]);
    37. // Delete State
    38. const response = await client.state.delete(serviceStoreName, "first-key-name");
    39. }
    40. start().catch((e) => {
    41. console.error(e);
    42. process.exit(1);
    43. });

    Query State API

    1. import { DaprClient } from "@dapr/dapr";
    2. async function start() {
    3. const client = new DaprClient(daprHost, daprPort);
    4. const res = await client.state.query("state-mongodb", {
    5. filter: {
    6. OR: [
    7. {
    8. EQ: { "person.org": "Dev Ops" },
    9. },
    10. {
    11. AND: [
    12. {
    13. EQ: { "person.org": "Finance" },
    14. },
    15. {
    16. IN: { state: ["CA", "WA"] },
    17. },
    18. ],
    19. },
    20. ],
    21. },
    22. sort: [
    23. {
    24. key: "state",
    25. order: "DESC",
    26. },
    27. ],
    28. page: {
    29. limit: 10,
    30. },
    31. });
    32. console.log(res);
    33. }
    34. start().catch((e) => {
    35. console.error(e);
    36. process.exit(1);
    37. });

    Publish messages

    Bindings API

    Invoke Output Binding

    Output Bindings

    1. import { DaprClient } from "@dapr/dapr";
    2. const daprPort = "3500";
    3. async function start() {
    4. const client = new DaprClient(daprHost, daprPort);
    5. const bindingName = "my-binding-name";
    6. const bindingOperation = "create";
    7. const message = { hello: "world" };
    8. const response = await client.binding.send(bindingName, bindingOperation, message);
    9. }
    10. start().catch((e) => {
    11. console.error(e);
    12. process.exit(1);
    13. });

    Secret API

    Retrieve secrets

    1. import { DaprClient } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1";
    3. const daprPort = "3500";
    4. async function start() {
    5. const client = new DaprClient(daprHost, daprPort);
    6. const secretStoreName = "my-secret-store";
    7. const secretKey = "secret-key";
    8. // Retrieve a single secret from secret store
    9. const response = await client.secret.get(secretStoreName, secretKey);
    10. // Retrieve all secrets from secret store
    11. const response = await client.secret.getBulk(secretStoreName);
    12. }
    13. start().catch((e) => {
    14. console.error(e);
    15. process.exit(1);
    16. });

    Get Configuration Keys

    1. import { DaprClient } from "@dapr/dapr";
    2. const daprHost = "127.0.0.1";
    3. const daprAppId = "example-config";
    4. async function start() {
    5. const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT);
    6. const config = await client.configuration.get("config-store", ["key1", "key2"]);
    7. console.log(config);
    8. }
    9. start().catch((e) => {
    10. console.error(e);
    11. process.exit(1);
    12. });

    Distributed Lock API

    Try Lock and Unlock APIs

    1. import { CommunicationProtocolEnum, DaprClient } from "@dapr/dapr";
    2. import { LockStatus } from "@dapr/dapr/types/lock/UnlockResponse";
    3. const daprHost = "127.0.0.1";
    4. const daprPortDefault = "3500";
    5. async function start() {
    6. const client = new DaprClient(daprHost, daprPort);
    7. const storeName = "redislock";
    8. const resourceId = "resourceId";
    9. const lockOwner = "owner1";
    10. let expiryInSeconds = 1000;
    11. console.log(`Acquiring lock on ${storeName}, ${resourceId} as owner: ${lockOwner}`);
    12. const tryLockResponse = await client.lock.tryLock(storeName, resourceId, lockOwner, expiryInSeconds);
    13. console.log(tryLockResponse);
    14. console.log(`Unlocking on ${storeName}, ${resourceId} as owner: ${lockOwner}`);
    15. const unlockResponse = await client.lock.unlock(storeName, resourceId, lockOwner);
    16. console.log("Unlock API response: " + getResponseStatus(unlockResponse.status));
    17. }
    18. function getResponseStatus(status: LockStatus) {
    19. switch (status) {
    20. case LockStatus.Success:
    21. return "Success";
    22. case LockStatus.LockDoesNotExist:
    23. return "LockDoesNotExist";
    24. case LockStatus.LockBelongsToOthers:
    25. return "LockBelongsToOthers";
    26. default:
    27. return "InternalError";
    28. }
    29. }
    30. start().catch((e) => {
    31. console.error(e);
    32. process.exit(1);