--- type: docs title: "Quickstart: Publish and Subscribe" linkTitle: "Publish and Subscribe" weight: 72 description: "Get started with Dapr's Publish and Subscribe building block" --- Let's take a look at Dapr's [Publish and Subscribe (Pub/sub) building block]({{< ref pubsub >}}). In this Quickstart, you will run a publisher microservice and a subscriber microservice to demonstrate how Dapr enables a Pub/sub pattern. 1. Using a publisher service, developers can repeatedly publish messages to a topic. 1. [A Pub/sub component](https://docs.dapr.io/concepts/components-concept/#pubsub-brokers) queues or brokers those messages. Our example below uses Redis, you can use RabbitMQ, Kafka, etc. 1. The subscriber to that topic pulls messages from the queue and processes them. You can try out this pub/sub quickstart by either: - [Running all applications in this sample simultaneously with the Multi-App Run template file]({{< ref "#run-using-multi-app-run" >}}), or - [Running one application at a time]({{< ref "#run-one-application-at-a-time" >}}) ## Run using Multi-App Run Select your preferred language-specific Dapr SDK before proceeding with the Quickstart. {{< tabs "Python" "JavaScript" ".NET" "Java" "Go" >}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [Python 3.8+ installed](https://www.python.org/downloads/). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` From the root of the Quickstarts directory, navigate into the pub/sub directory: ```bash cd pub_sub/python/sdk ``` Install the dependencies for the `order-processor` and `checkout` apps: ```bash cd ./checkout pip3 install -r requirements.txt cd .. cd ./order-processor pip3 install -r requirements.txt cd .. cd ./order-processor-fastapi pip3 install -r requirements.txt cd .. ``` ### Step 3: Run the publisher and subscriber With the following command, simultaneously run the following services alongside their own Dapr sidecars: - The `order-processor` subscriber - The `checkout` publisher ```bash dapr run -f . ``` > **Note**: Since Python3.exe is not defined in Windows, you may need to change `python3` to `python` in the [`dapr.yaml`]({{< ref "#dapryaml-multi-app-run-template-file" >}}) file before running `dapr run -f .` **Expected output** ``` == APP - checkout-sdk == Published data: Order { OrderId = 1 } == APP - order-processor == Subscriber received : Order { OrderId = 1 } == APP - checkout-sdk == Published data: Order { OrderId = 2 } == APP - order-processor == Subscriber received : Order { OrderId = 2 } == APP - checkout-sdk == Published data: Order { OrderId = 3 } == APP - order-processor == Subscriber received : Order { OrderId = 3 } == APP - checkout-sdk == Published data: Order { OrderId = 4 } == APP - order-processor == Subscriber received : Order { OrderId = 4 } == APP - checkout-sdk == Published data: Order { OrderId = 5 } == APP - order-processor == Subscriber received : Order { OrderId = 5 } == APP - checkout-sdk == Published data: Order { OrderId = 6 } == APP - order-processor == Subscriber received : Order { OrderId = 6 } == APP - checkout-sdk == Published data: Order { OrderId = 7 } == APP - order-processor == Subscriber received : Order { OrderId = 7 } == APP - checkout-sdk == Published data: Order { OrderId = 8 } == APP - order-processor == Subscriber received : Order { OrderId = 8 } == APP - checkout-sdk == Published data: Order { OrderId = 9 } == APP - order-processor == Subscriber received : Order { OrderId = 9 } == APP - checkout-sdk == Published data: Order { OrderId = 10 } == APP - order-processor == Subscriber received : Order { OrderId = 10 } Exited App successfully ``` ### What happened? When you ran `dapr init` during Dapr install, the following YAML files were generated in the `.dapr/components` directory: - [`dapr.yaml` Multi-App Run template file]({{< ref "#dapryaml-multi-app-run-template-file" >}}) - [`pubsub.yaml` component file]({{< ref "#pubsubyaml-component-file" >}}) Running `dapr run -f .` in this Quickstart started both the [subscriber]({{< ref "#order-processor-subscriber" >}}) and [publisher]({{< ref "#checkout-publisher" >}}) applications. ##### `dapr.yaml` Multi-App Run template file Running the [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) with `dapr run -f .` starts all applications in your project. In this Quickstart, the `dapr.yaml` file contains the following: ```yml version: 1 common: resourcesPath: ../../components/ apps: - appID: order-processor-sdk appDirPath: ./order-processor/ appPort: 6001 command: ["uvicorn", "app:app"] - appID: checkout-sdk appDirPath: ./checkout/ command: ["python3", "app.py"] ``` ##### `pubsub.yaml` component file With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the component YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. ##### `order-processor` subscriber In the `order-processor` subscriber, you subscribe to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```py # Register Dapr pub/sub subscriptions @app.route('/dapr/subscribe', methods=['GET']) def subscribe(): subscriptions = [{ 'pubsubname': 'orderpubsub', 'topic': 'orders', 'route': 'orders' }] print('Dapr pub/sub is subscribed to: ' + json.dumps(subscriptions)) return jsonify(subscriptions) # Dapr subscription in /dapr/subscribe sets up this route @app.route('/orders', methods=['POST']) def orders_subscriber(): event = from_http(request.headers, request.get_data()) print('Subscriber received : ' + event.data['orderid'], flush=True) return json.dumps({'success': True}), 200, { 'ContentType': 'application/json'} app.run(port=5001) ``` ##### `checkout` publisher In the `checkout` publisher, you publish the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```python with DaprClient() as client: # Publish an event/message using Dapr PubSub result = client.publish_event( pubsub_name='orderpubsub', topic_name='orders', data=json.dumps(order), data_content_type='application/json', ) ``` {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [Latest Node.js installed](https://nodejs.org/download/). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` From the root of the Quickstarts directory, navigate into the pub/sub directory: ```bash cd pub_sub/javascript/sdk ``` Install the dependencies for the `order-processor` and `checkout` apps: ```bash cd ./order-processor npm install cd .. cd ./checkout npm install cd .. ``` ### Step 3: Run the publisher and subscriber With the following command, simultaneously run the following services alongside their own Dapr sidecars: - The `order-processor` subscriber - The `checkout` publisher ```bash dapr run -f . ``` **Expected output** ``` == APP - checkout-sdk == Published data: Order { OrderId = 1 } == APP - order-processor == Subscriber received : Order { OrderId = 1 } == APP - checkout-sdk == Published data: Order { OrderId = 2 } == APP - order-processor == Subscriber received : Order { OrderId = 2 } == APP - checkout-sdk == Published data: Order { OrderId = 3 } == APP - order-processor == Subscriber received : Order { OrderId = 3 } == APP - checkout-sdk == Published data: Order { OrderId = 4 } == APP - order-processor == Subscriber received : Order { OrderId = 4 } == APP - checkout-sdk == Published data: Order { OrderId = 5 } == APP - order-processor == Subscriber received : Order { OrderId = 5 } == APP - checkout-sdk == Published data: Order { OrderId = 6 } == APP - order-processor == Subscriber received : Order { OrderId = 6 } == APP - checkout-sdk == Published data: Order { OrderId = 7 } == APP - order-processor == Subscriber received : Order { OrderId = 7 } == APP - checkout-sdk == Published data: Order { OrderId = 8 } == APP - order-processor == Subscriber received : Order { OrderId = 8 } == APP - checkout-sdk == Published data: Order { OrderId = 9 } == APP - order-processor == Subscriber received : Order { OrderId = 9 } == APP - checkout-sdk == Published data: Order { OrderId = 10 } == APP - order-processor == Subscriber received : Order { OrderId = 10 } Exited App successfully ``` ### What happened? When you ran `dapr init` during Dapr install, the following YAML files were generated in the `.dapr/components` directory: - [`dapr.yaml` Multi-App Run template file]({{< ref "#dapryaml-multi-app-run-template-file" >}}) - [`pubsub.yaml` component file]({{< ref "#pubsubyaml-component-file" >}}) Running `dapr run -f .` in this Quickstart started both the [subscriber]({{< ref "#order-processor-subscriber" >}}) and [publisher]({{< ref "#checkout-publisher" >}}) applications. ##### `dapr.yaml` Multi-App Run template file Running the [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) with `dapr run -f .` starts all applications in your project. In this Quickstart, the `dapr.yaml` file contains the following: ```yml version: 1 common: resourcesPath: ../../components/ apps: - appID: order-processor appDirPath: ./order-processor/ appPort: 5002 command: ["npm", "run", "start"] - appID: checkout-sdk appDirPath: ./checkout/ command: ["npm", "run", "start"] ``` ##### `pubsub.yaml` component file With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the component YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. ##### `order-processor` subscriber In the `order-processor` subscriber, you subscribe to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```js server.pubsub.subscribe("orderpubsub", "orders", (data) => console.log("Subscriber received: " + JSON.stringify(data))); ``` ##### `checkout` publisher In the `checkout` publisher service, you publish the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```js const client = new DaprClient(); await client.pubsub.publish(PUBSUB_NAME, PUBSUB_TOPIC, order); console.log("Published data: " + JSON.stringify(order)); ``` {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [.NET SDK or .NET 6 SDK installed](https://dotnet.microsoft.com/download). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` From the root of the Quickstarts directory, navigate into the pub/sub directory: ```bash cd pub_sub/csharp/sdk ``` Install the dependencies for the `order-processor` and `checkout` apps: ```bash cd ./order-processor dotnet restore dotnet build cd ../checkout dotnet restore dotnet build cd .. ``` ### Step 3: Run the publisher and subscriber With the following command, simultaneously run the following services alongside their own Dapr sidecars: - The `order-processor` subscriber - The `checkout` publisher ```bash dapr run -f . ``` **Expected output** ``` == APP - checkout-sdk == Published data: Order { OrderId = 1 } == APP - order-processor == Subscriber received : Order { OrderId = 1 } == APP - checkout-sdk == Published data: Order { OrderId = 2 } == APP - order-processor == Subscriber received : Order { OrderId = 2 } == APP - checkout-sdk == Published data: Order { OrderId = 3 } == APP - order-processor == Subscriber received : Order { OrderId = 3 } == APP - checkout-sdk == Published data: Order { OrderId = 4 } == APP - order-processor == Subscriber received : Order { OrderId = 4 } == APP - checkout-sdk == Published data: Order { OrderId = 5 } == APP - order-processor == Subscriber received : Order { OrderId = 5 } == APP - checkout-sdk == Published data: Order { OrderId = 6 } == APP - order-processor == Subscriber received : Order { OrderId = 6 } == APP - checkout-sdk == Published data: Order { OrderId = 7 } == APP - order-processor == Subscriber received : Order { OrderId = 7 } == APP - checkout-sdk == Published data: Order { OrderId = 8 } == APP - order-processor == Subscriber received : Order { OrderId = 8 } == APP - checkout-sdk == Published data: Order { OrderId = 9 } == APP - order-processor == Subscriber received : Order { OrderId = 9 } == APP - checkout-sdk == Published data: Order { OrderId = 10 } == APP - order-processor == Subscriber received : Order { OrderId = 10 } Exited App successfully ``` ### What happened? When you ran `dapr init` during Dapr install, the following YAML files were generated in the `.dapr/components` directory: - [`dapr.yaml` Multi-App Run template file]({{< ref "#dapryaml-multi-app-run-template-file" >}}) - [`pubsub.yaml` component file]({{< ref "#pubsubyaml-component-file" >}}) Running `dapr run -f .` in this Quickstart started both the [subscriber]({{< ref "#order-processor-subscriber" >}}) and [publisher]({{< ref "#checkout-publisher" >}}) applications. ##### `dapr.yaml` Multi-App Run template file Running the [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) with `dapr run -f .` starts all applications in your project. In this Quickstart, the `dapr.yaml` file contains the following: ```yml version: 1 common: resourcesPath: ../../components/ apps: - appID: order-processor appDirPath: ./order-processor/ appPort: 7006 command: ["dotnet", "run"] - appID: checkout-sdk appDirPath: ./checkout/ command: ["dotnet", "run"] ``` ##### `pubsub.yaml` component file With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the component YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. ##### `order-processor` subscriber In the `order-processor` subscriber, you subscribe to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```cs // Dapr subscription in [Topic] routes orders topic to this route app.MapPost("/orders", [Topic("orderpubsub", "orders")] (Order order) => { Console.WriteLine("Subscriber received : " + order); return Results.Ok(order); }); public record Order([property: JsonPropertyName("orderId")] int OrderId); ``` ##### `checkout` publisher In the `checkout` publisher, you publish the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```cs using var client = new DaprClientBuilder().Build(); await client.PublishEventAsync("orderpubsub", "orders", order); Console.WriteLine("Published data: " + order); ``` {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - Java JDK 17 (or greater): - [Oracle JDK](https://www.oracle.com/java/technologies/downloads), or - OpenJDK - [Apache Maven](https://maven.apache.org/install.html), version 3.x. - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` From the root of the Quickstarts directory, navigate into the pub/sub directory: ```bash cd pub_sub/java/sdk ``` Install the dependencies for the `order-processor` and `checkout` apps: ```bash cd ./order-processor mvn clean install cd .. cd ./checkout mvn clean install cd .. ``` ### Step 3: Run the publisher and subscriber With the following command, simultaneously run the following services alongside their own Dapr sidecars: - The `order-processor` subscriber - The `checkout` publisher ```bash dapr run -f . ``` **Expected output** ``` == APP - checkout-sdk == Published data: Order { OrderId = 1 } == APP - order-processor == Subscriber received : Order { OrderId = 1 } == APP - checkout-sdk == Published data: Order { OrderId = 2 } == APP - order-processor == Subscriber received : Order { OrderId = 2 } == APP - checkout-sdk == Published data: Order { OrderId = 3 } == APP - order-processor == Subscriber received : Order { OrderId = 3 } == APP - checkout-sdk == Published data: Order { OrderId = 4 } == APP - order-processor == Subscriber received : Order { OrderId = 4 } == APP - checkout-sdk == Published data: Order { OrderId = 5 } == APP - order-processor == Subscriber received : Order { OrderId = 5 } == APP - checkout-sdk == Published data: Order { OrderId = 6 } == APP - order-processor == Subscriber received : Order { OrderId = 6 } == APP - checkout-sdk == Published data: Order { OrderId = 7 } == APP - order-processor == Subscriber received : Order { OrderId = 7 } == APP - checkout-sdk == Published data: Order { OrderId = 8 } == APP - order-processor == Subscriber received : Order { OrderId = 8 } == APP - checkout-sdk == Published data: Order { OrderId = 9 } == APP - order-processor == Subscriber received : Order { OrderId = 9 } == APP - checkout-sdk == Published data: Order { OrderId = 10 } == APP - order-processor == Subscriber received : Order { OrderId = 10 } Exited App successfully ``` ### What happened? When you ran `dapr init` during Dapr install, the following YAML files were generated in the `.dapr/components` directory: - [`dapr.yaml` Multi-App Run template file]({{< ref "#dapryaml-multi-app-run-template-file" >}}) - [`pubsub.yaml` component file]({{< ref "#pubsubyaml-component-file" >}}) Running `dapr run -f .` in this Quickstart started both the [subscriber]({{< ref "#order-processor-subscriber" >}}) and [publisher]({{< ref "#checkout-publisher" >}}) applications. ##### `dapr.yaml` Multi-App Run template file Running the [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) with `dapr run -f .` starts all applications in your project. In this Quickstart, the `dapr.yaml` file contains the following: ```yml version: 1 common: resourcesPath: ../../components/ apps: - appID: order-processor-sdk appDirPath: ./order-processor/target/ appPort: 8080 command: ["java", "-jar", "OrderProcessingService-0.0.1-SNAPSHOT.jar"] - appID: checkout-sdk appDirPath: ./checkout/target/ command: ["java", "-jar", "CheckoutService-0.0.1-SNAPSHOT.jar"] ``` ##### `pubsub.yaml` component file With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the component YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. ##### `order-processor` subscriber In the `order-processor` subscriber, you subscribe to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```java @Topic(name = "orders", pubsubName = "orderpubsub") @PostMapping(path = "/orders", consumes = MediaType.ALL_VALUE) public Mono getCheckout(@RequestBody(required = false) CloudEvent cloudEvent) { return Mono.fromSupplier(() -> { try { logger.info("Subscriber received: " + cloudEvent.getData().getOrderId()); return ResponseEntity.ok("SUCCESS"); } catch (Exception e) { throw new RuntimeException(e); } }); } ``` ##### `checkout` publisher In the `checkout` publisher, you publish the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```java DaprClient client = new DaprClientBuilder().build(); client.publishEvent( PUBSUB_NAME, TOPIC_NAME, order).block(); logger.info("Published data: " + order.getOrderId()); ``` {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [Latest version of Go](https://go.dev/dl/). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` From the root of the Quickstarts directory, navigate into the pub/sub directory: ```bash cd pub_sub/go/sdk ``` Install the dependencies for the `order-processor` and `checkout` apps: ```bash cd ./order-processor go build . cd ../checkout go build . cd .. ``` ### Step 3: Run the publisher and subscriber With the following command, simultaneously run the following services alongside their own Dapr sidecars: - The `order-processor` subscriber - The `checkout` publisher ```bash dapr run -f . ``` **Expected output** ``` == APP - checkout-sdk == Published data: Order { OrderId = 1 } == APP - order-processor == Subscriber received : Order { OrderId = 1 } == APP - checkout-sdk == Published data: Order { OrderId = 2 } == APP - order-processor == Subscriber received : Order { OrderId = 2 } == APP - checkout-sdk == Published data: Order { OrderId = 3 } == APP - order-processor == Subscriber received : Order { OrderId = 3 } == APP - checkout-sdk == Published data: Order { OrderId = 4 } == APP - order-processor == Subscriber received : Order { OrderId = 4 } == APP - checkout-sdk == Published data: Order { OrderId = 5 } == APP - order-processor == Subscriber received : Order { OrderId = 5 } == APP - checkout-sdk == Published data: Order { OrderId = 6 } == APP - order-processor == Subscriber received : Order { OrderId = 6 } == APP - checkout-sdk == Published data: Order { OrderId = 7 } == APP - order-processor == Subscriber received : Order { OrderId = 7 } == APP - checkout-sdk == Published data: Order { OrderId = 8 } == APP - order-processor == Subscriber received : Order { OrderId = 8 } == APP - checkout-sdk == Published data: Order { OrderId = 9 } == APP - order-processor == Subscriber received : Order { OrderId = 9 } == APP - checkout-sdk == Published data: Order { OrderId = 10 } == APP - order-processor == Subscriber received : Order { OrderId = 10 } Exited App successfully ``` ### What happened? When you ran `dapr init` during Dapr install, the following YAML files were generated in the `.dapr/components` directory: - [`dapr.yaml` Multi-App Run template file]({{< ref "#dapryaml-multi-app-run-template-file" >}}) - [`pubsub.yaml` component file]({{< ref "#pubsubyaml-component-file" >}}) Running `dapr run -f .` in this Quickstart started both the [subscriber]({{< ref "#order-processor-subscriber" >}}) and [publisher]({{< ref "#checkout-publisher" >}}) applications. ##### `dapr.yaml` Multi-App Run template file Running the [Multi-App Run template file]({{< ref multi-app-dapr-run >}}) with `dapr run -f .` starts all applications in your project. In this Quickstart, the `dapr.yaml` file contains the following: ```yml version: 1 common: resourcesPath: ../../components/ apps: - appID: order-processor appDirPath: ./order-processor/ appPort: 6005 command: ["go", "run", "."] - appID: checkout-sdk appDirPath: ./checkout/ command: ["go", "run", "."] ``` ##### `pubsub.yaml` component file With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the component YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. ##### `order-processor` subscriber In the `order-processor` subscriber, you subscribe to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```go func eventHandler(ctx context.Context, e *common.TopicEvent) (retry bool, err error) { fmt.Println("Subscriber received: ", e.Data) return false, nil } ``` ##### `checkout` publisher In the `checkout` publisher, you publish the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```go client, err := dapr.NewClient() if err := client.PublishEvent(ctx, PUBSUB_NAME, PUBSUB_TOPIC, []byte(order)); err != nil { panic(err) } fmt.Println("Published data: ", order) ``` {{% /codetab %}} {{< /tabs >}} ## Run one application at a time Select your preferred language-specific Dapr SDK before proceeding with the Quickstart. {{< tabs "Python" "JavaScript" ".NET" "Java" "Go" >}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [Python 3.7+ installed](https://www.python.org/downloads/). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` ### Step 3: Subscribe to topics In a terminal window, from the root of the Quickstarts clone directory navigate to the `order-processor` directory. ```bash cd pub_sub/python/sdk/order-processor ``` Install the dependencies: ```bash pip3 install -r requirements.txt ``` Run the `order-processor` subscriber service alongside a Dapr sidecar. ```bash dapr run --app-id order-processor --resources-path ../../../components/ --app-port 6002 -- python3 app.py ``` > **Note**: Since Python3.exe is not defined in Windows, you may need to use `python app.py` instead of `python3 app.py`. In the `order-processor` subscriber, we're subscribing to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```py # Register Dapr pub/sub subscriptions @app.route('/dapr/subscribe', methods=['GET']) def subscribe(): subscriptions = [{ 'pubsubname': 'orderpubsub', 'topic': 'orders', 'route': 'orders' }] print('Dapr pub/sub is subscribed to: ' + json.dumps(subscriptions)) return jsonify(subscriptions) # Dapr subscription in /dapr/subscribe sets up this route @app.route('/orders', methods=['POST']) def orders_subscriber(): event = from_http(request.headers, request.get_data()) print('Subscriber received : ' + event.data['orderid'], flush=True) return json.dumps({'success': True}), 200, { 'ContentType': 'application/json'} app.run(port=5001) ``` ### Step 4: Publish a topic In a new terminal window, navigate to the `checkout` directory. ```bash cd pub_sub/python/sdk/checkout ``` Install the dependencies: ```bash pip3 install -r requirements.txt ``` Run the `checkout` publisher service alongside a Dapr sidecar. ```bash dapr run --app-id checkout --resources-path ../../../components/ -- python3 app.py ``` > **Note**: Since Python3.exe is not defined in Windows, you may need to use `python app.py` instead of `python3 app.py`. In the `checkout` publisher, we're publishing the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```python with DaprClient() as client: # Publish an event/message using Dapr PubSub result = client.publish_event( pubsub_name='orderpubsub', topic_name='orders', data=json.dumps(order), data_content_type='application/json', ) ``` ### Step 5: View the Pub/sub outputs The publisher sends orders to the Dapr sidecar while the subscriber receives them. Publisher output: ``` == APP == INFO:root:Published data: {"orderId": 1} == APP == INFO:root:Published data: {"orderId": 2} == APP == INFO:root:Published data: {"orderId": 3} == APP == INFO:root:Published data: {"orderId": 4} == APP == INFO:root:Published data: {"orderId": 5} == APP == INFO:root:Published data: {"orderId": 6} == APP == INFO:root:Published data: {"orderId": 7} == APP == INFO:root:Published data: {"orderId": 8} == APP == INFO:root:Published data: {"orderId": 9} == APP == INFO:root:Published data: {"orderId": 10} ``` Subscriber output: ``` == APP == INFO:root:Subscriber received: {"orderId": 1} == APP == INFO:root:Subscriber received: {"orderId": 2} == APP == INFO:root:Subscriber received: {"orderId": 3} == APP == INFO:root:Subscriber received: {"orderId": 4} == APP == INFO:root:Subscriber received: {"orderId": 5} == APP == INFO:root:Subscriber received: {"orderId": 6} == APP == INFO:root:Subscriber received: {"orderId": 7} == APP == INFO:root:Subscriber received: {"orderId": 8} == APP == INFO:root:Subscriber received: {"orderId": 9} == APP == INFO:root:Subscriber received: {"orderId": 10} ``` ##### `pubsub.yaml` component file When you run `dapr init`, Dapr creates a default Redis `pubsub.yaml` and runs a Redis container on your local machine, located: - On Windows, under `%UserProfile%\.dapr\components\pubsub.yaml` - On Linux/MacOS, under `~/.dapr/components/pubsub.yaml` With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [Latest Node.js installed](https://nodejs.org/download/). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` ### Step 3: Subscribe to topics In a terminal window, from the root of the Quickstarts clone directory navigate to the `order-processor` directory. ```bash cd pub_sub/javascript/sdk/order-processor ``` Install dependencies, which will include the `@dapr/dapr` package from the JavaScript SDK: ```bash npm install ``` Verify you have the following files included in the service directory: - `package.json` - `package-lock.json` Run the `order-processor` subscriber service alongside a Dapr sidecar. ```bash dapr run --app-port 5002 --app-id order-processing --app-protocol http --dapr-http-port 3501 --resources-path ../../../components -- npm run start ``` In the `order-processor` subscriber, we're subscribing to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```js server.pubsub.subscribe("orderpubsub", "orders", (data) => console.log("Subscriber received: " + JSON.stringify(data))); ``` ### Step 4: Publish a topic In a new terminal window, from the root of the Quickstarts clone directory, navigate to the `checkout` directory. ```bash cd pub_sub/javascript/sdk/checkout ``` Install dependencies, which will include the `@dapr/dapr` package from the JavaScript SDK: ```bash npm install ``` Verify you have the following files included in the service directory: - `package.json` - `package-lock.json` Run the `checkout` publisher service alongside a Dapr sidecar. ```bash dapr run --app-id checkout --app-protocol http --dapr-http-port 3500 --resources-path ../../../components -- npm run start ``` In the `checkout` publisher service, we're publishing the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```js const client = new DaprClient(); await client.pubsub.publish(PUBSUB_NAME, PUBSUB_TOPIC, order); console.log("Published data: " + JSON.stringify(order)); ``` ### Step 5: View the Pub/sub outputs Notice, as specified in the code above, the publisher pushes a random number to the Dapr sidecar while the subscriber receives it. Publisher output: ```cli == APP == Published data: {"orderId":1} == APP == Published data: {"orderId":2} == APP == Published data: {"orderId":3} == APP == Published data: {"orderId":4} == APP == Published data: {"orderId":5} == APP == Published data: {"orderId":6} == APP == Published data: {"orderId":7} == APP == Published data: {"orderId":8} == APP == Published data: {"orderId":9} == APP == Published data: {"orderId":10} ``` Subscriber output: ```cli == APP == Subscriber received: {"orderId":1} == APP == Subscriber received: {"orderId":2} == APP == Subscriber received: {"orderId":3} == APP == Subscriber received: {"orderId":4} == APP == Subscriber received: {"orderId":5} == APP == Subscriber received: {"orderId":6} == APP == Subscriber received: {"orderId":7} == APP == Subscriber received: {"orderId":8} == APP == Subscriber received: {"orderId":9} == APP == Subscriber received: {"orderId":10} ``` ##### `pubsub.yaml` component file When you run `dapr init`, Dapr creates a default Redis `pubsub.yaml` and runs a Redis container on your local machine, located: - On Windows, under `%UserProfile%\.dapr\components\pubsub.yaml` - On Linux/MacOS, under `~/.dapr/components/pubsub.yaml` With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [.NET SDK or .NET 6 SDK installed](https://dotnet.microsoft.com/download). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` ### Step 3: Subscribe to topics In a terminal window, from the root of the Quickstarts clone directory navigate to the `order-processor` directory. ```bash cd pub_sub/csharp/sdk/order-processor ``` Recall NuGet packages: ```bash dotnet restore dotnet build ``` Run the `order-processor` subscriber service alongside a Dapr sidecar. ```bash dapr run --app-id order-processor --resources-path ../../../components --app-port 7006 -- dotnet run ``` In the `order-processor` subscriber, we're subscribing to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```cs // Dapr subscription in [Topic] routes orders topic to this route app.MapPost("/orders", [Topic("orderpubsub", "orders")] (Order order) => { Console.WriteLine("Subscriber received : " + order); return Results.Ok(order); }); public record Order([property: JsonPropertyName("orderId")] int OrderId); ``` ### Step 4: Publish a topic In a new terminal window, from the root of the Quickstarts clone directory, navigate to the `checkout` directory. ```bash cd pub_sub/csharp/sdk/checkout ``` Recall NuGet packages: ```bash dotnet restore dotnet build ``` Run the `checkout` publisher service alongside a Dapr sidecar. ```bash dapr run --app-id checkout --resources-path ../../../components -- dotnet run ``` In the `checkout` publisher, we're publishing the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```cs using var client = new DaprClientBuilder().Build(); await client.PublishEventAsync("orderpubsub", "orders", order); Console.WriteLine("Published data: " + order); ``` ### Step 5: View the Pub/sub outputs Notice, as specified in the code above, the publisher pushes a random number to the Dapr sidecar while the subscriber receives it. Publisher output: ```dotnetcli == APP == Published data: Order { OrderId = 1 } == APP == Published data: Order { OrderId = 2 } == APP == Published data: Order { OrderId = 3 } == APP == Published data: Order { OrderId = 4 } == APP == Published data: Order { OrderId = 5 } == APP == Published data: Order { OrderId = 6 } == APP == Published data: Order { OrderId = 7 } == APP == Published data: Order { OrderId = 8 } == APP == Published data: Order { OrderId = 9 } == APP == Published data: Order { OrderId = 10 } ``` Subscriber output: ```dotnetcli == APP == Subscriber received: Order { OrderId = 1 } == APP == Subscriber received: Order { OrderId = 2 } == APP == Subscriber received: Order { OrderId = 3 } == APP == Subscriber received: Order { OrderId = 4 } == APP == Subscriber received: Order { OrderId = 5 } == APP == Subscriber received: Order { OrderId = 6 } == APP == Subscriber received: Order { OrderId = 7 } == APP == Subscriber received: Order { OrderId = 8 } == APP == Subscriber received: Order { OrderId = 9 } == APP == Subscriber received: Order { OrderId = 10 } ``` ##### `pubsub.yaml` component file When you run `dapr init`, Dapr creates a default Redis `pubsub.yaml` and runs a Redis container on your local machine, located: - On Windows, under `%UserProfile%\.dapr\components\pubsub.yaml` - On Linux/MacOS, under `~/.dapr/components/pubsub.yaml` With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" ``` In the YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - Java JDK 11 (or greater): - [Oracle JDK](https://www.oracle.com/java/technologies/downloads), or - OpenJDK - [Apache Maven](https://maven.apache.org/install.html), version 3.x. - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` ### Step 3: Subscribe to topics In a terminal window, from the root of the Quickstarts clone directory navigate to the `order-processor` directory. ```bash cd pub_sub/java/sdk/order-processor ``` Install the dependencies: ```bash mvn clean install ``` Run the `order-processor` subscriber service alongside a Dapr sidecar. ```bash dapr run --app-port 8080 --app-id order-processor --resources-path ../../../components -- java -jar target/OrderProcessingService-0.0.1-SNAPSHOT.jar ``` In the `order-processor` subscriber, we're subscribing to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```java @Topic(name = "orders", pubsubName = "orderpubsub") @PostMapping(path = "/orders", consumes = MediaType.ALL_VALUE) public Mono getCheckout(@RequestBody(required = false) CloudEvent cloudEvent) { return Mono.fromSupplier(() -> { try { logger.info("Subscriber received: " + cloudEvent.getData().getOrderId()); return ResponseEntity.ok("SUCCESS"); } catch (Exception e) { throw new RuntimeException(e); } }); } ``` ### Step 4: Publish a topic In a new terminal window, from the root of the Quickstarts clone directory, navigate to the `checkout` directory. ```bash cd pub_sub/java/sdk/checkout ``` Install the dependencies: ```bash mvn clean install ``` Run the `checkout` publisher service alongside a Dapr sidecar. ```bash dapr run --app-id checkout --resources-path ../../../components -- java -jar target/CheckoutService-0.0.1-SNAPSHOT.jar ``` In the `checkout` publisher, we're publishing the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```java DaprClient client = new DaprClientBuilder().build(); client.publishEvent( PUBSUB_NAME, TOPIC_NAME, order).block(); logger.info("Published data: " + order.getOrderId()); ``` ### Step 5: View the Pub/sub outputs Notice, as specified in the code above, the publisher pushes a random number to the Dapr sidecar while the subscriber receives it. Publisher output: ``` == APP == 7194 [main] INFO com.service.CheckoutServiceApplication - Published data: 1 == APP == 12213 [main] INFO com.service.CheckoutServiceApplication - Published data: 2 == APP == 17233 [main] INFO com.service.CheckoutServiceApplication - Published data: 3 == APP == 22252 [main] INFO com.service.CheckoutServiceApplication - Published data: 4 == APP == 27276 [main] INFO com.service.CheckoutServiceApplication - Published data: 5 == APP == 32320 [main] INFO com.service.CheckoutServiceApplication - Published data: 6 == APP == 37340 [main] INFO com.service.CheckoutServiceApplication - Published data: 7 == APP == 42356 [main] INFO com.service.CheckoutServiceApplication - Published data: 8 == APP == 47386 [main] INFO com.service.CheckoutServiceApplication - Published data: 9 == APP == 52410 [main] INFO com.service.CheckoutServiceApplication - Published data: 10 ``` Subscriber output: ``` == APP == 2022-03-07 13:31:19.551 INFO 43512 --- [nio-8080-exec-5] c.s.c.OrderProcessingServiceController : Subscriber received: 1 == APP == 2022-03-07 13:31:19.552 INFO 43512 --- [nio-8080-exec-9] c.s.c.OrderProcessingServiceController : Subscriber received: 2 == APP == 2022-03-07 13:31:19.551 INFO 43512 --- [nio-8080-exec-6] c.s.c.OrderProcessingServiceController : Subscriber received: 3 == APP == 2022-03-07 13:31:19.552 INFO 43512 --- [nio-8080-exec-2] c.s.c.OrderProcessingServiceController : Subscriber received: 4 == APP == 2022-03-07 13:31:19.553 INFO 43512 --- [nio-8080-exec-2] c.s.c.OrderProcessingServiceController : Subscriber received: 5 == APP == 2022-03-07 13:31:19.553 INFO 43512 --- [nio-8080-exec-9] c.s.c.OrderProcessingServiceController : Subscriber received: 6 == APP == 2022-03-07 13:31:22.849 INFO 43512 --- [nio-8080-exec-3] c.s.c.OrderProcessingServiceController : Subscriber received: 7 == APP == 2022-03-07 13:31:27.866 INFO 43512 --- [nio-8080-exec-6] c.s.c.OrderProcessingServiceController : Subscriber received: 8 == APP == 2022-03-07 13:31:32.895 INFO 43512 --- [nio-8080-exec-6] c.s.c.OrderProcessingServiceController : Subscriber received: 9 == APP == 2022-03-07 13:31:37.919 INFO 43512 --- [nio-8080-exec-2] c.s.c.OrderProcessingServiceController : Subscriber received: 10 ``` ##### `pubsub.yaml` component file When you run `dapr init`, Dapr creates a default Redis `pubsub.yaml` and runs a Redis container on your local machine, located: - On Windows, under `%UserProfile%\.dapr\components\pubsub.yaml` - On Linux/MacOS, under `~/.dapr/components/pubsub.yaml` With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" scopes: - orderprocessing - checkout ``` In the YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. {{% /codetab %}} {{% codetab %}} ### Step 1: Pre-requisites For this example, you will need: - [Dapr CLI and initialized environment](https://docs.dapr.io/getting-started). - [Latest version of Go](https://go.dev/dl/). - [Docker Desktop](https://www.docker.com/products/docker-desktop) ### Step 2: Set up the environment Clone the [sample provided in the Quickstarts repo](https://github.com/dapr/quickstarts/tree/master/pub_sub). ```bash git clone https://github.com/dapr/quickstarts.git ``` ### Step 3: Subscribe to topics In a terminal window, from the root of the Quickstarts clone directory navigate to the `order-processor` directory. ```bash cd pub_sub/go/sdk/order-processor ``` Install the dependencies and build the application: ```bash go build . ``` Run the `order-processor` subscriber service alongside a Dapr sidecar. ```bash dapr run --app-port 6005 --app-id order-processor-sdk --app-protocol http --dapr-http-port 3501 --resources-path ../../../components -- go run . ``` In the `order-processor` subscriber, we're subscribing to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. This enables your app code to talk to the Redis component instance through the Dapr sidecar. ```go func eventHandler(ctx context.Context, e *common.TopicEvent) (retry bool, err error) { fmt.Println("Subscriber received: ", e.Data) return false, nil } ``` ### Step 4: Publish a topic In a new terminal window, from the root of the Quickstarts clone directory, navigate to the `checkout` directory. ```bash cd pub_sub/go/sdk/checkout ``` Install the dependencies and build the application: ```bash go build . ``` Run the `checkout` publisher service alongside a Dapr sidecar. ```bash dapr run --app-id checkout --app-protocol http --dapr-http-port 3500 --resources-path ../../../components -- go run . ``` In the `checkout` publisher, we're publishing the orderId message to the Redis instance called `orderpubsub` [(as defined in the `pubsub.yaml` component)]({{< ref "#pubsubyaml-component-file" >}}) and topic `orders`. As soon as the service starts, it publishes in a loop: ```go client, err := dapr.NewClient() if err := client.PublishEvent(ctx, PUBSUB_NAME, PUBSUB_TOPIC, []byte(order)); err != nil { panic(err) } fmt.Println("Published data: ", order) ``` ### Step 5: View the Pub/sub outputs Notice, as specified in the code above, the publisher pushes a numbered message to the Dapr sidecar while the subscriber receives it. Publisher output: ``` == APP == dapr client initializing for: 127.0.0.1:63293 == APP == Published data: {"orderId":1} == APP == Published data: {"orderId":2} == APP == Published data: {"orderId":3} == APP == Published data: {"orderId":4} == APP == Published data: {"orderId":5} == APP == Published data: {"orderId":6} == APP == Published data: {"orderId":7} == APP == Published data: {"orderId":8} == APP == Published data: {"orderId":9} == APP == Published data: {"orderId":10} ``` Subscriber output: ``` == APP == Subscriber received: {"orderId":1} == APP == Subscriber received: {"orderId":2} == APP == Subscriber received: {"orderId":3} == APP == Subscriber received: {"orderId":4} == APP == Subscriber received: {"orderId":5} == APP == Subscriber received: {"orderId":6} == APP == Subscriber received: {"orderId":7} == APP == Subscriber received: {"orderId":8} == APP == Subscriber received: {"orderId":9} == APP == Subscriber received: {"orderId":10} ``` Note: the order in which they are received may vary. ##### `pubsub.yaml` component file When you run `dapr init`, Dapr creates a default Redis `pubsub.yaml` and runs a Redis container on your local machine, located: - On Windows, under `%UserProfile%\.dapr\components\pubsub.yaml` - On Linux/MacOS, under `~/.dapr/components/pubsub.yaml` With the `pubsub.yaml` component, you can easily swap out underlying components without application code changes. The Redis `pubsub.yaml` file included for this Quickstart contains the following: ```yaml apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderpubsub spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: localhost:6379 - name: redisPassword value: "" scopes: - orderprocessing - checkout ``` In the YAML file: - `metadata/name` is how your application talks to the component. - `spec/metadata` defines the connection to the instance of the component. - `scopes` specify which application can use the component. {{% /codetab %}} {{< /tabs >}} ## Tell us what you think! We're continuously working to improve our Quickstart examples and value your feedback. Did you find this Quickstart helpful? Do you have suggestions for improvement? Join the discussion in our [discord channel](https://discord.com/channels/778680217417809931/953427615916638238). ## Next steps - Set up Pub/sub using HTTP instead of an SDK. - [Python](https://github.com/dapr/quickstarts/tree/master/pub_sub/python/http) - [JavaScript](https://github.com/dapr/quickstarts/tree/master/pub_sub/javascript/http) - [.NET](https://github.com/dapr/quickstarts/tree/master/pub_sub/csharp/http) - [Java](https://github.com/dapr/quickstarts/tree/master/pub_sub/java/http) - [Go](https://github.com/dapr/quickstarts/tree/master/pub_sub/go/http) - Learn more about [Pub/sub as a Dapr building block]({{< ref pubsub-overview >}}) {{< button text="Explore Dapr tutorials >>" page="getting-started/tutorials/_index.md" >}}