Skip to content

Commit 74d3591

Browse files
docs: Improve the documentation page with Response class (#2238)
* Improve docs * docs: generate API References * Add information about `NatsResponse` class * docs: generate API References * Correct response headers, revert example structure * Added documentation for other brokers * docs: generate API References * docs: polish style and text --------- Co-authored-by: Nikita Pastukhov <[email protected]>
1 parent a25c2e0 commit 74d3591

File tree

3 files changed

+279
-13
lines changed

3 files changed

+279
-13
lines changed

docs/docs/en/nats/rpc.md

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,10 @@ Just send a message like a regular one and get a response synchronously.
2323

2424
It is very close to the common **requests** syntax:
2525

26-
```python hl_lines="3"
26+
```python linenums="1" hl_lines="3"
2727
from faststream.nats import NatsMessage
2828

29-
msg: NatsMessage = await broker.request(
30-
"Hi!",
31-
subject="test",
32-
)
29+
msg: NatsMessage = await broker.request("Hello, NATS!", subject="test")
3330
```
3431

3532
## Reply-To
@@ -38,7 +35,7 @@ Also, if you want to create a permanent request-reply data flow, probably, you s
3835

3936
So, if you have such one, you can specify it with the `reply_to` argument. This way, **FastStream** will send a response to this subject automatically.
4037

41-
```python hl_lines="1 8"
38+
```python linenums="1" hl_lines="1 8"
4239
@broker.subscriber("response-subject")
4340
async def consume_responses(msg):
4441
...
@@ -49,3 +46,89 @@ await broker.publish(
4946
reply_to="response-subject",
5047
)
5148
```
49+
50+
## Creating an RPC subscriber
51+
52+
To handle an RPC request, you need to create a subscriber that processes the incoming message and returns a response.
53+
The subscriber should be decorated with `#!python @broker.subscriber` and return either a raw value or a `Response` object.
54+
55+
Below is an example of a simple RPC subscriber that processes a message and returns a response.
56+
57+
```python linenums="1" hl_lines="7"
58+
from faststream.nats import NatsBroker
59+
60+
broker = NatsBroker()
61+
62+
@broker.subscriber("test")
63+
async def handle(msg):
64+
return f"Received: {msg}"
65+
```
66+
67+
When the client sends a request like this:
68+
69+
```python linenums="1" hl_lines="3"
70+
from faststream.nats import NatsMessage
71+
72+
msg: NatsMessage = await broker.request("Hello, NATS!", subject="test")
73+
assert msg.body == b"Received: Hello, NATS!"
74+
```
75+
76+
The subscriber processes the request and sends back the response, which is received by the client.
77+
78+
!!! tip
79+
You can use the `no_reply=True` flag in the `#!python @broker.subscriber` decorator to suppress automatic RPC and `reply_to` responses.
80+
This is useful when you want the subscriber to process the message without sending a response back to the client.
81+
82+
## Using the Response class
83+
84+
The `Response` class allows you to attach metadata, such as headers, to the response message.
85+
This is useful for adding context or tracking information to your responses.
86+
87+
Below is an example of how to use the `Response` class in an RPC subscriber.
88+
89+
```python linenums="1" hl_lines="1 8-12"
90+
from faststream import Response
91+
from faststream.nats import NatsBroker
92+
93+
broker = NatsBroker()
94+
95+
@broker.subscriber("test")
96+
async def handle(msg):
97+
return Response(
98+
body=f"Processed: {msg}",
99+
headers={"x-token": "some-token"},
100+
correlation_id="some-correlation-id",
101+
)
102+
```
103+
104+
When the client sends a request:
105+
106+
```python linenums="1" hl_lines="4-6"
107+
from faststream.nats import NatsMessage
108+
109+
msg: NatsMessage = await broker.request("Hello, NATS!", subject="test")
110+
assert msg.body == b"Processed: Hello, NATS!"
111+
assert msg.headers == {"x-token": "some-token"}
112+
assert msg.correlation_id == "some-correlation-id"
113+
```
114+
115+
## Using the NatsResponse class
116+
117+
For NATS-specific use cases, you can use the `NatsResponse` class instead of the generic `Response` class.
118+
119+
The `NatsResponse` class extends `Response` and adds support for specifying a `stream` parameter. This ensures the response is published to the correct stream in a JetStream context.
120+
121+
```python linenums="1" hl_lines="1 7-13"
122+
from faststream.nats import NatsBroker, NatsResponse
123+
124+
broker = NatsBroker()
125+
126+
@broker.subscriber("test", stream="stream")
127+
async def handle(msg):
128+
return NatsResponse(
129+
body=f"Processed: {msg}",
130+
headers={"x-token": "some-token"},
131+
correlation_id="some-correlation-id",
132+
stream="stream",
133+
)
134+
```

docs/docs/en/rabbit/rpc.md

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,10 @@ Just send a message like a regular one and get a response synchronously.
2020

2121
It is very close to common **requests** syntax:
2222

23-
```python hl_lines="3"
23+
```python linenums="1" hl_lines="3"
2424
from faststream.rabbit import RabbitMessage
2525

26-
msg: RabbitMessage = await broker.request(
27-
"Hi!",
28-
queue="test",
29-
)
26+
msg: RabbitMessage = await broker.request("Hello, RabbitMQ!", queue="test")
3027
```
3128

3229
## Reply-To
@@ -35,14 +32,106 @@ Also, if you want to create a permanent request-reply data flow, probably, you s
3532

3633
So, if you have such one, you can specify it with the `reply_to` argument. This way, **FastStream** will send a response to this queue automatically.
3734

38-
```python hl_lines="1 8"
35+
```python linenums="1" hl_lines="1 8"
3936
@broker.subscriber("response-queue")
4037
async def consume_responses(msg):
4138
...
4239

4340
await broker.publish(
44-
"Hi!",
41+
"Hello, RabbitMQ!",
4542
queue="test",
4643
reply_to="response-queue",
4744
)
4845
```
46+
47+
## Creating an RPC subscriber
48+
49+
To handle an RPC request, you need to create a subscriber that processes the incoming message and returns a response.
50+
The subscriber should be decorated with `#!python @broker.subscriber` and return either a raw value or a `Response` object.
51+
52+
Below is an example of a simple RPC subscriber that processes a message and returns a response.
53+
54+
```python linenums="1" hl_lines="7"
55+
from faststream.rabbit import RabbitBroker
56+
57+
broker = RabbitBroker()
58+
59+
@broker.subscriber("test")
60+
async def handle(msg):
61+
return f"Received: {msg}"
62+
```
63+
64+
When the client sends a request like this:
65+
66+
```python linenums="1" hl_lines="3"
67+
from faststream.rabbit import RabbitMessage
68+
69+
msg: RabbitMessage = await broker.request("Hello, RabbitMQ!", queue="test")
70+
assert msg.body == b"Received: Hello, RabbitMQ!"
71+
```
72+
73+
The subscriber processes the request and sends back the response, which is received by the client.
74+
75+
!!! tip
76+
You can use the `no_reply=True` flag in the `#!python @broker.subscriber` decorator to suppress automatic RPC and `reply_to` responses.
77+
This is useful when you want the subscriber to process the message without sending a response back to the client.
78+
79+
## Using the Response class
80+
81+
The `Response` class allows you to attach metadata, such as headers, to the response message.
82+
This is useful for adding context or tracking information to your responses.
83+
84+
Below is an example of how to use the `Response` class in an RPC subscriber.
85+
86+
```python linenums="1" hl_lines="1 8-12"
87+
from faststream import Response
88+
from faststream.rabbit import RabbitBroker
89+
90+
broker = RabbitBroker()
91+
92+
@broker.subscriber("test")
93+
async def handle(msg):
94+
return Response(
95+
body=f"Processed: {msg}",
96+
headers={"x-token": "some-token"},
97+
correlation_id="some-correlation-id",
98+
)
99+
```
100+
101+
When the client sends a request:
102+
103+
```python linenums="1" hl_lines="4-6"
104+
from faststream.rabbit import RabbitMessage
105+
106+
msg: RabbitMessage = await broker.request("Hello, RabbitMQ!", queue="test")
107+
assert msg.body == b"Processed: Hello, RabbitMQ!"
108+
assert msg.headers == {"x-token": "some-token"}
109+
assert msg.correlation_id == "some-correlation-id"
110+
```
111+
112+
## Using the RabbitResponse class
113+
114+
For RabbitMQ-specific use cases, you can use the `RabbitResponse` class instead of the generic `Response` class.
115+
116+
The `RabbitResponse` class extends `Response` and adds support for RabbitMQ-specific message properties, such as `message_id`, `priority`, `expiration`, and more.
117+
118+
This is particularly useful when you need fine-grained control over the message properties in a RabbitMQ context.
119+
120+
Below is an example of how to use the `RabbitResponse` class in an RPC subscriber.
121+
122+
```python linenums="1" hl_lines="1 7-14"
123+
from faststream.rabbit import RabbitBroker, RabbitResponse
124+
125+
broker = RabbitBroker()
126+
127+
@broker.subscriber("test")
128+
async def handle(msg):
129+
return RabbitResponse(
130+
body=f"Processed: {msg}",
131+
headers={"x-token": "some-token"},
132+
correlation_id="some-correlation-id",
133+
message_id="unique-message-id",
134+
priority=1,
135+
mandatory=True,
136+
)
137+
```

docs/docs/en/redis/rpc.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,97 @@ Combining all the code snippets above, here is the complete example of how to se
5656
```
5757

5858
By embracing **Redis** RPC with **FastStream**, you can build sophisticated message-based architectures that require direct feedback from message processors. This feature is particularly suitable for cases where immediate processing is necessary or calling functions across different services is essential.
59+
60+
## Creating an RPC subscriber
61+
62+
To handle an RPC request, you need to create a subscriber that processes the incoming message and returns a response.
63+
The subscriber should be decorated with `#!python @broker.subscriber` and return either a raw value or a `Response` object.
64+
65+
Below is an example of a simple RPC subscriber that processes a message and returns a response.
66+
67+
```python linenums="1" hl_lines="7"
68+
from faststream.redis import RedisBroker
69+
70+
broker = RedisBroker()
71+
72+
@broker.subscriber(channel="test-channel")
73+
async def handle(msg):
74+
return f"Received: {msg}"
75+
```
76+
77+
When the client sends a request like this:
78+
79+
```python linenums="1" hl_lines="3"
80+
from faststream.redis import RedisMessage
81+
82+
msg: RedisMessage = await broker.request(
83+
"Hello, Redis!",
84+
channel="test-channel",
85+
)
86+
assert await msg.decode() == "Received: Hello, Redis!"
87+
```
88+
89+
The subscriber processes the request and sends back the response, which is received by the client.
90+
91+
!!! tip
92+
You can use the `no_reply=True` flag in the `#!python @broker.subscriber` decorator to suppress automatic RPC and `reply_to` responses.
93+
This is useful when you want the subscriber to process the message without sending a response back to the client.
94+
95+
## Using the Response class
96+
97+
The `Response` class allows you to attach metadata, such as headers, to the response message.
98+
This is useful for adding context or tracking information to your responses.
99+
100+
Below is an example of how to use the `Response` class in an RPC subscriber.
101+
102+
```python linenums="1" hl_lines="1 8-12"
103+
from faststream import Response
104+
from faststream.redis import RedisBroker
105+
106+
broker = RedisBroker()
107+
108+
@broker.subscriber(channel="test-channel")
109+
async def handle(msg):
110+
return Response(
111+
body=f"Processed: {msg}",
112+
headers={"x-token": "some-token"},
113+
correlation_id="some-correlation-id",
114+
)
115+
```
116+
117+
When the client sends a request:
118+
119+
```python linenums="1" hl_lines="7-9"
120+
from faststream.redis import RedisMessage
121+
122+
msg: RedisMessage = await broker.request(
123+
"Hello, Redis!",
124+
channel="test-channel",
125+
)
126+
assert msg.body == b"Processed: Hello, Redis!"
127+
assert msg.headers == {"x-token": "some-token"}
128+
assert msg.correlation_id == "some-correlation-id"
129+
```
130+
131+
## Using the RedisResponse class
132+
133+
For Redis-specific use cases, you can use the `RedisResponse` class instead of the generic `Response` class.
134+
135+
The `RedisResponse` class extends `Response` and adds support for specifying a `maxlen` parameter, which is useful when publishing responses to a Redis stream to limit the stream's length. This option could be helpful with Reply-To feature, when reply-to destination is a Redis stream.
136+
137+
Below is an example of how to use the RedisResponse class in an RPC subscriber.
138+
139+
```python linenums="1" hl_lines="1 7-12"
140+
from faststream.redis import RedisBroker, RedisResponse
141+
142+
broker = RedisBroker()
143+
144+
@broker.subscriber(stream="test-stream")
145+
async def handle(msg):
146+
return RedisResponse(
147+
body=f"Processed: {msg}",
148+
headers={"x-token": "some-token"},
149+
correlation_id="some-correlation-id",
150+
maxlen=1000,
151+
)
152+
```

0 commit comments

Comments
 (0)