Skip to content

Commit 2899201

Browse files
committed
chore: update docs
1 parent 9c29034 commit 2899201

File tree

6 files changed

+66
-7
lines changed

6 files changed

+66
-7
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ This project includes [Claude Code skills](https://docs.anthropic.com/en/docs/cl
3333
| Skill | Description |
3434
|-------|-------------|
3535
| `submit-issue` | Report bugs, request features, or ask questions |
36+
| `resolve-issue` | Investigate and resolve GitHub issues |
3637
| `test` | Run the full test suite |
37-
| `compare-repo` | Compare an external GitHub repository against connectrpc-axum |
3838

3939
### Architecture
4040

41-
See [`.claude/architecture.md`](.claude/architecture.md) for detailed documentation on the project structure, core modules, and design decisions.
41+
See [`.claude/architecture.md`](./docs/guide/architecture.md) for detailed documentation on the project structure, core modules, and design decisions.
4242

4343
## Examples
4444

docs/guide/architecture.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ These are the types you interact with when building services:
157157
| `CompressionContext` | Per-request compression context with envelope settings and full `CompressionConfig` |
158158
| `CompressionEncoding` | Supported encodings: `Gzip`, `Deflate`, `Brotli`, `Zstd`, or `Identity`. Use `codec_with_level()` for level-aware compression |
159159
| `CompressionLevel` | Compression level (re-exported from tower-http) |
160+
| `IdempotencyLevel` | Method idempotency: `Unknown`, `NoSideEffects` (enables GET), `Idempotent` |
160161
| `EnvelopeCompression` | Per-envelope compression settings for streaming RPCs |
161162
| `ContextError` | Error type for context building failures (protocol detection, header parsing) |
162163
| `BoxedCodec` | Type-erased codec storage (`Box<dyn Codec>`) for dynamic compression dispatch |
@@ -208,6 +209,8 @@ Two functions create method routers from handlers:
208209
| `post_connect(f)` | POST | Unary and streaming RPCs |
209210
| `get_connect(f)` | GET | Idempotent unary RPCs (query param encoding) |
210211

212+
For methods marked with `option idempotency_level = NO_SIDE_EFFECTS` in proto, the code generator automatically merges `get_connect()` and `post_connect()` handlers, enabling both HTTP GET and POST requests per the Connect protocol spec.
213+
211214
### How Handler Wrappers Work
212215

213216
`ConnectHandlerWrapper<F>` is a newtype that wraps a user function `F`. It has multiple `impl Handler<T, S>` blocks, each with different `where` bounds on `F`. The compiler selects the appropriate impl based on the handler signature.
@@ -341,7 +344,7 @@ For generated code to provide default "unimplemented" methods:
341344

342345
| Module | Purpose |
343346
|--------|---------|
344-
| `protocol.rs` | `RequestProtocol` enum, detection, and validation functions (`can_handle_content_type`, `can_handle_get_encoding`, `SUPPORTED_CONTENT_TYPES`) |
347+
| `protocol.rs` | `RequestProtocol` enum, `IdempotencyLevel` enum, detection, and validation functions (`can_handle_content_type`, `can_handle_get_encoding`, `SUPPORTED_CONTENT_TYPES`) |
345348
| `envelope_compression.rs` | `Codec` trait, per-envelope compression, `CompressionEncoding::codec_with_level()` for level-aware codecs |
346349
| `limit.rs` | Receive and send message size limits |
347350
| `timeout.rs` | Request timeout handling |
@@ -408,7 +411,7 @@ Method availability is enforced via trait bounds:
408411

409412
**Constraints:** `no_handlers()` and `with_tonic()` cannot be combined (enforced at compile time).
410413

411-
**Protoc Fetching:** The `fetch_protoc(version, path)` method downloads a protoc binary to the specified path using the protoc-fetcher crate. This is useful for CI environments or when a system protoc is unavailable.
414+
**Protoc Fetching:** The `fetch_protoc(version, path)` method downloads a protoc binary to the specified path using the protoc-fetcher crate. This requires the `fetch-protoc` feature flag. Useful for CI environments or when a system protoc is unavailable.
412415

413416
### Pass 1: Prost + Connect
414417

@@ -423,6 +426,9 @@ prost_build::Config
423426
- User configuration via `with_prost_config()` is applied here
424427
- All type customization (attributes, extern paths) must be done in this pass
425428
- Generated builders use the unified `post_connect()` function which auto-detects RPC type from handler signature
429+
- For methods with `idempotency_level = NO_SIDE_EFFECTS`, the generator merges `get_connect()` and `post_connect()` handlers
430+
- Generated builders expose `{METHOD}_IDEMPOTENCY` constants for each method's idempotency level
431+
- `build_connect()` convenience method wraps the router with `MakeServiceBuilder::new()`, providing default gzip compression
426432
- With `no_handlers()`, only message types are generated (no service builders)
427433
- Streaming type aliases (`BoxedCall`, `BoxedStreamCall`, etc.) are only generated for RPC patterns actually used by the service
428434

docs/guide/axum-router.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,34 @@ This serves:
8989

9090
### GET Requests
9191

92-
Use `get_connect` for idempotent RPCs to enable browser caching:
92+
#### Automatic GET Support (Recommended)
93+
94+
Mark methods with `idempotency_level = NO_SIDE_EFFECTS` in your proto file to automatically enable GET requests:
95+
96+
```protobuf
97+
rpc GetUser(GetUserRequest) returns (GetUserResponse) {
98+
option idempotency_level = NO_SIDE_EFFECTS;
99+
}
100+
```
101+
102+
The generated service builder will automatically handle both GET and POST requests:
103+
104+
```rust
105+
let router = userservice::UserServiceBuilder::new()
106+
.get_user(get_user)
107+
.build_connect(); // GET + POST automatically enabled for GetUser
108+
```
109+
110+
The code generator also exports idempotency level constants for each method:
111+
112+
```rust
113+
use your_crate::userservice::GET_USER_IDEMPOTENCY;
114+
// GET_USER_IDEMPOTENCY == IdempotencyLevel::NoSideEffects
115+
```
116+
117+
#### Manual GET Support
118+
119+
For custom routing, use `get_connect` and `post_connect`:
93120

94121
```rust
95122
use axum::Router;
@@ -100,6 +127,8 @@ let router = Router::new()
100127
get_connect(get_user).merge(post_connect(get_user)));
101128
```
102129

130+
#### GET Request Format
131+
103132
GET requests encode the message in query parameters:
104133

105134
| Parameter | Required | Description |

docs/guide/build.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1515

1616
Use `.fetch_protoc()` to automatically download the protoc compiler. This is useful when you don't want to require protoc to be installed on the build machine.
1717

18+
::: warning Feature Required
19+
The `fetch_protoc()` method requires the `fetch-protoc` feature flag:
20+
21+
```toml
22+
[build-dependencies]
23+
connectrpc-axum-build = { version = "*", features = ["fetch-protoc"] }
24+
```
25+
:::
26+
1827
```rust
1928
fn main() -> Result<(), Box<dyn std::error::Error>> {
2029
connectrpc_axum_build::compile_dir("proto")

docs/guide/compression.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
# Compression
22

3-
## Basic Usage
3+
## Default Compression
44

5-
Configure response compression using `MakeServiceBuilder`:
5+
When using `build_connect()` on a service builder, gzip compression is enabled by default:
6+
7+
```rust
8+
let router = helloworldservice::HelloWorldServiceBuilder::new()
9+
.say_hello(say_hello)
10+
.build_connect(); // Includes default gzip compression
11+
```
12+
13+
This uses `MakeServiceBuilder::new()` internally, which provides:
14+
- Default gzip compression and decompression
15+
- Standard ConnectLayer configuration
16+
17+
## Custom Configuration
18+
19+
For custom compression settings, use `MakeServiceBuilder` directly:
620

721
```rust
822
use connectrpc_axum::{MakeServiceBuilder, CompressionConfig, CompressionLevel};

docs/guide/examples.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ See the [connectrpc-axum-examples](https://github.com/washanhanzi/connectrpc-axu
1111
| `connect-client-stream` | Pure Connect client streaming |
1212
| `connect-bidi-stream` | Pure Connect bidirectional streaming |
1313
| `get-request` | GET request support for idempotent unary RPCs |
14+
| `idempotency-get` | Automatic GET support via proto `idempotency_level = NO_SIDE_EFFECTS` |
1415

1516
## Tonic/gRPC Integration
1617

0 commit comments

Comments
 (0)