{"id":15973417,"url":"https://github.com/TeaEntityLab/httpAPIService","last_synced_at":"2025-05-13T04:33:08.466Z","repository":{"id":62440276,"uuid":"389692873","full_name":"TeaEntityLab/httpAPIService","owner":"TeaEntityLab","description":"A Retrofit inspired implementation for Rust ","archived":false,"fork":false,"pushed_at":"2021-08-23T01:39:41.000Z","size":236,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-24T01:42:28.179Z","etag":null,"topics":["api","api-client","api-service","binding","http","http-client","hyper","multipart","retrofit","rust","rust-lang","rustlang"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TeaEntityLab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-26T16:06:59.000Z","updated_at":"2023-08-27T09:13:50.000Z","dependencies_parsed_at":"2022-11-01T21:50:12.883Z","dependency_job_id":null,"html_url":"https://github.com/TeaEntityLab/httpAPIService","commit_stats":null,"previous_names":["teaentitylab/hyperapiservice"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FhttpAPIService","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FhttpAPIService/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FhttpAPIService/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TeaEntityLab%2FhttpAPIService/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TeaEntityLab","download_url":"https://codeload.github.com/TeaEntityLab/httpAPIService/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253877265,"owners_count":21977632,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","api-client","api-service","binding","http","http-client","hyper","multipart","retrofit","rust","rust-lang","rustlang"],"created_at":"2024-10-07T21:04:49.995Z","updated_at":"2025-05-13T04:33:06.524Z","avatar_url":"https://github.com/TeaEntityLab.png","language":"Rust","readme":"# httpAPIService\n\n[![tag](https://img.shields.io/github/tag/TeaEntityLab/httpAPIService.svg)](https://github.com/TeaEntityLab/httpAPIService)\n[![Crates.io](https://img.shields.io/crates/d/http_api_service.svg)](https://crates.io/crates/http_api_service)\n[![Travis CI Build Status](https://api.travis-ci.org/TeaEntityLab/httpAPIService.svg?branch=master)](https://travis-ci.org/TeaEntityLab/httpAPIService)\n[![docs](https://img.shields.io/badge/docs-online-5023dd.svg)](https://docs.rs/http_api_service/)\n\n[![license](https://img.shields.io/github/license/TeaEntityLab/httpAPIService.svg?style=social\u0026label=License)](https://github.com/TeaEntityLab/httpAPIService)\n[![stars](https://img.shields.io/github/stars/TeaEntityLab/httpAPIService.svg?style=social\u0026label=Stars)](https://github.com/TeaEntityLab/httpAPIService)\n[![forks](https://img.shields.io/github/forks/TeaEntityLab/httpAPIService.svg?style=social\u0026label=Fork)](https://github.com/TeaEntityLab/httpAPIService)\n\n\nA Retrofit inspired implementation for Rust.\n\n# Why\n\nI love Retrofit(for java), WebServiceAPI-style coding.\n\nHowever it's hard to implement them in Rust, and there're few libraries to achieve parts of them.\n\nThus I implemented httpAPIService. I hope you would like it :)\n\n\n# Features\n\n* Retrofit-like API for WebService Restful API\n  * Engine:\n    * Hyper **feature: for_hyper**\n    * Ureq **feature: for_ureq**\n    * *`\u003c To Be Continued I \\ I /`* ...\n  * Common:\n    * Intercept the request: *`InterceptorFunc`* (struct) / *`Interceptor`* (trait)\n    * Shared Connection Timeout: *`set_timeout_millisecond()`*\n    * Shared Default Header: *`set_default_header()`*\n    * Shared Client: *`set_client()`*\n  * Request:\n    * Serialize Struct to hyper HTTPBody: *`BodySerializer`* (trait)\n  * Response:\n    * Deserialize hyper HTTPBody to Struct: *`BodyDeserializer`* (trait)\n* Optional:\n  * *`SerdeJsonSerializer`*/*`SerdeJsonDeserializer`* **feature: for_serde**\n  * *`MultipartSerializer`* **feature: multipart**\n\nNote:\n* If you want to bypass\n  * Serialization, you can use *`DummyBypassSerializerForBody`*/*`DummyBypassSerializerForBytes`*/*`DummyBypassSerializerForBytesToBody`*\n  * Deserialization, you can use *`DummyBypassDeserializer`*\n\n# Dependencies\n\n```toml\n[features]\ndefault = [\n  \"for_hyper\", \"multipart\", \"for_serde\"\n]\nfor_hyper = [ \"hyper\", \"tokio\", \"http\" ]\nfor_ureq = [ \"ureq\" ]\nmultipart = [ \"formdata\", \"multer\", \"mime\" ]\nfor_serde = [ \"serde\", \"serde_json\" ]\npure = []\n\n[dependencies]\n\n# Required\nbytes = \"^1.0.0\"\nurl=\"^2.2.0\"\nfutures = { version = \"0.3\", default-features = false, features = [\"thread-pool\"] }\n\n# for_hyper\nhyper = { version = \"^0.14.0\", optional = true, features = [\"client\", \"http1\", \"http2\", \"stream\", \"tcp\",] }\ntokio = { version = \"^1.8.0\", optional = true,features = [\"time\", \"macros\",] }\nhttp = { version = \"^0.2.4\", optional = true, }\n\n# for_ureq\nureq = { version = \"^2.1.0\", optional = true, features = [\"tls\",] }\n\n# multipart\nformdata = { version = \"^0.13.0\", optional = true }\nmulter = { version = \"^2.0.0\", optional = true }\nmime = { version = \"^0.3.0\", optional = true }\n\n# for_serde\nserde = { version = \"^1.0\", features = [\"derive\"], optional = true }\nserde_json = { version = \"^1.0\", optional = true }\n```\n\n# Usage\n\n## Setup: BaseURL/Timeout/Header, Intercept/Serializer/Deserializer\n\nExample:\n\n```rust\n\nuse std::sync::Arc;\n\nuse http::method::Method;\nuse hyper::HeaderMap;\n\nuse http_api_service::bind_hyper;\nuse http_api_service::path_param;\nuse http_api_service::simple_api;\nuse http_api_service::simple_api::{\n    DEFAULT_SERDE_JSON_DESERIALIZER, DEFAULT_SERDE_JSON_SERIALIZER,\n};\n\nuse serde::{Deserialize, Serialize};\n#[derive(Serialize, Deserialize, Debug)]\nstruct Product {\n    name: String,\n    age: String,\n}\nimpl Default for Product {\n    fn default() -\u003e Self {\n        return Product {\n            name: \"\".to_string(),\n            age: \"\".to_string(),\n        };\n    }\n}\n\nlet json_serializer = Arc::new(DEFAULT_SERDE_JSON_SERIALIZER);\nlet json_deserializer = Arc::new(DEFAULT_SERDE_JSON_DESERIALIZER);\nlet return_type_marker = \u0026Product::default();\n\nlet common_api = bind_hyper::CommonAPI::new_for_hyper();\nlet mut base_service_setter = common_api.as_base_service_setter();\nlet base_service_shared = common_api.as_base_service_shared();\n\n// Setup base_url\nbase_service_setter.set_base_url(url::Url::parse(\"http://localhost:3000\").ok().unwrap());\n// Setup timeout_millisecond\nbase_service_setter.set_timeout_millisecond(10 * 1000);\n\n// Add common headers for Authentication or other usages\nlet mut header_map = match base_service_setter.get_default_header() {\n    Some(header) =\u003e header,\n    None =\u003e HeaderMap::new(),\n};\nheader_map = bind_hyper::add_header_authentication_bearer(header_map, \"MY_TOKEN\")\n    .ok()\n    .unwrap();\nbase_service_setter.set_default_header(Some(header_map));\n\n// Add interceptor for observing Requests before connections\nbase_service_setter.add_interceptor_fn(|req| {\n    println!(\"REQ_CONTENT: {:?}\", req);\n    Ok(())\n});\n\n```\n\n## GET/POST\n\nExample:\n\n```rust\n\n// GET\nlet api_get_product = base_service_shared.make_api_no_body(\n    base_service_shared.clone(),\n    Method::GET,\n    \"/products/{id}\",\n    json_deserializer.clone(),\n    return_type_marker,\n);\n\n// NOTE: You can use the HashMap\u003cString, String\u003e directly\n// or path_param![\"key1\" =\u003e \"val1\", \"key2\" =\u003e \"val2\"])\n\n// let path_param = [(\"id\".into(), \"3\".into())]\n//     .iter()\n//     .cloned()\n//     .collect::\u003csimple_api::PathParam\u003e();\nlet resp = api_get_product.call(Some(path_param![\"id\" =\u003e \"3\"])).await;\nlet model = resp.ok().unwrap(); // The deserialized model Product is here.\n\n// POST\n\nlet api_post_product = base_service_shared.make_api_has_body(\n    base_service_shared.clone(),\n    Method::POST,\n    \"/products/{id}\",\n    \"application/json\",\n    json_serializer.clone(),\n    json_deserializer.clone(),\n    return_type_marker,\n);\n\nlet sent_body = Product {\n    name: \"Alien \".to_string(),\n    age: \"5 month\".to_string(),\n};\nlet resp = api_post_product\n    .call(Some(path_param![\"id\" =\u003e \"5\"]), sent_body)\n    .await;\nlet model = resp.ok().unwrap();\n\n```\n\n## Multipart\n\nExample:\n\n```rust\n\n// Multipart\n\nuse formdata::FormData;\n\nlet form_data_origin = FormData {\n    fields: vec![\n        (\"name\".to_owned(), \"Baxter\".to_owned()),\n        (\"age\".to_owned(), \"1 month\".to_owned()),\n    ],\n    files: vec![],\n};\n\n// POST make_api_multipart\nlet api_post_multipart = base_service_shared.make_api_multipart(\n    base_service_shared.clone(),\n    Method::POST,\n    \"/form\",\n    json_deserializer.clone(),\n    return_type_marker,\n);\n\nlet resp = api_post_multipart\n    .call(Some(simple_api::PathParam::new()), form_data_origin)\n    .await;\nlet model = resp.ok().unwrap();\n\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTeaEntityLab%2FhttpAPIService","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTeaEntityLab%2FhttpAPIService","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTeaEntityLab%2FhttpAPIService/lists"}