Merge branch 'bindings_quickstarts' of https://github.com/nirmash/docs into bindings_quickstarts

This commit is contained in:
Hannah Hunter 2022-06-21 13:54:46 -05:00
commit 2e18103338
15 changed files with 148 additions and 277 deletions

View File

@ -6,8 +6,13 @@ weight: 100
description: "Overview of the Dapr sidecar process"
---
Dapr uses a [sidecar pattern]({{< ref "concepts/overview.md#sidecar-architecture" >}}), meaning the Dapr APIs are run and exposed on a separate process (i.e. the Dapr sidecar) running alongside your application. The Dapr sidecar process is named `daprd` and is launched in different ways depending on the hosting environment.
Dapr uses a [sidecar pattern]({{< ref "concepts/overview.md#sidecar-architecture" >}}), meaning the Dapr APIs are run and exposed on a separate process, the Dapr sidecar, running alongside your application. The Dapr sidecar process is named `daprd` and is launched in different ways depending on the hosting environment.
The Dapr sidecar exposes [building block APIs]({{<ref building-blocks-concept>}}) used by your application business logic, a [metadata API]({{<ref metadata_api>}}) for discoverability of capabiliites and to set attributes and a [health API]({{<ref sidecar-health>}}) to determine health status.
<img src="/images/overview-sidecar-apis.png" width=700>
The sidecar APIs are called from your application over local http or gRPC endpoints.
<img src="/images/overview-sidecar-model.png" width=700>
## Self-hosted with `dapr run`
@ -20,13 +25,13 @@ On [Kubernetes]({{< ref kubernetes.md >}}), the Dapr control plane includes the
## Running the sidecar directly
In most cases you do not need to run `daprd` explicitly, as the sidecar is either launched by the CLI (self-hosted mode) or by the dapr-sidecar-injector service (Kubernetes). For advanced use cases (debugging, scripted deployments, etc.) the `daprd` process can be launched directly.
In most cases you do not need to run `daprd` explicitly, as the sidecar is either launched by the [CLI]({{<ref cli-overview>}}) (self-hosted mode) or by the dapr-sidecar-injector service (Kubernetes). For advanced use cases (debugging, scripted deployments, etc.) the `daprd` process can be launched directly.
For a detailed list of all available arguments run `daprd --help` or see this [table]({{< ref arguments-annotations-overview.md >}}) which outlines how the `daprd` arguments relate to the CLI arguments and Kubernetes annotations.
### Examples
1. Start a sidecar along an application by specifying its unique ID. Note `--app-id` is a required field:
1. Start a sidecar along with an application by specifying its unique ID. Note `--app-id` is a required field:
```bash
daprd --app-id myapp

View File

@ -6,31 +6,28 @@ description: "Invoke external systems with output bindings"
weight: 300
---
Output bindings enable you to invoke external resources without taking dependencies on special SDK or libraries.
For a complete sample showing output bindings, visit this [link](https://github.com/dapr/quickstarts/tree/master/tutorials/bindings).
## Example:
The below code example loosely describes an application that processes orders. In the example, there is an order processing service which has a Dapr sidecar. The order processing service uses Dapr to invoke external resources, in this case a Kafka, via an output binding.
With output bindings, you can invoke external resources without depending on special SDK or libraries. An output binding represents a resource that Dapr uses to invoke and send messages to. For a complete sample showing output bindings, [walk through the tutorial](https://github.com/dapr/quickstarts/tree/master/tutorials/bindings).
<img src="/images/building-block-output-binding-example.png" width=1000 alt="Diagram showing bindings of example service">
## 1. Create a binding
This guide uses a Kafka binding as an example. You can find your preferred binding spec from [the list of bindings components]({{< ref setup-bindings >}}).
An output binding represents a resource that Dapr uses to invoke and send messages to.
For the purpose of this guide, you'll use a Kafka binding. You can find a list of the different binding specs [here]({{< ref setup-bindings >}}).
## Create a binding
Create a new binding component with the name of `checkout`.
Inside the `metadata` section, configure Kafka related properties such as the topic to publish the message to and the broker.
Within the `metadata` section, configure Kafka-related properties, such as:
- The topic to which you'll publish the message
- The broker
Create the following `binding.yaml` file and save to a `components` sub-folder in your application directory.
{{< tabs "Self-Hosted (CLI)" Kubernetes >}}
{{% codetab %}}
Create the following YAML file, named `binding.yaml`, and save this to a `components` sub-folder in your application directory.
(Use the `--components-path` flag with `dapr run` to point to your custom components dir)
Use the `--components-path` flag with `dapr run` to point to your custom components directory.
```yaml
apiVersion: dapr.io/v1alpha1
@ -60,8 +57,7 @@ spec:
{{% codetab %}}
To deploy this into a Kubernetes cluster, fill in the `metadata` connection details of your [desired binding component]({{< ref setup-bindings >}}) in the yaml below (in this case kafka), save as `binding.yaml`, and run `kubectl apply -f binding.yaml`.
To deploy the following `binding.yaml` file into a Kubernetes cluster, run `kubectl apply -f binding.yaml`.
```yaml
apiVersion: dapr.io/v1alpha1
@ -91,7 +87,7 @@ spec:
{{< /tabs >}}
## 2. Send an event (Output binding)
## Send an event (output binding)
Below are code examples that leverage Dapr SDKs to interact with an output binding.
@ -135,12 +131,6 @@ namespace EventService
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --app-ssl dotnet run
```
{{% /codetab %}}
{{% codetab %}}
@ -179,12 +169,6 @@ public class OrderProcessingServiceApplication {
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 mvn spring-boot:run
```
{{% /codetab %}}
{{% codetab %}}
@ -213,12 +197,6 @@ while True:
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --app-protocol grpc python3 OrderProcessingService.py
```
{{% /codetab %}}
{{% codetab %}}
@ -257,12 +235,6 @@ func main() {
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 go run OrderProcessingService.go
```
{{% /codetab %}}
{{% codetab %}}
@ -301,17 +273,11 @@ function sleep(ms) {
}
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 npm start
```
{{% /codetab %}}
{{< /tabs >}}
All that's left now is to invoke the output bindings endpoint on a running Dapr instance.
Invoke the output bindings endpoint on a running Dapr instance.
You can also invoke the output bindings endpoint using HTTP:
@ -319,11 +285,13 @@ You can also invoke the output bindings endpoint using HTTP:
curl -X POST -H 'Content-Type: application/json' http://localhost:3601/v1.0/bindings/checkout -d '{ "data": 100, "operation": "create" }'
```
As seen above, you invoked the `/binding` endpoint with the name of the binding to invoke, in our case its `checkout`.
The payload goes inside the mandatory `data` field, and can be any JSON serializable value.
As seen above:
You'll also notice that there's an `operation` field that tells the binding what you need it to do.
You can check [here]({{< ref supported-bindings >}}) which operations are supported for every output binding.
1. The example invoked the `/binding` endpoint with `checkout`, the name of the binding to invoke.
1. The payload goes inside the mandatory `data` field, and can be any JSON serializable value.
1. The `operation` field tells the binding what action it needs to take. For example, [the Kafka binding supports the `create` operation]({{< ref "kafka.md#binding-support" >}}).
You can check [which operations (specific to each component) are supported for every output binding]({{< ref supported-bindings >}}).
Watch this [video](https://www.youtube.com/watch?v=ysklxm81MTs&feature=youtu.be&t=1960) on how to use bi-directional output bindings.

View File

@ -8,7 +8,7 @@ weight: 200
Using bindings, your code can be triggered with incoming events from different resources which can be anything: a queue, messaging pipeline, cloud-service, filesystem etc.
This is ideal for event-driven processing, data pipelines or just generally reacting to events and doing further processing.
This is ideal for event-driven processing, data pipelines, or generally reacting to events and performing further processing.
Dapr bindings allow you to:
@ -16,30 +16,25 @@ Dapr bindings allow you to:
* Replace bindings without changing your code
* Focus on business logic and not the event resource implementation
For more info on bindings, read [this overview]({{<ref bindings-overview.md>}}).
## Example:
The below code example loosely describes an application that processes orders. In the example, there is an order processing service which has a Dapr sidecar. The checkout service uses Dapr to trigger the application via an input binding.
An input binding represents a resource that Dapr uses to read events from and push to your application. Read the [bindings overview for more information]({{<ref bindings-overview.md>}}).
<img src="/images/building-block-input-binding-example.png" width=1000 alt="Diagram showing bindings of example service">
## 1. Create a binding
This guide uses a Kafka binding as an example. You can find your preferred binding spec from [the list of bindings components]({{< ref setup-bindings >}}).
An input binding represents a resource that Dapr uses to read events from and push to your application.
For the purpose of this guide, you'll use a Kafka binding. You can find a list of supported binding components [here]({{< ref setup-bindings >}}).
## Create a binding
Create a new binding component with the name of `checkout`.
Inside the `metadata` section, configure Kafka related properties, such as the topic to publish the message to and the broker.
Inside the `metadata` section, configure Kafka-related properties, such as the topic to publish the message to and the broker.
Create the following `binding.yaml` file and save it to a `components` sub-folder in your application directory.
{{< tabs "Self-Hosted (CLI)" Kubernetes >}}
{{% codetab %}}
Create the following YAML file, named `binding.yaml`, and save this to a `components` sub-folder in your application directory.
(Use the `--components-path` flag with `dapr run` to point to your custom components dir)
Use the `--components-path` flag with the `dapr run` command to point to your custom components directory.
```yaml
apiVersion: dapr.io/v1alpha1
@ -69,8 +64,7 @@ spec:
{{% codetab %}}
To deploy this into a Kubernetes cluster, fill in the `metadata` connection details of your [desired binding component]({{< ref setup-bindings >}}) in the yaml below (in this case kafka), save as `binding.yaml`, and run `kubectl apply -f binding.yaml`.
To deploy into a Kubernetes cluster, run `kubectl apply -f binding.yaml`.
```yaml
apiVersion: dapr.io/v1alpha1
@ -100,13 +94,13 @@ spec:
{{< /tabs >}}
## 2. Listen for incoming events (input binding)
## Listen for incoming events (input binding)
Now configure your application to receive incoming events. If using HTTP, you need to listen on a `POST` endpoint with the name of the binding as specified in `metadata.name` in the file.
Configure your application to receive incoming events. If using HTTP, you need to listen on a `POST` endpoint with the name of the binding, as specified in `metadata.name` in the `binding.yaml` file.
Below are code examples that leverage Dapr SDKs to demonstrate an output binding.
{{< tabs Dotnet Java Python Go JavaScript>}}
{{< tabs Dotnet Java Python Go Javascript>}}
{{% codetab %}}
@ -134,12 +128,6 @@ namespace CheckoutService.controller
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 --app-ssl dotnet run
```
{{% /codetab %}}
{{% codetab %}}
@ -165,12 +153,6 @@ public class CheckoutServiceController {
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 mvn spring-boot:run
```
{{% /codetab %}}
{{% codetab %}}
@ -192,12 +174,6 @@ app.run(6002)
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --app-protocol grpc -- python3 CheckoutService.py
```
{{% /codetab %}}
{{% codetab %}}
@ -232,12 +208,6 @@ func main() {
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 go run CheckoutService.go
```
{{% /codetab %}}
{{% codetab %}}
@ -265,28 +235,22 @@ async function start() {
```
Navigate to the directory containing the above code, then run the following command to launch a Dapr sidecar and run the application:
```bash
dapr run --app-id checkout --app-port 6002 --dapr-http-port 3602 --dapr-grpc-port 60002 dotnet npm start
```
{{% /codetab %}}
{{< /tabs >}}
### ACK-ing an event
In order to tell Dapr that you successfully processed an event in your application, return a `200 OK` response from your HTTP handler.
Tell Dapr you've successfully processed an event in your application by returning a `200 OK` response from your HTTP handler.
### Rejecting an event
In order to tell Dapr that the event was not processed correctly in your application and schedule it for redelivery, return any response other than `200 OK`. For example, a `500 Error`.
Tell Dapr the event was not processed correctly in your application and schedule it for redelivery by returning any response other than `200 OK`. For example, a `500 Error`.
### Specifying a custom route
By default, incoming events will be sent to an HTTP endpoint that corresponds to the name of the input binding.
You can override this by setting the following metadata property:
You can override this by setting the following metadata property in `binding.yaml`:
```yaml
name: mybinding
@ -298,6 +262,7 @@ spec:
```
### Event delivery Guarantees
Event delivery guarantees are controlled by the binding implementation. Depending on the binding implementation, the event delivery can be exactly once or at least once.
## References
@ -305,4 +270,4 @@ Event delivery guarantees are controlled by the binding implementation. Dependin
* [Bindings building block]({{< ref bindings >}})
* [Bindings API]({{< ref bindings_api.md >}})
* [Components concept]({{< ref components-concept.md >}})
* [Supported bindings]({{< ref supported-bindings >}})
* [Supported bindings]({{< ref supported-bindings >}})

View File

@ -6,22 +6,21 @@ weight: 2000
description: "Learn how to get application configuration and subscribe for changes"
---
## Introduction
This HowTo uses the Redis configuration store component as an example on how to retrieve a configuration item.
This example uses the Redis configuration store component to demonstrate how to retrieve a configuration item.
*This API is currently in `Alpha` state and only available on gRPC. An HTTP1.1 supported version with this URL syntax `/v1.0/configuration` will be available before the API is certified into `Stable` state.*
{{% alert title="Note" color="primary" %}}
This API is currently in `Alpha` state and only available on gRPC. An HTTP1.1 supported version with this URL syntax `/v1.0/configuration` will be available before the API is certified into `Stable` state.
## Example:
The below code examples loosely describe an application that processes orders. In the examples, there is an order processing service which has a Dapr sidecar. The order processing service uses Dapr to retrieve the configuration from a Redis configuration store.
{{% /alert %}}
<img src="/images/building-block-configuration-example.png" width=1000 alt="Diagram showing get configuration of example service">
## Step 1: Create a configuration item in store
## Create a configuration item in store
First, create a configuration item in a supported configuration store. This can be a simple key-value item, with any key of your choice. For this example, we'll use the Redis configuration store component.
Create a configuration item in a supported configuration store. This can be a simple key-value item, with any key of your choice. As mentioned earlier, this example uses the Redis configuration store component.
### Run Redis with Docker
```
docker run --name my-redis -p 6379:6379 -d redis
```
@ -42,7 +41,15 @@ MSET orderId1 "101||1" orderId2 "102||1"
### Configure a Dapr configuration store
Save the following component file, for example to the [default components folder]({{<ref "install-dapr-selfhost.md#step-5-verify-components-directory-has-been-initialized">}}) on your machine. You can use this as the Dapr component YAML for Kubernetes using `kubectl` or when running with the Dapr CLI. Note: The Redis configuration component has identical metadata to the Redis state store component, so you can simply copy and change the Redis state store component type if you already have a Redis state store YAML file.
Save the following component file to the [default components folder]({{< ref "install-dapr-selfhost.md#step-5-verify-components-directory-has-been-initialized" >}}) on your machine. You can use this as the Dapr component YAML:
- For Kubernetes using `kubectl`.
- When running with the Dapr CLI.
{{% alert title="Note" color="primary" %}}
Since the Redis configuration component has identical metadata to the Redis `statestore.yaml` component, you can simply copy/change the Redis state store component type if you already have a Redis `statestore.yaml`.
{{% /alert %}}
```yaml
apiVersion: dapr.io/v1alpha1
@ -63,6 +70,7 @@ spec:
{{< tabs Dotnet Java Python>}}
{{% codetab %}}
```csharp
//dependencies
using System;
@ -88,14 +96,10 @@ namespace ConfigurationApi
}
```
Navigate to the directory containing the above code and run the following command to launch the application along with a Dapr sidecar:
```bash
dapr run --app-id orderprocessing --components-path ./components -- dotnet run
```
{{% /codetab %}}
{{% codetab %}}
```java
//dependencies
import io.dapr.client.DaprClientBuilder;
@ -125,14 +129,10 @@ public static void main(String[] args) throws Exception {
}
```
Navigate to the directory containing the above code and run the following command to launch the application along with a Dapr sidecar:
```bash
dapr run --app-id orderprocessing --components-path ./components mvn spring-boot:run
```
{{% /codetab %}}
{{% codetab %}}
```python
#dependencies
from dapr.clients import DaprClient
@ -146,12 +146,6 @@ with DaprClient() as d:
print(f"Got key={configuration.items[0].key} value={configuration.items[0].value} version={configuration.items[0].version}")
```
Navigate to the directory containing the above code and run the following command to launch the application along with a Dapr sidecar:
```bash
dapr run --app-id orderprocessing --components-path ./components python3 OrderProcessingService.py
```
{{% /codetab %}}
{{< /tabs >}}
@ -163,37 +157,45 @@ Using your [favorite language](https://grpc.io/docs/languages/), create a Dapr g
{{< tabs Java Dotnet Python Javascript >}}
{{% codetab %}}
```java
Dapr.ServiceBlockingStub stub = Dapr.newBlockingStub(channel);
stub.GetConfigurationAlpha1(new GetConfigurationRequest{ StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} });
```
{{% /codetab %}}
{{% codetab %}}
```csharp
var call = client.GetConfigurationAlpha1(new GetConfigurationRequest { StoreName = "redisconfigstore", Keys = new String[]{"myconfig"} });
```
{{% /codetab %}}
{{% codetab %}}
```python
response = stub.GetConfigurationAlpha1(request={ StoreName: 'redisconfigstore', Keys = ['myconfig'] })
```
{{% /codetab %}}
{{% codetab %}}
```javascript
client.GetConfigurationAlpha1({ StoreName: 'redisconfigstore', Keys = ['myconfig'] })
```
{{% /codetab %}}
{{< /tabs >}}
##### Watch configuration items
#### Watch configuration items
Create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto) using your [preferred language](https://grpc.io/docs/languages/). Then use the proto method `SubscribeConfigurationAlpha1` on your client stub to start subscribing to events. The method accepts the following request object:
Create a Dapr gRPC client from the [Dapr proto](https://github.com/dapr/dapr/blob/master/dapr/proto/runtime/v1/dapr.proto) using your [preferred language](https://grpc.io/docs/languages/). Use the `SubscribeConfigurationAlpha1` proto method on your client stub to start subscribing to events. The method accepts the following request object:
```proto
message SubscribeConfigurationRequest {
@ -210,45 +212,11 @@ message SubscribeConfigurationRequest {
}
```
Using this method, you can subscribe to changes in specific keys for a given configuration store. gRPC streaming varies widely based on language - see the [gRPC examples here](https://grpc.io/docs/languages/) for usage.
Using this method, you can subscribe to changes in specific keys for a given configuration store. gRPC streaming varies widely based on language. [See the gRPC examples](https://grpc.io/docs/languages/) for usage.
Below are the examples in sdks:
#### Stop watching configuration items
{{< tabs Python>}}
{{% codetab %}}
```python
#dependencies
import asyncio
from dapr.clients import DaprClient
#code
async def executeConfiguration():
with DaprClient() as d:
CONFIG_STORE_NAME = 'configstore'
key = 'orderId'
# Subscribe to configuration by key.
configuration = await d.subscribe_configuration(store_name=CONFIG_STORE_NAME, keys=[key], config_metadata={})
if configuration != None:
items = configuration.get_items()
for item in items:
print(f"Subscribe key={item.key} value={item.value} version={item.version}", flush=True)
else:
print("Nothing yet")
asyncio.run(executeConfiguration())
```
```bash
dapr run --app-id orderprocessing --components-path components/ -- python3 OrderProcessingService.py
```
{{% /codetab %}}
{{< /tabs >}}
##### Stop watching configuration items
After you have subscribed to watch configuration items, the gRPC-server stream starts. This stream thread does not close itself, and you have to do by explicitly call the `UnSubscribeConfigurationRequest` API. This method accepts the following request object:
After you've subscribed to watch configuration items, the gRPC-server stream starts. Since this stream thread does not close itself, you have to explicitly call the `UnSubscribeConfigurationRequest` API to unsubscribe. This method accepts the following request object:
```proto
// UnSubscribeConfigurationRequest is the message to stop watching the key-value configuration.
@ -265,4 +233,5 @@ message UnSubscribeConfigurationRequest {
Using this unsubscribe method, you can stop watching configuration update events. Dapr locates the subscription stream based on the `store_name` and any optional keys supplied and closes it.
## Next steps
* Read [configuration API overview]({{< ref configuration-api-overview.md >}})
* Read [configuration API overview]({{< ref configuration-api-overview.md >}})

View File

@ -3,7 +3,7 @@ type: docs
title: "Declarative and programmatic subscription methods"
linkTitle: "Subscription methods"
weight: 3000
description: "Learn more about the two methods by which Dapr allows you to subscribe to topics."
description: "Learn more about the methods by which Dapr allows you to subscribe to topics."
---
## Pub/sub API subscription methods
@ -13,7 +13,7 @@ Dapr applications can subscribe to published topics via two methods that support
| Subscription method | Description |
| ------------------- | ----------- |
| [**Declarative**]({{< ref "subscription-methods.md#declarative-subscriptions" >}}) | Subscription is defined in an **external file**. The declarative approach removes the Dapr dependency from your code and allows for existing applications to subscribe to topics, without having to change code. |
| [**Programmatic**]({{< ref "subscription-methods.md#programmatic-subscriptions" >}}) | Subscription is defined in the **user code**. The programmatic approach implements the subscription in your code. |
| [**Programmatic**]({{< ref "subscription-methods.md#programmatic-subscriptions" >}}) | Subscription is defined in the **application code**. The programmatic approach implements the subscription in your code. |
The examples below demonstrate pub/sub messaging between a `checkout` app and an `orderprocessing` app via the `orders` topic. The examples demonstrate the same Dapr pub/sub component used first declaratively, then programmatically.
@ -25,21 +25,22 @@ You can subscribe declaratively to a topic using an external component file. Thi
apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:
name: order_pub_sub
name: order
spec:
topic: orders
route: /checkout
pubsubname: order_pub_sub
pubsubname: pubsub
scopes:
- orderprocessing
- checkout
```
Notice, the pub/sub component `order_pub_sub` subscribes to topic `orders`.
- The `route` field tells Dapr to send all topic messages to the `/checkout` endpoint in the app.
- The `scopes` field enables this subscription for apps with IDs `orderprocessing` and `checkout`.
Here the subscription called `order`:
- Uses the pub/sub component called `pubsub` to subscribes to the topic called `orders`.
- Sets the `route` field to send all topic messages to the `/checkout` endpoint in the app.
- Sets `scopes` field to scope this subscription for access only by apps with IDs `orderprocessing` and `checkout`.
When running Dapr, call out the YAML component file path to point Dapr to the component.
When running Dapr, set the YAML component file path to point Dapr to the component.
{{< tabs ".NET" Java Python JavaScript Go Kubernetes>}}
@ -103,7 +104,7 @@ In your application code, subscribe to the topic specified in the Dapr pub/sub c
```csharp
//Subscribe to a topic
[Topic("order_pub_sub", "orders")]
[Topic("pubsub", "orders")]
[HttpPost("checkout")]
public void getCheckout([FromBody] int orderId)
{
@ -117,7 +118,7 @@ public void getCheckout([FromBody] int orderId)
```java
//Subscribe to a topic
@Topic(name = "orders", pubsubName = "order_pub_sub")
@Topic(name = "orders", pubsubName = "pubsub")
@PostMapping(path = "/checkout")
public Mono<Void> getCheckout(@RequestBody(required = false) CloudEvent<String> cloudEvent) {
return Mono.fromRunnable(() -> {
@ -136,7 +137,7 @@ public Mono<Void> getCheckout(@RequestBody(required = false) CloudEvent<String>
```python
#Subscribe to a topic
@app.subscribe(pubsub_name='order_pub_sub', topic='orders')
@app.subscribe(pubsub_name='pubsub', topic='orders')
def mytopic(event: v1.Event) -> None:
data = json.loads(event.Data())
logging.info('Subscriber received: ' + str(data))
@ -150,7 +151,7 @@ app.run(6002)
```javascript
//Subscribe to a topic
await server.pubsub.subscribe("order_pub_sub", "orders", async (orderId) => {
await server.pubsub.subscribe("pubsub", "orders", async (orderId) => {
console.log(`Subscriber received: ${JSON.stringify(orderId)}`)
});
await server.startServer();
@ -179,18 +180,18 @@ func eventHandler(ctx context.Context, e *common.TopicEvent) (retry bool, err er
{{< /tabs >}}
The `/checkout` endpoint matches the `route` defined in the subscriptions and this is where Dapr will send all topic messages to.
The `/checkout` endpoint matches the `route` defined in the subscriptions and this is where Dapr sends all topic messages to.
### Programmatic subscriptions
The programmatic approach returns the `routes` JSON structure within the code, unlike the declarative approach's `route` YAML structure. In the example below, we define the values found in the [declarative YAML subscription](#declarative-subscriptions) above within the application code.
The programmatic approach returns the `routes` JSON structure within the code, unlike the declarative approach's `route` YAML structure. In the example below, you define the values found in the [declarative YAML subscription](#declarative-subscriptions) above within the application code.
{{< tabs ".NET" Java Python JavaScript Go>}}
{{% codetab %}}
```csharp
[Topic("order_pub_sub", "checkout", event.type ==\"order\"")]
[Topic("pubsub", "checkout", event.type ==\"order\"")]
[HttpPost("orders")]
public async Task<ActionResult<Stock>> HandleCheckout(Checkout checkout, [FromServices] DaprClient daprClient)
{
@ -206,7 +207,7 @@ public async Task<ActionResult<Stock>> HandleCheckout(Checkout checkout, [FromSe
```java
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
@Topic(name = "checkout", pubsubName = "order_pub_sub")
@Topic(name = "checkout", pubsubName = "pubsub")
@PostMapping(path = "/orders")
public Mono<Void> handleMessage(@RequestBody(required = false) CloudEvent<String> cloudEvent) {
return Mono.fromRunnable(() -> {
@ -228,7 +229,7 @@ public Mono<Void> handleMessage(@RequestBody(required = false) CloudEvent<String
def subscribe():
subscriptions = [
{
'pubsubname': 'order_pub_sub',
'pubsubname': 'pubsub',
'topic': 'checkout',
'routes': {
'rules': [
@ -264,7 +265,7 @@ const port = 3000
app.get('/dapr/subscribe', (req, res) => {
res.json([
{
pubsubname: "order_pub_sub",
pubsubname: "pubsub",
topic: "checkout",
routes: {
rules: [
@ -325,7 +326,7 @@ type rule struct {
func configureSubscribeHandler(w http.ResponseWriter, _ *http.Request) {
t := []subscription{
{
PubsubName: "order_pub_sub",
PubsubName: "pubsub",
Topic: "checkout",
Routes: routes{
Rules: []rule{

View File

@ -6,25 +6,16 @@ weight: 2000
description: "Use the secret store building block to securely retrieve a secret"
---
This article provides guidance on using Dapr's secrets API in your code to leverage the [secrets store building block]({{<ref secrets-overview>}}). The secrets API allows you to easily retrieve secrets in your application code from a configured secret store.
{{% alert title="Note" color="primary" %}}
If you haven't already, [try out the secrets management quickstart]({{< ref secrets-quickstart.md >}}) for a quick walk-through on how to retrieve a secret.
{{% /alert %}}
## Example
The below code example loosely describes an application that processes orders. In the example, there is an order processing service, which has a Dapr sidecar. The order processing service uses Dapr to store a secret in a local secret store.
This guide demonstrates how to use Dapr's secrets API in your code to leverage the [secrets store building block]({{< ref secrets-overview >}}). With the secrets API, you easily retrieve secrets in your application code from a configured secret store.
<img src="/images/building-block-secrets-management-example.png" width=1000 alt="Diagram showing secrets management of example service">
## Set up a secret store
Before retrieving secrets in your application's code, you must have a secret store component configured. For the purposes of this guide, as an example you will configure a local secret store which uses a local JSON file to store secrets.
Before retrieving secrets in your application's code, you must configure a secret store component. This example configures a local secret store which uses a local JSON file to store secrets.
{{% alert title="Warning" color="warning" %}}
In a production-grade application, local secret stores are not recommended. You can find other alternatives [here]({{<ref supported-secret-stores >}}) to securely manage your secrets.
In a production-grade application, local secret stores are not recommended. [Find alternatives]({{< ref supported-secret-stores >}}) to securely manage your secrets.
{{% /alert %}}
Create a file named `secrets.json` with the following contents:
@ -53,58 +44,21 @@ spec:
value: ":"
```
>Note: the path to the secret store JSON is relative to where you call `dapr run` from.
{{% alert title="Warning" color="warning" %}}
The path to the secret store JSON is relative to where you call `dapr run` from.
{{% /alert %}}
For more information, see how to [configure a different kind of secret store]({{< ref setup-secret-store >}}) and review [supported secret stores]({{< ref supported-secret-stores >}}) to see specific details required for different secret store solutions.
To configure a different kind of secret store see the guidance on [how to configure a secret store]({{<ref setup-secret-store>}}) and review [supported secret stores]({{<ref supported-secret-stores >}}) to see specific details required for different secret store solutions.
## Get a secret
Run the Dapr sidecar with the application.
{{< tabs Dotnet Java Python Go Javascript>}}
{{% codetab %}}
```bash
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components dotnet run
```
{{% /codetab %}}
{{% codetab %}}
```bash
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components mvn spring-boot:run
```
{{% /codetab %}}
{{% codetab %}}
```bash
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components python3 OrderProcessingService.py
```
{{% /codetab %}}
{{% codetab %}}
```bash
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components go run OrderProcessingService.go
```
{{% /codetab %}}
{{% codetab %}}
```bash
dapr run --app-id orderprocessingservice --app-port 6001 --dapr-http-port 3601 --dapr-grpc-port 60001 --components-path ./components npm start
```
{{% /codetab %}}
{{< /tabs >}}
Get the secret by calling the Dapr sidecar using the secrets API:
```bash
curl http://localhost:3601/v1.0/secrets/localsecretstore/secret
```
For a full API reference, go [here]({{< ref secrets_api.md >}}).
See a [full API reference]({{< ref secrets_api.md >}}).
## Calling the secrets API from your code
@ -113,6 +67,7 @@ Once you have a secret store, call Dapr to get the secrets from your application
{{< tabs Dotnet Java Python Go Javascript>}}
{{% codetab %}}
```csharp
//dependencies
using System;
@ -141,6 +96,7 @@ namespace EventService
}
}
```
{{% /codetab %}}
{{% codetab %}}
@ -174,6 +130,7 @@ public class OrderProcessingServiceApplication {
}
}
```
{{% /codetab %}}
{{% codetab %}}
@ -203,6 +160,7 @@ with DaprClient() as client:
logging.info('Result for bulk secret: ')
logging.info(sorted(secret.secrets.items()))
```
{{% /codetab %}}
{{% codetab %}}
@ -240,6 +198,7 @@ func main() {
}
}
```
{{% /codetab %}}
{{% codetab %}}
@ -264,6 +223,7 @@ async function main() {
main();
```
{{% /codetab %}}
{{< /tabs >}}
@ -275,4 +235,4 @@ main();
- [Configure a secret store]({{<ref setup-secret-store>}})
- [Supported secrets]({{<ref supported-secret-stores>}})
- [Using secrets in components]({{<ref component-secrets>}})
- [Secret stores quickstart](https://github.com/dapr/quickstarts/tree/master/tutorials/secretstore)
- [Secret stores tutorial](https://github.com/dapr/quickstarts/tree/master/tutorials/secretstore)

View File

@ -54,7 +54,7 @@ For more information read [referencing secret stores in components]({{< ref comp
To provide more granular control on access to secrets, Dapr provides the ability to define scopes and restricting access permissions. Learn more about [using secret scoping]({{<ref secrets-scopes>}})
## Try out service management
## Try out secrets management
### Quickstarts and tutorials
@ -67,6 +67,4 @@ Want to put the Dapr secrets management API to the test? Walk through the follow
### Start managing secrets directly in your app
Want to skip the quickstarts? Not a problem. You can try out the secret management building block directly in your application to retrieve and manage secrets. After [Dapr is installed]({{< ref "getting-started/_index.md" >}}), you can begin using the secrets management API starting with [the secrets how-to guide]({{< ref howto-secrets.md >}}).
Want to skip the quickstarts? Not a problem. You can try out the secret management building block directly in your application to retrieve and manage secrets. After [Dapr is installed]({{< ref "getting-started/_index.md" >}}), you can begin using the secrets management API starting with [the secrets how-to guide]({{< ref howto-secrets.md >}}).

View File

@ -6,22 +6,18 @@ description: "Call between services using service invocation"
weight: 2000
---
This article describe how to deploy services each with an unique application ID, so that other services can discover and call endpoints on them using service invocation API.
## Example:
The below code examples loosely describes an application that processes orders. In the examples, there are two services - an order processing service and a checkout service. Both services have Dapr sidecars and the order processing service uses Dapr to invoke the checkout method in the checkout service.
This article demonstrates how to deploy services each with an unique application ID for other services to discover and call endpoints on them using service invocation over HTTP.
<img src="/images/building-block-service-invocation-example.png" width=1000 height=500 alt="Diagram showing service invocation of example service">
## Step 1: Choose an ID for your service
For a complete sample demonstrating service invocation, [walk through the service invocation quickstart](https://github.com/dapr/quickstarts/tree/master/service_invocation).
## Choose an ID for your service
Dapr allows you to assign a global, unique ID for your app. This ID encapsulates the state for your application, regardless of the number of instances it may have.
{{< tabs Dotnet Java Python Go Javascript Kubernetes>}}
{{% codetab %}}
```bash
@ -88,7 +84,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```bash
@ -111,7 +106,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
```bash
@ -134,7 +128,6 @@ dapr run --app-id orderprocessing --app-port 6001 --dapr-http-port 3601 --dapr-g
{{% /codetab %}}
{{% codetab %}}
### Set an app-id when deploying to Kubernetes
@ -164,24 +157,23 @@ spec:
dapr.io/app-port: "6001"
...
```
*If your app uses an SSL connection, you can tell Dapr to invoke your app over an insecure SSL connection with the `app-ssl: "true"` annotation (full list [here]({{< ref arguments-annotations-overview.md >}}))*
{{% /codetab %}}
{{< /tabs >}}
## Step 2: Invoke the service
## Invoke the service
To invoke an application using Dapr, you can use the `invoke` API on any Dapr instance.
The sidecar programming model encourages each application to interact with its own instance of Dapr. The Dapr sidecars discover and communicate with one another.
To invoke an application using Dapr, you can use the `invoke` API on any Dapr instance. The sidecar programming model encourages each application to interact with its own instance of Dapr. The Dapr sidecars discover and communicate with one another.
Below are code examples that leverage Dapr SDKs for service invocation.
{{< tabs Dotnet Java Python Go Javascript>}}
{{% codetab %}}
```csharp
//dependencies
using System;
@ -217,10 +209,11 @@ namespace EventService
}
}
```
{{% /codetab %}}
{{% codetab %}}
```java
//dependencies
import io.dapr.client.DaprClient;
@ -258,9 +251,11 @@ public class OrderProcessingServiceApplication {
}
}
```
{{% /codetab %}}
{{% codetab %}}
```python
#dependencies
import random
@ -285,9 +280,11 @@ while True:
logging.info('Order requested: ' + str(orderId))
logging.info('Result: ' + str(result))
```
{{% /codetab %}}
{{% codetab %}}
```go
//dependencies
import (
@ -324,9 +321,11 @@ func main() {
}
}
```
{{% /codetab %}}
{{% codetab %}}
```javascript
//dependencies
import { DaprClient, HttpMethod, CommunicationProtocolEnum } from 'dapr-client';
@ -359,6 +358,7 @@ function sleep(ms) {
main();
```
{{% /codetab %}}
{{< /tabs >}}
@ -366,17 +366,18 @@ main();
### Additional URL formats
To invoke a 'GET' endpoint:
```bash
curl http://localhost:3602/v1.0/invoke/checkout/method/checkout/100
```
In order to avoid changing URL paths as much as possible, Dapr provides the following ways to call the service invocation API:
To avoid changing URL paths as much as possible, Dapr provides the following ways to call the service invocation API:
1. Change the address in the URL to `localhost:<dapr-http-port>`.
2. Add a `dapr-app-id` header to specify the ID of the target service, or alternatively pass the ID via HTTP Basic Auth: `http://dapr-app-id:<service-id>@localhost:3602/path`.
For example, the following command
For example, the following command:
```bash
curl http://localhost:3602/v1.0/invoke/checkout/method/checkout/100
```
@ -403,7 +404,7 @@ dapr invoke --app-id checkout --method checkout/100
When running on [namespace supported platforms]({{< ref "service_invocation_api.md#namespace-supported-platforms" >}}), you include the namespace of the target app in the app ID: `checkout.production`
For example, invoking the example service with a namespace would be:
For example, invoking the example service with a namespace would look like:
```bash
curl http://localhost:3602/v1.0/invoke/checkout.production/method/checkout/100 -X POST
@ -411,13 +412,17 @@ curl http://localhost:3602/v1.0/invoke/checkout.production/method/checkout/100 -
See the [Cross namespace API spec]({{< ref "service_invocation_api.md#cross-namespace-invocation" >}}) for more information on namespaces.
## Step 3: View traces and logs
## View traces and logs
The example above showed you how to directly invoke a different service running locally or in Kubernetes. Dapr outputs metrics, tracing and logging information allowing you to visualize a call graph between services, log errors and optionally log the payload body.
Our example above showed you how to directly invoke a different service running locally or in Kubernetes. Dapr:
For more information on tracing and logs see the [observability]({{< ref observability-concept.md >}}) article.
- Outputs metrics, tracing, and logging information,
- Allows you to visualize a call graph between services and log errors, and
- Optionally, log the payload body.
## Related Links
For more information on tracing and logs, see the [observability]({{< ref observability-concept.md >}}) article.
* [Service invocation overview]({{< ref service-invocation-overview.md >}})
* [Service invocation API specification]({{< ref service_invocation_api.md >}})
## Related Links
- [Service invocation overview]({{< ref service-invocation-overview.md >}})
- [Service invocation API specification]({{< ref service_invocation_api.md >}})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 279 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 KiB

After

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 205 KiB

After

Width:  |  Height:  |  Size: 253 KiB