ame_bus/
lib.rs

1#![deny(rustdoc::broken_intra_doc_links)]
2#![warn(missing_docs)]
3#![doc = include_str!("../README.md")]
4
5#[cfg(feature = "jetstream")]
6/// [JetStream](https://docs.nats.io/nats-concepts/jetstream) support.
7pub mod jetstream;
8
9#[cfg(feature = "jetstream")]
10/// [Key/Value Store](https://docs.nats.io/nats-concepts/jetstream/key-value-store) support.
11pub mod kv;
12
13/// Define the message struct using inside `ame-bus`.
14pub mod message;
15
16/// Tokio concurrency utilities.
17pub mod pool;
18
19#[cfg(feature = "service")]
20/// Service RPC support. Using just NATS core features.
21pub mod service_rpc;
22
23#[cfg(test)]
24mod tests;
25
26pub use message::{NatsJsonMessage, NatsMessage};
27
28/// # Specify the JetStream using of the struct.
29/// Usually used for a consumer or message in JetStream.
30///
31/// ## Example:
32///
33/// ```rust
34/// # use ame_bus_macros::jet;
35/// #[jet(
36///     name = "user",
37///     description = "User successful registered event",
38/// )]
39/// pub struct UserSuccessfulRegistered {
40///     pub user_id: String,
41///     pub email: String,
42/// }
43/// ```
44///
45/// ## Supported attributes
46///
47/// - `name="foo"` (required): Stream name. Must not have spaces, tabs or period . characters.
48/// - `description="foo"`: Stream description.
49/// - `max_messages=100_000`: Maximum number of messages to keep in the stream.
50/// - `max_bytes=1024`: Maximum bytes of messages
51/// - `no_ack`: Disables acknowledging messages that are received by the Stream.
52///
53/// Attention that these options only work if the stream is not created yet and the stream
54/// is created with these options.
55#[cfg(feature = "jetstream")]
56pub use ame_bus_macros::jet;
57
58/// # Configure the JetStream consumer.
59///
60/// Must implement [NatsJetStreamMeta](crate::jetstream::NatsJetStreamMeta) trait first.
61///
62/// ## Example
63///
64/// ```rust
65/// # use ame_bus_macros::{jet, jet_consumer};
66/// #[jet(
67///      name = "user",
68///      description = "User successful registered event consumer",
69/// )]
70/// #[jet_consumer(
71///    name = "user-successful-registered-consumer",
72///    durable,
73///    filter_subject = "user.registered",
74/// )]
75/// pub struct UserSuccessfulRegisteredConsumer {
76///     database_connection: (),    // use `()` for example, should be a real connection
77/// }
78/// ```
79///
80/// ## Supported attributes
81///
82/// - `name="foo"`: Consumer name. If the consumer is durable, it will also be the durable name. Default to the struct name in snake case.
83/// - `push`: Use push-based consumer. Cannot be used with `pull`.
84/// - `pull`: Use pull-based consumer. Cannot be used with `push`. Default if neither `push` nor `pull` is specified.
85/// - `durable`: Create a durable consumer. Default is false.
86/// - `durable_name="foo"`: Durable name. If not specified, the consumer name is used.
87/// - `deliver_policy="all"|"last"|"new"|"last_per_subject"`: Delivery policy. Default is `all`.
88/// - `ack_policy="explicit"|"all"|"none"`: Acknowledgement policy. Default is `explicit`.
89/// - `ack_wait_secs=10`: Acknowledgement wait time in seconds.
90/// - `filter_subject="foo.bar"`: Filter messages by subject. Allow wildcards.
91/// - `headers_only`: Let payload be empty and only headers are delivered.
92///
93/// only with pull consumer:
94/// - `max_batch=10`: Maximum number of messages to fetch in a batch.
95///
96/// only with push consumer:
97/// - `deliver_subject="foo.bar"`: Subject to deliver messages to.
98/// - `deliver_group="foo"`: Consumer group to deliver messages to.
99///
100/// ## Example:
101///
102/// ```rust
103/// # use ame_bus_macros::*;
104/// #[jet(name = "mail", description = "Mail service")]
105/// #[jet_consumer(pull, durable, filter_subject="mail.send")]
106/// struct EmailSendEventConsumer {
107///     smtp_connection: (),
108///     email_template: String,
109/// }
110/// ```
111#[cfg(feature = "jetstream")]
112pub use ame_bus_macros::jet_consumer;
113
114/// Implement [NatsJsonMessage](crate::message::NatsJsonMessage) trait if it has already
115/// implemented `Serialize` and `Deserialize` traits.
116///
117/// example:
118/// ```rust
119/// # use serde::{Deserialize, Serialize};
120/// # use ame_bus_macros::NatsJsonMessage;
121/// #[derive(Serialize, Deserialize, NatsJsonMessage)]
122/// pub struct User {
123///    pub id: String,
124///    pub name: String,
125/// }
126/// ```
127pub use ame_bus_macros::NatsJsonMessage;
128
129/// # RPC Service
130/// 
131/// Mark a struct as an RPC service.
132/// 
133/// ## Example
134/// ```rust
135/// # use ame_bus_macros::rpc_service;
136/// #[rpc_service(
137///     name = "user.info",
138///     version = "0.1.0",
139/// )]
140/// pub struct UserInfoService {
141///     // fields, like database connection
142/// }
143/// ```
144/// 
145/// ## Supported attributes
146/// 
147/// - `name="foo"` (required): Service name. Can be a NATS path.
148/// - `description="foo"`: Service description.
149/// - `version="0.1.0"`: Service version. Default is `0.1.0`.
150/// - `queue_group="foo"`: Queue group name.
151/// 
152/// Usually, you need to set the `queue_group` to make the service scaled properly.
153#[cfg(feature = "service")]
154pub use ame_bus_macros::rpc_service;
155
156/// # RPC Route Register
157///
158/// Register the route, and implement the [PooledApp](pool::PooledApp) trait.
159///
160/// ## Usage
161///
162/// Use an enum as route table, mark the enum with `#[rpc_route()]` attribute.
163///
164/// `#[rpc_route()]` must have these args:
165///
166/// - `service`: The service struct name.
167/// - `nats_connection`: The NATS connection, should be `&async_nats::Client`.
168///
169/// *To avoid lifetime issue, use `&'static async_nats::Client` with `OnceCell<Client>` is suggested.*
170///
171/// To register the requests, each variant in enum must have `#[rpc_endpoint()]` attribute.
172///
173/// `#[rpc_endpoint(request = "RequestName")]` must have these args:
174///
175/// - `request`: the request, must implement [NatsRpcRequest](crate::service_rpc::NatsRpcRequest) trait.
176///
177/// ## Example
178///
179/// ```rust
180/// # use ame_bus_macros::*;
181/// # use ame_bus::service_rpc::NatsRpcRequestMeta;
182/// use tokio::sync::OnceCell;
183/// use serde::{Deserialize, Serialize};
184/// use ame_bus::service_rpc::NatsRpcRequest;
185///
186/// // don't forget to set up the NATS connection
187/// static NATS_CONNECTION: OnceCell<async_nats::Client> = OnceCell::const_new();
188/// 
189/// #[rpc_service(
190///     name = "user.info",
191///     version = "0.1.0",
192/// )]
193/// pub struct UserInfoService {
194///     // fields, like database connection
195/// }
196///
197/// #[derive(Debug, Clone, Serialize, Deserialize, NatsJsonMessage)]
198/// struct UserAvatarReq {
199///     user_id: String,
200/// }
201/// 
202/// # impl NatsRpcRequestMeta for UserAvatarReq {
203/// #     const ENDPOINT_NAME: &'static str = "avatar";
204/// #     type Service = UserInfoService;
205/// # }
206///
207/// #[async_trait::async_trait]
208/// impl NatsRpcRequest for UserAvatarReq {
209///     type Response = ();
210///
211///     async fn process_request(service_state: &Self::Service, request: Self) -> anyhow::Result<Self::Response> {
212///         Ok(())
213///     }
214/// }
215///
216/// #[derive(Debug, Clone, Serialize, Deserialize, NatsJsonMessage)]
217/// struct UserMetaReq {
218///     user_id: String,
219/// }
220/// 
221/// # impl NatsRpcRequestMeta for UserMetaReq {
222/// #     const ENDPOINT_NAME: &'static str = "meta";
223/// #     type Service = UserInfoService;
224/// # }
225/// 
226/// #[async_trait::async_trait]
227/// impl NatsRpcRequest for UserMetaReq {
228///     type Response = ();
229///     async fn process_request(service_state: &Self::Service, request: Self) -> anyhow::Result<Self::Response> {
230///         Ok(())
231///     }
232/// }
233///
234/// #[rpc_route(service="UserInfoService", nats_connection="NATS_CONNECTION.get().unwrap()")]
235/// enum UserInfoRoute {
236///     #[rpc_endpoint(request="UserAvatarReq")]
237///     UserAvatar,
238///     #[rpc_endpoint(request="UserMetaReq")]
239///     UserMeta,
240/// }
241/// ```
242#[cfg(feature = "service")]
243pub use ame_bus_macros::rpc_route;
244
245/// Implement [NatsCoreMessageSendTrait](crate::message::NatsCoreMessageSendTrait) for the struct.
246/// 
247/// Must implement [NatsMessage](crate::message::NatsMessage) and 
248/// [DynamicSubjectNatsMessage](crate::message::DynamicSubjectNatsMessage) first.
249pub use ame_bus_macros::DeriveCoreMessageSend;
250
251#[cfg(feature = "jetstream")]
252/// Implement [JetStreamMessageSendTrait](crate::message::JetStreamMessageSendTrait) for the struct.
253/// 
254/// Must implement [NatsMessage](crate::message::NatsMessage) and 
255/// [DynamicSubjectNatsMessage](crate::message::DynamicSubjectNatsMessage) first.
256pub use ame_bus_macros::DeriveJetMessageSend;
257
258/// Implement [StaticSubjectNatsMessage](crate::message::StaticSubjectNatsMessage) for the struct.
259/// 
260/// The subject must be static. Implement [StaticSubjectNatsMessage](crate::message::StaticSubjectNatsMessage)
261/// will also implement [DynamicSubjectNatsMessage](crate::message::DynamicSubjectNatsMessage) for the struct.
262/// 
263/// usage: 
264/// 
265/// ```rust
266/// # use ame_bus_macros::nats_message;
267/// #[nats_message(subject = "user.registered")]
268/// pub struct UserRegistered {}
269/// ```
270pub use ame_bus_macros::nats_message;
271
272pub use tracing;
273pub use futures;