Introduction
In the Create an AsyncAPI Document for a Slackbot with WebSockets tutorial, you learned how to write an AsyncAPI document for a Slackbot Heart-Counter that actively monitored reactions associated with a message. In this lesson, let's go a step further. After receiving a reaction, Heart-Counter responds via a message back to the Slack server through WebSocket to confirm the event reception.
The interaction where the Slackbot acknowledges the event and replies with a specific response sets the stage for the Request/Reply messaging pattern discussed in this context.
Refer to the Request/Reply pattern tutorial for an introduction to its implementation.
Background context
The Request-Reply Messaging Pattern in AsyncAPI is an exciting and highly anticipated feature. The messaging pattern mirrors a traditional conversation, where one "requester" entity initiates a query or request, and the "responder" entity provides a specific and expected response. The messaging pattern can work in both synchronous and asynchronous environments and is very beneficial to decouple components by allowing them to operate independently in a distributed system.
Define messages
In the Heart-Counter tutorial, you dealt with the hello event triggered when the WebSocket connection was established and the reaction event expected when a new reaction-added event was triggered.
In this tutorial, you'll add the acknowledge message to your AsyncAPI document to represent the acknowledgment sent by the Slack application back to the server to indicate that it has successfully received the message.
1components:2 messages:3 reaction:4 summary: Action triggered when the channel receives a new reaction-added event5 payload:6 $ref: '#/components/schemas/reaction'7 hello:8 summary: Action triggered when a successful WebSocket connection is established9 payload:10 $ref: '#/components/schemas/hello'11 acknowledge:12 summary: Acknowledgement response sent to Server13 payload:14 $ref: '#/components/schemas/acknowledge'
Define schemas
Previously, the reaction schema was simplified to include the event payload. However, in this instance, you will be able to elaborate on the schema for the complete request it is expected to receive.
Remember
The sample request and response payloads are extracted from Slack's official documentation.
1 schemas:2 hello:3 type: object4 properties:5 type:6 type: string7 description: A hello string confirming WebSocket connection8 connection_info:9 type: object10 properties:11 app_id:12 type: string13 num_connections:14 type: integer15 debug_info:16 type: object17 properties:18 host:19 type: string20 started:21 type: string22 build_number:23 type: integer24 approximate_connection_time:25 type: integer26 reaction:27 type: object28 properties:29 envelope_id:30 type: string31 description: 'Unique ID assigned to payload'32 payload:33 type: object34 description: 'Payload of the reaction added event'35 properties:36 token:37 type: string38 team_id:39 type: string40 event:41 type: object42 properties:43 user:44 type: string45 description: User ID who performed this event46 reaction:47 type: string48 description: The only reaction that you need is a heart emoji49 item_user:50 type: string51 description: |52 User ID that created the original item that has been reacted53 to54 item:55 type: object56 properties:57 channel:58 type: string59 description: Channel information of original message60 ts:61 type: string62 description: Timestamp information of original message63 event_ts:64 type: string65 description: Reaction timestamp66 type:67 type: string68 accepts_response_payload:69 type: boolean
Additionally, you will also be adding the acknowledge schema that makes use of the envelope_id attribute to send a reply back to Slack acknowledging that event has been received.
1 acknowledge:2 type: object3 properties:4 envelope_id:5 type: string6 description: 'Unique ID of acknowledged payload'7 payload:8 type: object9 description: 'Optional payload of event'
Define acknowledge message to channel
Extend the channel the Heart-Counter used to include the acknowledge message.
1channels:2 root:3 address: /4 messages:5 hello:6 $ref: '#/components/messages/hello'7 reaction:8 $ref: '#/components/messages/reaction'9 acknowledge:10 $ref: '#/components/messages/acknowledge'
Define operations
Now you've reached the most important part of the tutorial; it's time to represent the Request/Reply pattern.
Both helloListener and reactionListener operations are set to receive events. However, in the case of reactionListener, you also want to represent the message sent back to the server. This is where the reply attribute comes into play.
Since both the request and reply function happens over the same WebSocket URL, both channel values stay the same. However, you can differentiate each operation's message by specifying the messages sent or received.
Thus, you can say that for a reaction message received over the root channel, the reactionListener operation will reply with the acknowledge message over the same channel.
1operations:2 helloListener:3 action: receive4 channel:5 $ref: '#/channels/root'6 messages:7 - $ref: '#/channels/root/messages/hello'8 reactionListener:9 action: receive10 channel:11 $ref: '#/channels/root'12 messages:13 - $ref: '#/channels/root/messages/reaction'14 reply:15 messages:16 - $ref: '#/channels/root/messages/acknowledge'17 channel:18 $ref: '#/channels/root'
Putting all this together, you have your AsyncAPI document ready to go!
1asyncapi: 3.0.02info:3 title: Implement Request/Reply in an AsyncAPI document for a Slack app4 version: 1.0.05 description: >6 The Heart-Counter manages popular messages in a Slack workspace by7 monitoring message reaction data. It also sends an acknowledgment message8 back to the Slack Server to indicate it has received the message.9servers:10 production:11 host: wss-primary.slack.com12 pathname: /link13 protocol: wss14 description: Slack's server in Socket Mode for real-time communication15channels:16 root:17 address: /18 messages:19 hello:20 $ref: '#/components/messages/hello'21 reaction:22 $ref: '#/components/messages/reaction'23 acknowledge:24 $ref: '#/components/messages/acknowledge'25 bindings:26 ws:27 query:28 type: object29 description: >-30 Tokens are produced in the WebSocket URL generated from the31 [apps.connections.open](https://api.slack.com/methods/apps.connections.open)32 method from Slack's API33 properties:34 ticket:35 type: string36 description: Temporary token generated when connection is initiated37 const: 13748dac-b866-4ea7-b98e-4fb7895c0a7f38 app_id:39 type: string40 description: Unique identifier assigned to the Slack app41 const: fe684dfa62159c6ac646beeac31c8f4ef415e4f39c626c2dbd1530e3a690892f42operations:43 helloListener:44 action: receive45 channel:46 $ref: '#/channels/root'47 messages:48 - $ref: '#/channels/root/messages/hello'49 reactionListener:50 action: receive51 channel:52 $ref: '#/channels/root'53 messages:54 - $ref: '#/channels/root/messages/reaction'55 reply:56 messages:57 - $ref: '#/channels/root/messages/acknowledge'58 channel:59 $ref: '#/channels/root'60components:61 messages:62 reaction:63 summary: Action triggered when the channel receives a new reaction-added event64 payload:65 $ref: '#/components/schemas/reaction'66 hello:67 summary: Action triggered when a successful WebSocket connection is established68 payload:69 $ref: '#/components/schemas/hello'70 acknowledge:71 summary: Acknowledgement response sent to Server72 payload:73 $ref: '#/components/schemas/acknowledge'74 schemas:75 hello:76 type: object77 properties:78 type:79 type: string80 description: A hello string confirming WebSocket connection81 connection_info:82 type: object83 properties:84 app_id:85 type: string86 num_connections:87 type: integer88 debug_info:89 type: object90 properties:91 host:92 type: string93 started:94 type: string95 build_number:96 type: integer97 approximate_connection_time:98 type: integer99 reaction:100 type: object101 properties:102 envelope_id:103 type: string104 description: 'Unique ID assigned to payload'105 payload:106 type: object107 description: 'Payload of the reaction added event'108 properties:109 token:110 type: string111 team_id:112 type: string113 event:114 type: object115 properties:116 user:117 type: string118 description: User ID who performed this event119 reaction:120 type: string121 description: The only reaction that you need is a heart emoji122 item_user:123 type: string124 description: |125 User ID that created the original item that has been reacted126 to127 item:128 type: object129 properties:130 channel:131 type: string132 description: Channel information of original message133 ts:134 type: string135 description: Timestamp information of original message136 event_ts:137 type: string138 description: Reaction timestamp139 type:140 type: string141 accepts_response_payload:142 type: boolean143 acknowledge:144 type: object145 properties:146 envelope_id:147 type: string148 description: 'Unique ID of acknowledged payload'149 payload:150 type: object151 description: 'Optional payload of event'
Summary
Great job getting to the end! In this tutorial, you learned how to create an AsyncAPI document for a use case that implemented the Request-Reply messaging pattern. Now, you can explore this pattern with sub-patterns to see how it works with real-life use cases.