Dapr 是一個可移植的、事件驅動的執行時,它使任何開發人員能夠輕鬆構建出彈性的、無狀態和有狀態的應用程式,並可執行在雲平臺或邊緣計算中,它同時也支援多種程式語言和開發框架。Dapr 確保開發人員專注於編寫業務邏輯,不必分神解決分散式系統難題,從而顯著提高了生產力。Dapr 降低了構建微服務架構類現代雲原生應用的門檻。
用於在 JavaScript 和 TypeScript 中構建 Dapr 應用程式的使用者端庫。該使用者端抽象了公共 Dapr API,例如服務到服務呼叫、狀態管理、釋出/訂閱、機密等,併為構建應用程式提供了一個簡單、直觀的 API。
要開始使用 Javascript SDK,請從 NPM 安裝 Dapr JavaScript SDK 包:
npm install --save @dapr/dapr
⚠️ dapr-client 現在已棄用。 請參閱#259 瞭解更多資訊。
Dapr Javascript SDK 包含兩個主要元件:
上述通訊可以設定為使用 gRPC 或 HTTP 協定。
Dapr Client 允許您與 Dapr Sidecar 通訊並存取其面向使用者端的功能,例如釋出事件、呼叫輸出繫結、狀態管理、Secret 管理等等。
npm i @dapr/dapr --save
import { DaprClient, DaprServer, HttpMethod, CommunicationProtocolEnum } from "@dapr/dapr";
const daprHost = "127.0.0.1"; // Dapr Sidecar Host
const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
const serverHost = "127.0.0.1"; // App Host of this Example Server
const serverPort = "50051"; // App Port of this Example Server
// HTTP Example
const client = new DaprClient(daprHost, daprPort);
// GRPC Example
const client = new DaprClient(daprHost, daprPort, CommunicationProtocolEnum.GRPC);
要執行範例,您可以使用兩種不同的協定與 Dapr sidecar 互動:HTTP(預設)或 gRPC。
import { DaprClient } from "@dapr/dapr";
const client = new DaprClient(daprHost, daprPort);
# Using dapr run
dapr run --app-id example-sdk --app-protocol http -- npm run start
# or, using npm script
npm run start:dapr-http
由於 HTTP 是預設設定,因此您必須調整通訊協定以使用 gRPC。 您可以通過向用戶端或伺服器建構函式傳遞一個額外的引數來做到這一點。
import { DaprClient, CommunicationProtocol } from "@dapr/dapr";
const client = new DaprClient(daprHost, daprPort, CommunicationProtocol.GRPC);
# Using dapr run
dapr run --app-id example-sdk --app-protocol grpc -- npm run start
# or, using npm script
npm run start:dapr-grpc
通過代理請求,我們可以利用 Dapr 通過其 sidecar 架構帶來的獨特功能,例如服務發現、紀錄檔記錄等,使我們能夠立即「升級」我們的 gRPC 服務。 gRPC 代理的這一特性在community call 41 中得到了展示。
community call 41
要執行 gRPC 代理,只需呼叫 client.proxy.create() 方法建立一個代理:
// As always, create a client to our dapr sidecar
// this client takes care of making sure the sidecar is started, that we can communicate, ...
const clientSidecar = new DaprClient(daprHost, daprPort, CommunicationProtocolEnum.GRPC);
// Create a Proxy that allows us to use our gRPC code
const clientProxy = await clientSidecar.proxy.create<GreeterClient>(GreeterClient);
我們現在可以呼叫 GreeterClient 介面中定義的方法(在本例中來自 Hello World 範例)
--app-port
告訴 Dapr 這個 gRPC 伺服器在哪個埠上執行,並通過 --app-id <APP_ID_HERE>
給它一個唯一的 Dapr 應用 IDdapr-app-id
的後設資料鍵,其中包含在 Dapr 中啟動的 gRPC 伺服器的值(例如,我們範例中的 server
)JavaScript 使用者端 SDK 允許您與專注於 Client to Sidecar 功能的所有 Dapr 構建塊進行互動。
呼叫一個服務
import { DaprClient, HttpMethod } from "@dapr/dapr";
const daprHost = "127.0.0.1";
const daprPort = "3500";
async function start() {
const client = new DaprClient(daprHost, daprPort);
const serviceAppId = "my-app-id";
const serviceMethod = "say-hello";
// POST Request
const response = await client.invoker.invoke(serviceAppId , serviceMethod , HttpMethod.POST, { hello: "world" });
// GET Request
const response = await client.invoker.invoke(serviceAppId , serviceMethod , HttpMethod.GET);
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
有關服務呼叫的完整指南,請存取 How-To: Invoke a service。
儲存、獲取和刪除應用程式狀態
import { DaprClient } from "@dapr/dapr";
const daprHost = "127.0.0.1";
const daprPort = "3500";
async function start() {
const client = new DaprClient(daprHost, daprPort);
const serviceStoreName = "my-state-store-name";
// Save State
const response = await client.state.save(serviceStoreName, [
{
key: "first-key-name",
value: "hello"
},
{
key: "second-key-name",
value: "world"
}
]);
// Get State
const response = await client.state.get(serviceStoreName, "first-key-name");
// Get Bulk State
const response = await client.state.getBulk(serviceStoreName, ["first-key-name", "second-key-name"]);
// State Transactions
await client.state.transaction(serviceStoreName, [
{
operation: "upsert",
request: {
key: "first-key-name",
value: "new-data"
}
},
{
operation: "delete",
request: {
key: "second-key-name"
}
}
]);
// Delete State
const response = await client.state.delete(serviceStoreName, "first-key-name");
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
有關狀態操作的完整列表,請存取 How-To: Get & save state。https://docs.dapr.io/developing-applications/building-blocks/state-management/howto-get-save-state/
import { DaprClient } from "@dapr/dapr";
async function start() {
const client = new DaprClient(daprHost, daprPort);
const res = await client.state.query("state-mongodb", {
filter: {
OR: [
{
EQ: { "person.org": "Dev Ops" }
},
{
"AND": [
{
"EQ": { "person.org": "Finance" }
},
{
"IN": { "state": ["CA", "WA"] }
}
]
}
]
},
sort: [
{
key: "state",
order: "DESC"
}
],
page: {
limit: 10
}
});
console.log(res);
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
釋出訊息
import { DaprClient } from "@dapr/dapr";
const daprHost = "127.0.0.1";
const daprPort = "3500";
async function start() {
const client = new DaprClient(daprHost, daprPort);
const pubSubName = "my-pubsub-name";
const topic = "topic-a";
const message = { hello: "world" }
// Publish Message to Topic
const response = await client.pubsub.publish(pubSubName, topic, message);
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
訂閱訊息
import { DaprServer } from "@dapr/dapr";
const daprHost = "127.0.0.1"; // Dapr Sidecar Host
const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
const serverHost = "127.0.0.1"; // App Host of this Example Server
const serverPort = "50051"; // App Port of this Example Server "
async function start() {
const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
const pubSubName = "my-pubsub-name";
const topic = "topic-a";
// Configure Subscriber for a Topic
await server.pubsub.subscribe(pubSubName, topic, async (data: any) => console.log(`Got Data: ${JSON.stringify(data)}`));
await server.start();
}
有關狀態操作的完整列表,請存取 How-To: Publish and subscribe。https://docs.dapr.io/developing-applications/building-blocks/pubsub/howto-publish-subscribe/
呼叫輸出繫結
import { DaprClient } from "@dapr/dapr";
const daprHost = "127.0.0.1";
const daprPort = "3500";
async function start() {
const client = new DaprClient(daprHost, daprPort);
const bindingName = "my-binding-name";
const bindingOperation = "create";
const message = { hello: "world" };
const response = await client.binding.send(bindingName, bindingOperation, message);
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
有關輸出繫結的完整指南,請存取 How-To: Use bindings。https://docs.dapr.io/developing-applications/building-blocks/bindings/howto-bindings/
檢索 secret
import { DaprClient } from "@dapr/dapr";
const daprHost = "127.0.0.1";
const daprPort = "3500";
async function start() {
const client = new DaprClient(daprHost, daprPort);
const secretStoreName = "my-secret-store";
const secretKey = "secret-key";
// Retrieve a single secret from secret store
const response = await client.secret.get(secretStoreName, secretKey);
// Retrieve all secrets from secret store
const response = await client.secret.getBulk(secretStoreName);
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
有關 secrets 的完整指南,請存取 How-To: Retrieve Secrets。https://docs.dapr.io/developing-applications/building-blocks/secrets/howto-secrets/
獲取設定 key
import { DaprClient } from "@dapr/dapr";
const daprHost = "127.0.0.1";
const daprAppId = "example-config";
async function start() {
const client = new DaprClient(daprHost, process.env.DAPR_HTTP_PORT);
const config = await client.configuration.get('config-store', ['key1', 'key2']);
console.log(config);
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
Dapr Server 將允許您接收來自 Dapr Sidecar 的通訊並存取其面向伺服器的功能,例如:訂閱事件、接收輸入繫結等等。
npm
安裝 SDK:npm i @dapr/dapr --save
import { DaprClient, DaprServer, HttpMethod, CommunicationProtocolEnum } from "@dapr/dapr";
const daprHost = "127.0.0.1"; // Dapr Sidecar Host
const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
const serverHost = "127.0.0.1"; // App Host of this Example Server
const serverPort = "50051"; // App Port of this Example Server
// HTTP Example
const client = new DaprClient(daprHost, daprPort);
// GRPC Example
const client = new DaprClient(daprHost, daprPort, CommunicationProtocolEnum.GRPC);
要執行範例,您可以使用兩種不同的協定與 Dapr sidecar 互動:HTTP(預設)或 gRPC。
import { DaprServer } from "@dapr/dapr";
const server= new DaprServer(appHost, appPort, daprHost, daprPort);
// initialize subscribtions, ... before server start
// the dapr sidecar relies on these
await server.start();
# Using dapr run
dapr run --app-id example-sdk --app-port 50051 --app-protocol http -- npm run start
# or, using npm script
npm run start:dapr-http
ℹ️ Note:這裡需要 app-port,因為這是我們的伺服器需要繫結的地方。 Dapr 將在完成啟動之前檢查應用程式是否繫結到此埠。
由於 HTTP 是預設設定,因此您必須調整通訊協定以使用 gRPC。 您可以通過向用戶端或伺服器建構函式傳遞一個額外的引數來做到這一點。
import { DaprServer, CommunicationProtocol } from "@dapr/dapr";
const server = new DaprServer(appHost, appPort, daprHost, daprPort, CommunicationProtocol.GRPC);
// initialize subscribtions, ... before server start
// the dapr sidecar relies on these
await server.start();
# Using dapr run
dapr run --app-id example-sdk --app-port 50051 --app-protocol grpc -- npm run start
# or, using npm script
npm run start:dapr-grpc
ℹ️ Note:這裡需要 app-port,因為這是我們的伺服器需要繫結的地方。 Dapr 將在完成啟動之前檢查應用程式是否繫結到此埠。
JavaScript Server SDK 允許您與專注於 Sidecar 到 App 功能的所有 Dapr 構建塊進行互動。
監聽呼叫
import { DaprServer } from "@dapr/dapr";
const daprHost = "127.0.0.1"; // Dapr Sidecar Host
const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
const serverHost = "127.0.0.1"; // App Host of this Example Server
const serverPort = "50051"; // App Port of this Example Server "
async function start() {
const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
await server.invoker.listen('hello-world', mock, { method: HttpMethod.GET });
// You can now invoke the service with your app id and method "hello-world"
await server.start();
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
有關服務呼叫的完整指南,請存取 How-To: Invoke a service。
訂閱訊息
import { DaprServer } from "@dapr/dapr";
const daprHost = "127.0.0.1"; // Dapr Sidecar Host
const daprPort = "3500"; // Dapr Sidecar Port of this Example Server
const serverHost = "127.0.0.1"; // App Host of this Example Server
const serverPort = "50051"; // App Port of this Example Server "
async function start() {
const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
const pubSubName = "my-pubsub-name";
const topic = "topic-a";
// Configure Subscriber for a Topic
await server.pubsub.subscribe(pubSubName, topic, async (data: any) => console.log(`Got Data: ${JSON.stringify(data)}`));
await server.start();
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
有關狀態操作的完整列表,請存取 How-To: Publish and subscribe。https://docs.dapr.io/developing-applications/building-blocks/pubsub/howto-publish-subscribe/
接收一個輸入繫結
import { DaprServer } from "@dapr/dapr";
const daprHost = "127.0.0.1";
const daprPort = "3500";
const serverHost = "127.0.0.1";
const serverPort = "5051";
async function start() {
const server = new DaprServer(serverHost, serverPort, daprHost, daprPort);
const bindingName = "my-binding-name";
const response = await server.binding.receive(bindingName, async (data: any) => console.log(`Got Data: ${JSON.stringify(data)}`));
await server.start();
}
start().catch((e) => {
console.error(e);
process.exit(1);
});
有關輸出繫結的完整指南,請存取 How-To: Use bindings。https://docs.dapr.io/developing-applications/building-blocks/bindings/howto-bindings/