Skip to content

Commit d5f1d4b

Browse files
authored
Merge pull request #1 from ServiceStack/copilot/setup-rust-project-for-servicestack
Setup Rust crate for ServiceStack HTTP client library
2 parents a9f9f0e + b18baa6 commit d5f1d4b

File tree

9 files changed

+634
-2
lines changed

9 files changed

+634
-2
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# will have compiled files and executables
33
debug
44
target
5+
Cargo.lock
56

67
# These are backup files generated by rustfmt
78
**/*.rs.bk
@@ -19,3 +20,8 @@ target
1920
# and can be added to the global gitignore or merged into this file. For a more nuclear
2021
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
2122
#.idea/
23+
24+
25+
# Added by cargo
26+
27+
/target

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [0.1.0] - 2025-11-03
9+
10+
### Added
11+
- Initial release of ServiceStack Rust HTTP Client Library
12+
- Core `ServiceStackClient` for making HTTP requests
13+
- Support for all HTTP methods: GET, POST, PUT, DELETE, PATCH
14+
- Async/await support with tokio
15+
- JSON serialization/deserialization with serde
16+
- Type-safe request/response handling
17+
- Comprehensive documentation and examples
18+
- Error handling with custom error types
19+
- Basic usage example demonstrating client functionality
20+
21+
[0.1.0]: https://github.com/ServiceStack/servicestack-rust/releases/tag/v0.1.0

Cargo.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "servicestack"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["ServiceStack, Inc."]
6+
license = "BSD-3-Clause"
7+
description = "ServiceStack HTTP Client Library for Rust"
8+
documentation = "https://docs.rs/servicestack"
9+
repository = "https://github.com/ServiceStack/servicestack-rust"
10+
homepage = "https://servicestack.net"
11+
readme = "README.md"
12+
keywords = ["servicestack", "http", "client", "api", "rest"]
13+
categories = ["web-programming::http-client", "api-bindings"]
14+
15+
[dependencies]
16+
reqwest = { version = "0.12", features = ["json"] }
17+
serde = { version = "1.0", features = ["derive"] }
18+
serde_json = "1.0"
19+
tokio = { version = "1.0", features = ["full"] }
20+
thiserror = "1.0"
21+
22+
[dev-dependencies]
23+
tokio-test = "0.4"

LICENSE

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2025, ServiceStack, Inc.
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

PUBLISHING.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# Publishing to crates.io
2+
3+
This document describes how to publish the ServiceStack Rust client library to crates.io.
4+
5+
## Prerequisites
6+
7+
1. Create an account on [crates.io](https://crates.io/)
8+
2. Get your API token from [crates.io/me](https://crates.io/me)
9+
3. Configure your token locally:
10+
```bash
11+
cargo login <your-api-token>
12+
```
13+
14+
## Pre-publication Checklist
15+
16+
Before publishing, ensure:
17+
18+
- [ ] All tests pass: `cargo test`
19+
- [ ] Documentation builds without warnings: `cargo doc --no-deps`
20+
- [ ] Package builds successfully: `cargo package`
21+
- [ ] Version number is correct in `Cargo.toml`
22+
- [ ] `CHANGELOG.md` is updated
23+
- [ ] `README.md` is accurate and up-to-date
24+
- [ ] License file exists and is correct
25+
- [ ] All code is committed and pushed to GitHub
26+
27+
## Package Verification
28+
29+
1. Build and test the package:
30+
```bash
31+
cargo build
32+
cargo test
33+
```
34+
35+
2. Verify the package contents:
36+
```bash
37+
cargo package --list
38+
```
39+
40+
3. Build the package to check for issues:
41+
```bash
42+
cargo package
43+
```
44+
45+
4. Test the packaged version:
46+
```bash
47+
cargo package
48+
cd target/package
49+
cargo test
50+
```
51+
52+
## Publishing
53+
54+
Once all checks pass, publish to crates.io:
55+
56+
```bash
57+
cargo publish
58+
```
59+
60+
This will:
61+
1. Package your crate
62+
2. Upload it to crates.io
63+
3. Make it available for download via `cargo install`
64+
65+
## Post-Publication
66+
67+
After publishing:
68+
69+
1. Create a GitHub release:
70+
- Tag: `v0.1.0`
71+
- Title: `ServiceStack Rust v0.1.0`
72+
- Description: Copy from CHANGELOG.md
73+
74+
2. Verify the package appears on crates.io:
75+
- Visit https://crates.io/crates/servicestack
76+
- Check that documentation is generated at https://docs.rs/servicestack
77+
78+
3. Test installation:
79+
```bash
80+
cargo new test-project
81+
cd test-project
82+
cargo add servicestack
83+
cargo build
84+
```
85+
86+
## Version Updates
87+
88+
For future releases:
89+
90+
1. Update version in `Cargo.toml`
91+
2. Update `CHANGELOG.md` with new changes
92+
3. Commit and push changes
93+
4. Run through the pre-publication checklist
94+
5. Publish with `cargo publish`
95+
6. Create a new GitHub release
96+
97+
## Troubleshooting
98+
99+
- **Publishing fails**: Check that all required fields in `Cargo.toml` are filled
100+
- **Documentation fails to build**: Run `cargo doc` locally to see errors
101+
- **Tests fail**: Run `cargo test` to identify and fix failing tests
102+
- **Version conflict**: Ensure version number is incremented from last published version

README.md

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,138 @@
1-
# servicestack-rust
2-
ServiceStack Client Rust Library
1+
# ServiceStack Rust Client Library
2+
3+
A Rust client library for ServiceStack services, providing type-safe HTTP communication with async/await support.
4+
5+
[![Crates.io](https://img.shields.io/crates/v/servicestack.svg)](https://crates.io/crates/servicestack)
6+
[![Documentation](https://docs.rs/servicestack/badge.svg)](https://docs.rs/servicestack)
7+
[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)
8+
9+
## Features
10+
11+
- 🚀 **Async/await support** - Built on tokio for efficient async operations
12+
- 📦 **Type-safe** - Leverages Rust's type system with serde for serialization
13+
- 🔧 **Flexible** - Support for all HTTP methods (GET, POST, PUT, DELETE, PATCH)
14+
- 🛡️ **Reliable** - Built on reqwest for robust HTTP communication
15+
- 📖 **Well-documented** - Comprehensive API documentation and examples
16+
17+
## Installation
18+
19+
Add this to your `Cargo.toml`:
20+
21+
```toml
22+
[dependencies]
23+
servicestack = "0.1.0"
24+
tokio = { version = "1.0", features = ["full"] }
25+
serde = { version = "1.0", features = ["derive"] }
26+
```
27+
28+
## Quick Start
29+
30+
```rust
31+
use servicestack::{ServiceStackClient, Result};
32+
use serde::{Deserialize, Serialize};
33+
34+
#[derive(Serialize)]
35+
struct HelloRequest {
36+
name: String,
37+
}
38+
39+
#[derive(Deserialize)]
40+
struct HelloResponse {
41+
result: String,
42+
}
43+
44+
#[tokio::main]
45+
async fn main() -> Result<()> {
46+
// Create a new client
47+
let client = ServiceStackClient::new("https://example.org");
48+
49+
// Make a POST request
50+
let request = HelloRequest {
51+
name: "World".to_string()
52+
};
53+
let response: HelloResponse = client.post("/hello", &request).await?;
54+
55+
println!("{}", response.result);
56+
Ok(())
57+
}
58+
```
59+
60+
## Usage Examples
61+
62+
### GET Request
63+
64+
```rust
65+
use servicestack::{ServiceStackClient, Result};
66+
use serde::Deserialize;
67+
68+
#[derive(Deserialize)]
69+
struct User {
70+
id: u64,
71+
name: String,
72+
}
73+
74+
async fn get_user(client: &ServiceStackClient, id: u64) -> Result<User> {
75+
client.get(&format!("/users/{}", id)).await
76+
}
77+
```
78+
79+
### POST Request
80+
81+
```rust
82+
use servicestack::{ServiceStackClient, Result};
83+
use serde::{Deserialize, Serialize};
84+
85+
#[derive(Serialize)]
86+
struct CreateUserRequest {
87+
name: String,
88+
email: String,
89+
}
90+
91+
#[derive(Deserialize)]
92+
struct CreateUserResponse {
93+
id: u64,
94+
name: String,
95+
}
96+
97+
async fn create_user(client: &ServiceStackClient) -> Result<CreateUserResponse> {
98+
let request = CreateUserRequest {
99+
name: "John Doe".to_string(),
100+
email: "john@example.com".to_string(),
101+
};
102+
client.post("/users", &request).await
103+
}
104+
```
105+
106+
### Custom Client Configuration
107+
108+
```rust
109+
use servicestack::ServiceStackClient;
110+
use reqwest::Client;
111+
use std::time::Duration;
112+
113+
let custom_client = Client::builder()
114+
.timeout(Duration::from_secs(60))
115+
.build()
116+
.unwrap();
117+
118+
let client = ServiceStackClient::with_client(
119+
"https://api.example.com",
120+
custom_client
121+
);
122+
```
123+
124+
## API Documentation
125+
126+
For detailed API documentation, visit [docs.rs/servicestack](https://docs.rs/servicestack).
127+
128+
## License
129+
130+
This project is licensed under the BSD-3-Clause License - see the LICENSE file for details.
131+
132+
## Contributing
133+
134+
Contributions are welcome! Please feel free to submit a Pull Request.
135+
136+
## About ServiceStack
137+
138+
[ServiceStack](https://servicestack.net) is a simple, fast, versatile and highly-productive full-featured Web and Web Services Framework.

examples/basic_usage.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//! Basic usage example for the ServiceStack client library
2+
//!
3+
//! This example demonstrates how to use the ServiceStack client
4+
//! to make HTTP requests to a ServiceStack service.
5+
6+
use servicestack::{ServiceStackClient, Result};
7+
use serde::{Deserialize, Serialize};
8+
9+
#[derive(Serialize, Debug)]
10+
struct HelloRequest {
11+
name: String,
12+
}
13+
14+
#[derive(Deserialize, Debug)]
15+
struct HelloResponse {
16+
result: String,
17+
}
18+
19+
#[tokio::main]
20+
async fn main() -> Result<()> {
21+
// Create a new ServiceStack client
22+
let client = ServiceStackClient::new("https://test.servicestack.net");
23+
24+
// Example 1: Simple GET request
25+
println!("Example 1: GET request");
26+
match client.get::<serde_json::Value>("/hello/World").await {
27+
Ok(response) => println!("Response: {:?}", response),
28+
Err(e) => eprintln!("Error: {}", e),
29+
}
30+
31+
// Example 2: POST request with JSON body
32+
println!("\nExample 2: POST request");
33+
let request = HelloRequest {
34+
name: "Rust".to_string(),
35+
};
36+
37+
match client.post::<_, HelloResponse>("/hello", &request).await {
38+
Ok(response) => println!("Response: {:?}", response),
39+
Err(e) => eprintln!("Error: {}", e),
40+
}
41+
42+
println!("\nExamples completed!");
43+
Ok(())
44+
}

0 commit comments

Comments
 (0)