Skip to content

Commit

Permalink
Initial
Browse files Browse the repository at this point in the history
  • Loading branch information
prasadjivane committed Mar 16, 2024
1 parent 5654906 commit 37545e9
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 145 deletions.
9 changes: 3 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
[package]
name = "rust-api-test"
description = "CLI for testing REST APIs"
description = "CLI tool for testing REST APIs"
version = "0.1.0"
edition = "2021"
license = "MIT"
authors = ["Prasad Jivane <prasadjivane@gmail.com>"]
repository = "https://github.com/prasadjivane/rust-api-test"

[dependencies]
reqwest = "0.11"
reqwest = { version = "0.11", features = ["blocking", "json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[dependencies.tokio]
version = "1.0"
features = ["full"]
tokio = { version = "1.0", features = ["full"] }
50 changes: 30 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@

<img width="714" alt="rust-api-test" src="https://github.com/prasadjivane/rust-api-test/assets/26869583/10445b8d-7bbb-46a9-bfef-e49662a9176b">
<img width="714" alt="rust-api-test" src="https://github.com/prasadjivane/rust-api-test/assets/26869583/10445b8d-7bbb-46a9-bfef-e49662a9176b">

[<img alt="github" src="https://img.shields.io/badge/Github-rust%20api%20test-blue" height="30">](https://github.com/prasadjivane/rust-api-test)
[<img alt="crates.io" src="https://img.shields.io/badge/crates.io-V0.1.0-green" height="30">](https://crates.io/crates/rust-api-test)
[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-rust%20api%20test-orange" height="30">](https://docs.rs/crate/rust-api-test)
[<img alt="releases" src="https://img.shields.io/badge/Releases%20V0.1.0-8A2BE2" height="30">](https://github.com/prasadjivane/rust-api-test/releases)



# rust-api-test

`rust-api-test` is a Rust package that provides a command-line interface (CLI) for testing REST APIs in real-time. It allows Rust developers to easily perform HTTP GET, POST, PUT, and DELETE requests from the command line.

## Features

- Supports GET, POST, PUT, and DELETE HTTP methods.
- Allows sending JSON data in the request body.
- Provides real-time feedback on the response including status code and response body.
- Simple and easy-to-use CLI interface
- Supports GET, POST, PUT, and DELETE HTTP methods
- Real-time testing of REST APIs
- JSON request and response handling

## Installation

To use rust-api-test, you need to have Rust and Cargo installed on your system. You can install them from [rustup.rs](https://rustup.rs/).

Once you have Rust and Cargo installed, you can install rust-api-test using Cargo:

```bash
cargo install rust-api-test
```

To use `rust-api-test` in your Rust project, simply add it as a dependency in your `Cargo.toml` file:

```ssh
Expand All @@ -27,32 +37,32 @@ rust-api-test = "0.1.0"

## Usage

Once installed, you can use `rust-api-test` from the command line:
`rust-api-test <method> <url> [body]`

```
rust-api-test
```
Follow the on-screen instructions to select the HTTP method, enter the URL, and provide optional JSON data for POST and PUT requests.
## Examples

## Example
Get data from an API endpoint
```bash
rust-api-test GET https://jsonplaceholder.typicode.com/posts/1
```

```Enter your choice:
1. GET
2. POST
3. PUT
4. DELETE
5. Exit
Post data to an API endpoint
```bash
rust-api-test POST https://jsonplaceholder.typicode.com/posts userId=1 title="Test Title" body="Test Body"
```

## Dependencies

- reqwest - HTTP client for Rust.
- serde_json - JSON serialization and deserialization library for Rust.
- reqwest - HTTP client for Rust.

- serde_json - JSON serialization and deserialization library for Rust.


## Contributing

Contributions are welcome! If you encounter any issues or have suggestions for improvements, feel free to open an [issue](https://github.com/prasadjivane/rust-api-test/issues) or submit a [pull](https://github.com/prasadjivane/rust-api-test/pulls) request on [GitHub](https://github.com/prasadjivane).


## License

This project is licensed under the [MIT License](https://github.com/prasadjivane/rust-api-test?tab=MIT-1-ov-file) - see the LICENSE file for details.
This project is licensed under the [MIT License](https://github.com/prasadjivane/rust-api-test?tab=MIT-1-ov-file) - see the LICENSE file for details.
27 changes: 27 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use reqwest::{Client, Result};
use serde_json::Value;
use std::collections::HashMap;

pub async fn get(url: &str) -> Result<Value> {
let response = Client::new().get(url).send().await?;
let json = response.json().await?;
Ok(json)
}

pub async fn post(url: &str, body: HashMap<&str, &str>) -> Result<Value> {
let response = Client::new().post(url).json(&body).send().await?;
let json = response.json().await?;
Ok(json)
}

pub async fn put(url: &str, body: HashMap<&str, &str>) -> Result<Value> {
let response = Client::new().put(url).json(&body).send().await?;
let json = response.json().await?;
Ok(json)
}

pub async fn delete(url: &str) -> Result<Value> {
let response = Client::new().delete(url).send().await?;
let json = response.json().await?;
Ok(json)
}
155 changes: 36 additions & 119 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,124 +1,41 @@
use std::io;
use reqwest::{Client, Response};
use serde::{Deserialize, Serialize};
mod api;
use std::collections::HashMap;
use serde_json::json;
use std::env;

fn main() {
let args: Vec<String> = env::args().collect();
if args.len() < 3 {
println!("Usage: {} <method> <url> [body]", args[0]);
return;
}

#[derive(Debug, Serialize, Deserialize)]
struct ApiResponse {
// Define the structure of the API response data
// This can vary depending on your API's response format
// For simplicity, let's assume it's JSON
}

async fn get(url: &str) -> Result<Response, reqwest::Error> {
// Implement GET method
Client::new().get(url).send().await
}

async fn post(url: &str, body: HashMap<&str, &str>) -> Result<Response, reqwest::Error> {
// Serialize the body to JSON
let body_json = json!(body);

// Send POST request with JSON body
Client::new()
.post(url)
.header("Content-Type", "application/json")
.body(body_json.to_string())
.send()
.await
}

async fn put(url: &str, body: HashMap<&str, &str>) -> Result<Response, reqwest::Error> {
// Serialize the body to JSON
let body_json = json!(body);

// Send PUT request with JSON body
Client::new()
.put(url)
.header("Content-Type", "application/json")
.body(body_json.to_string())
.send()
.await
}

async fn delete(url: &str) -> Result<Response, reqwest::Error> {
// Implement DELETE method
Client::new().delete(url).send().await
}

async fn handle_response(response: Response) -> Result<(), reqwest::Error> {
// Process and display the response
let status = response.status();
let body = response.text().await?;

println!("Status: {}", status);
println!("Body: {}", body);

Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("REST CLI Tester");

loop {
println!("Enter your choice:");
println!("1. GET");
println!("2. POST");
println!("3. PUT");
println!("4. DELETE");
println!("5. Exit");

let mut choice = String::new();
io::stdin().read_line(&mut choice)?;

match choice.trim().parse() {
Ok(1) => {
println!("Enter URL:");
let mut url = String::new();
io::stdin().read_line(&mut url)?;
let response = get(&url.trim()).await?;
handle_response(response).await?;
}
Ok(2) => {
println!("Enter URL:");
let mut url = String::new();
io::stdin().read_line(&mut url)?;

println!("Enter JSON Body:");
let mut body_str = String::new();
io::stdin().read_line(&mut body_str)?;

let body: HashMap<&str, &str> = serde_json::from_str(&body_str)?;
let response = post(&url.trim(), body).await?;
handle_response(response).await?;
}
Ok(3) => {
println!("Enter URL:");
let mut url = String::new();
io::stdin().read_line(&mut url)?;

println!("Enter JSON Body:");
let mut body_str = String::new();
io::stdin().read_line(&mut body_str)?;

let body: HashMap<&str, &str> = serde_json::from_str(&body_str)?;
let response = put(&url.trim(), body).await?;
handle_response(response).await?;
}
Ok(4) => {
println!("Enter URL:");
let mut url = String::new();
io::stdin().read_line(&mut url)?;
let response = delete(&url.trim()).await?;
handle_response(response).await?;
}
Ok(5) => break,
_ => println!("Invalid choice!"),
let method = &args[1];
let url = &args[2];

let body: HashMap<&str, &str> = if args.len() > 3 {
args[3..].iter()
.map(|s| {
let mut parts = s.split('=');
(parts.next().unwrap(), parts.next().unwrap_or(""))
})
.collect()
} else {
HashMap::new()
};

let result = match method.as_str() {
"GET" => tokio::runtime::Runtime::new().unwrap().block_on(api::get(url)),
"POST" => tokio::runtime::Runtime::new().unwrap().block_on(api::post(url, body)),
"PUT" => tokio::runtime::Runtime::new().unwrap().block_on(api::put(url, body)),
"DELETE" => tokio::runtime::Runtime::new().unwrap().block_on(api::delete(url)),
_ => {
println!("Invalid method!");
return;
}
}
};

Ok(())
}
match result {
Ok(response) => println!("{:#?}", response),
Err(e) => println!("Error: {}", e),
}
}

0 comments on commit 37545e9

Please sign in to comment.