Skip to main content

conreg_feign_macro/
lib.rs

1//! # Conreg Feign
2//!
3//! This crate provides procedural macros for creating Feign-like declarative HTTP clients.
4//!
5//! # Feign Client Macro
6//!
7//! Used to create declarative HTTP clients similar to Java Feign. By annotating a trait with this macro,
8//! implementation code for HTTP requests is automatically generated, enabling RESTful communication between microservices.
9//!
10//! ## Parameters
11//!
12//! - `service_id`: **Required**, the unique identifier of the service, used for service discovery and load balancing.
13//! - `base_path`: *Optional*, the base path prefix that will be prepended to all request paths.
14//! - `url`: *Optional*, directly specifies the base URL for requests; if set, `service_id` and `base_path` will be ignored.
15//!
16//! Example:
17//! ```rust
18//! #[feign_client(service_id = "user-service", base_path = "/api")]
19//! trait UserService{
20//!   #[get("/api/users/{id}")]
21//!   async fn get_user(&self, id: i32) -> Result<String, FeignError>;
22//!
23//!   // ... other methods
24//! }
25//!
26//! // Then, you can use the generated client like this:
27//! let client = UserServiceImpl::default();
28//! let user = client.get_user(1).await?;
29//! ```
30//!
31//! # Http Method Macros
32//!
33//! ## Supported HTTP Method Annotations
34//!
35//! - `#[get]`
36//! - `#[post]`
37//! - `#[put]`
38//! - `#[delete]`
39//! - `#[patch]`
40//!
41//! ## Parameter Binding Methods
42//!
43//! ### Path Parameters
44//! Use `{param_name}` placeholders in the path. When a method parameter name matches the placeholder name, it is automatically bound.
45//!
46//! Example:
47//! ```rust
48//! #[get("/api/users/{id}")]
49//! async fn ip(&self, id: i32) -> Result<String, FeignError>;
50//! ```
51//!
52//! ### Query Parameters
53//! Use `query = "{param}"` to specify query parameter templates.
54//!
55//! Example:
56//! ```rust
57//! #[get(path = "/api/users", query = "id={id}")]
58//! async fn query(&self, id: i32) -> Result<String, FeignError>;
59//! ````
60//!
61//! ### Form Parameters
62//! Use `form = "{param}"` to specify form data, supporting `application/x-www-form-urlencoded` and `multipart/form-data`.
63//!
64//! Example:
65//! ```rust
66//! #[post(path = "/api/login", form = "{loginForm}")]
67//! async fn login(&self, loginForm: reqwest::multipart::Form) -> Result<String, FeignError>;
68//! ```
69//!
70//! ### Body Parameter
71//! Use `body = "{param}"` to specify the raw string body.
72//!
73//! Example:
74//! ```rust
75//! #[post(path = "/api/post", body = "{data}")]
76//! async fn post(&self, data: String) -> Result<String, FeignError>;
77//! ```
78//!
79//! ### JSON Parameter
80//! Use `json = "{param}"` to specify JSON data; it will be automatically serialized and `Content-Type: application/json` will be set.
81//!
82//! Note: need serde_json
83//!
84//! Example:
85//! ```rust
86//! #[post(path = "/api/post", json = "{data}")]
87//! async fn post(&self, data: serde_json::Value) -> Result<String, FeignError> {}
88//! ```
89//!
90//! ### Header Parameter
91//! Use `headers("Key=Value", ...)` or `headers("Key={param}", ...)` to specify request headers, supporting both static values and dynamic parameters.
92//!
93//! Example:
94//! ```rust
95//! #[get(path = "/api/users", headers("Authorization: Bearer {token}", "Accept: application/json"))]
96//! async fn get_users(&self, token: String) -> Result<String, FeignError>
97//! ```
98
99use proc_macro::TokenStream;
100
101mod feign_client;
102
103#[proc_macro_attribute]
104pub fn feign_client(args: TokenStream, input: TokenStream) -> TokenStream {
105    feign_client::feign_client_impl(args, input)
106}
107
108/// GET request annotation
109#[proc_macro_attribute]
110pub fn get(_args: TokenStream, input: TokenStream) -> TokenStream {
111    input
112}
113
114/// POST request annotation
115#[proc_macro_attribute]
116pub fn post(_args: TokenStream, input: TokenStream) -> TokenStream {
117    input
118}
119
120/// PUT request annotation
121#[proc_macro_attribute]
122pub fn put(_args: TokenStream, input: TokenStream) -> TokenStream {
123    input
124}
125
126/// DELETE request annotation
127#[proc_macro_attribute]
128pub fn delete(_args: TokenStream, input: TokenStream) -> TokenStream {
129    input
130}
131
132/// PATCH request annotation
133#[proc_macro_attribute]
134pub fn patch(_args: TokenStream, input: TokenStream) -> TokenStream {
135    input
136}