# Introduction to Dapr: Part-3

Before continuing any further, it is recommended that you read the [second part](https://geekyants.com/blog/introduction-to-dapr-part-2/) of the series on **Introduction to Dapr**, as it covers information on different forms of communication and how services are called.

`PubSub`is a way to connect with other services in an asynchronous manner. Let's take a look at what other features it offers.

### **Advantages Of Using PubSub With Dapr**

* `Pubsub` is an integral component of `Dapr`, allowing for the message broker to be interchangeable and set up as a `Dapr Pubsub component`. This eliminates the dependence on a specific service, making it more adaptable and portable to changes, even when switching to different message brokers.
    
* With `Dapr`, messages can be exchanged using a standard API, regardless of the programming language used.
    
* It also guarantees message delivery at least once and utilizes the `CloudEvents 1.0` protocol to provide additional context to the event payload.
    
* Dapr is compatible with all major message brokers as a `Pubsub` component.
    

### **How Dapr Handles PubSub**

Consider two services, the account service and the user service. When a user is created within the account service, a `PubSub` message will be sent to the email service, asking it to send a confirmation email as the email service is responsible for delivering these types of emails. To better understand how this works, the service that wants to publish the message (account-service) sends a network request, or API call, to the `Dapr Pubsub` building block API (account-service Dapr sidecar). This request is wrapped in the specific message broker specified in the configuration, and is then sent to the `Dapr sidecar` (email-service Dapr sidecar) that has subscribed to that specific subject. Once the message is received, the `Dapr sidecar` will deliver it to the appropriate service (the email service).

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1670474272474/xpCFkh_1a.png align="center")

To illustrate how to use `PubSub` with `Express JS,` we must take into account two important points. One, `Dapr` uses `redis streams` as its default message broker, which we will also be utilizing in this example. Two, it is possible to subscribe to a topic either through a declarative or programmatic method. In this particular example, we will demonstrate how to subscribe to a topic programmatically.

Create account service with index.js file and install [express](https://www.npmjs.com/package/express) and [dapr sdk](https://www.npmjs.com/package/@dapr/dapr). Then create a route as shown.

```javascript
const express = require("express");
const dapr = require("@dapr/dapr");
const app = express();

app.use(express.json());
const client = new dapr.DaprClient(
  "127.0.0.1",
  "3500",
  dapr.CommunicationProtocolEnum.HTTP
);

const pubSubName = "pubsub";
//THIS METHOD TAKE USER AND AFTER CREATING USER IT WILL PUBLISH MESSAGE
app.post("/create", async (req, res) => {
  const topic = "create-user";
  const userId = Math.floor(Math.random() * 100);
  const message = {
    userId,
    name: req.body.name,
    email: req.body.email,
  };
  // Publish Message to Topic :: THIS MESSAGE WILL BE CONSUMED[SUBSCRIBED] IN EMAIL SERVICE
  await client.pubsub.publish(pubSubName, topic, message);
  res.send(message);
});

app.listen("4000", () => {
  console.log("SERVER STARTED ");
});
```

Here, we are starting the `Dapr` client with the port 3500 and using the `Dapr SDK` client to publish the topic called **"create-user"** so that when the new user is created, this topic is published and the subscribers receive the message.

As previously discussed, we are going to use the default message broker, `Redis stream`, which has the name `PubSub`. Run the command stated below to start the service.

```bash
dapr run --app-id  account-service --app-port 4000 --dapr-http-port 3500  npm start
```

Similarly, create an email service with index.js file and install [express](https://www.npmjs.com/package/express)

```javascript
const express = require("express");

const app = express();
// Dapr publishes messages with the application/cloudevents+json content-type
app.use(express.json({ type: "application/*+json" }));

const port = 4002;

app.get("/dapr/subscribe", (_req, res) => {
  res.json([
    {
      pubsubname: "pubsub",
      topic: "create-user",
      route: "userCreated",
    },
  ]);
});
//WHEN  topic  "create-user" IS PUBLISHED MESSAGE THE ROUTE IS INVOKED

app.post("/userCreated", (req, res) => {
  console.log(
    " EMAIL SERVICE :: SEND WELCOME  EMAIL TO: ",
    req.body.data.email
  );
  console.log(req.body)
  res.sendStatus(200);
});


app.listen(port, () =>
  console.log(`EMAIL SERVICE listening on port ${port}`)
);
```

As Dapr utilizes cloud event specifications for transmitting pubsub messages, it is necessary to permit the `content-type application/cloudevents+json`. We have created the route `/dapr/subscribe`, which will return an array of objects that include the `PubSub` name, topic, and route. This route will be accessed by `Dapr` when the server is launched, and `Dapr` will automatically subscribe to this topic on behalf of the service. Once the publisher posts a message to this topic, `Dapr` will proceed along the path specified.

To start the server, execute the command below.

```bash
dapr run --app-id  email-service --app-port 4002 --dapr-http-port 3502 npm start
```

When you use postman to create a user from the account service, you will receive a response similar to this.

```json
{
    "userId": 4,
    "name": "salman",
    "email": "a@b.com"
}
```

Also if you check the logs of the email service, you will have received `EMAIL SERVICE:: SEND WELCOME EMAIL TO: a@b.com`. Additionally,a big json object(req.body) will also be logged which will resemble:

```json
{
    "data": {
        "email": "a@b.com",
        "name": "salman",
        "userId": 4
    },
    "datacontenttype": "application/json",
    "id": "9a0afb51-027e-40bc-8b2e-1021e4291048",
    "pubsubname": "pubsub",
    "source": "account-service",
    "specversion": "1.0",
    "topic": "create-user",
    "traceid": "00-486106d71125b78e0d384f64f4b1eee0-8330cfade53e844c-01",
    "traceparent": "00-486106d71125b78e0d384f64f4b1eee0-8330cfade53e844c-01",
    "tracestate": "",
    "type": "com.dapr.event.sent"
}
```

By utilizing cloud event specifications, we are able to gather extra information along with the data sent by another service. This includes details such as the topic name, `pubsub` name, source name, and unique id for each message. The actual data will be stored in an object called data. It's important to note that the route handling a specific topic should return a status code of 200 when it receives data as `Dapr` provides a guarantee of `at least one message delivery.` If `Dapr` does not receive a status code of 200, it will assume the message was not successfully received and will continue to send the same message.

### **Final Words**

That concludes the introduction to `Dapr’s PubSub` .To gain a deeper understanding of `PubSub`, you can refer to the `Dapr` documentation and access the code on GitHub. In the next blog post, we will delve into the topic of `state management` in `Dapr`.
