{"id":22477744,"url":"https://github.com/swiftuiux/async-http-client","last_synced_at":"2025-12-11T22:58:03.192Z","repository":{"id":77366023,"uuid":"605405148","full_name":"swiftuiux/async-http-client","owner":"swiftuiux","description":"Async http swift client new concurrency in swift uikit swiftui","archived":false,"fork":false,"pushed_at":"2024-11-30T13:09:50.000Z","size":121,"stargazers_count":38,"open_issues_count":0,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-23T18:54:38.976Z","etag":null,"topics":["async","http"],"latest_commit_sha":null,"homepage":"","language":"Swift","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/swiftuiux.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-02-23T04:36:45.000Z","updated_at":"2025-09-04T07:10:23.000Z","dependencies_parsed_at":"2024-08-22T06:10:56.931Z","dependency_job_id":"a8bd5774-03c0-442d-ad80-7ef36ca61ad2","html_url":"https://github.com/swiftuiux/async-http-client","commit_stats":{"total_commits":130,"total_committers":1,"mean_commits":130.0,"dds":0.0,"last_synced_commit":"0ee984f62303b26b8c78821497b8366079a6cb10"},"previous_names":["igor11191708/async-http-client","the-igor/async-http-client","igor111917180/async-http-client","swiftuiux/async-http-client"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/swiftuiux/async-http-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swiftuiux%2Fasync-http-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swiftuiux%2Fasync-http-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swiftuiux%2Fasync-http-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swiftuiux%2Fasync-http-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swiftuiux","download_url":"https://codeload.github.com/swiftuiux/async-http-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swiftuiux%2Fasync-http-client/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27672064,"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","status":"online","status_checked_at":"2025-12-11T02:00:11.302Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["async","http"],"created_at":"2024-12-06T14:12:08.032Z","updated_at":"2025-12-11T22:58:03.162Z","avatar_url":"https://github.com/swiftuiux.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Async/await http client using new concurrency model in Swift\n\nNetwork layer for running requests like GET, POST, PUT, DELETE etc customizable with coders. There's ability to retry request with different strategies\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fswiftuiux%2Fasync-http-client%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/swiftuiux/async-http-client)\n\n## [Documentation(API)](https://swiftpackageindex.com/swiftuiux/async-http-client/main/documentation/async_http_client)\nor\n- You need to have Xcode 13 installed in order to have access to Documentation Compiler (DocC)\n- Go to Product \u003e Build Documentation or **⌃⇧⌘ D**\n\n## [SwiftUI example](https://github.com/swiftuiux/async-http-client-example)\n\n## Features\n- [x] Multiplatform\n- [x] You have fast-track functions to make requests immediately by url or build the infrastructure configuration that suits you\n- [x] Stand alone package without any dependencies using just Apple's  facilities\n- [x] Set up amount of attempts(retry) with **\"Exponential backoff\"** or **\"Constant backoff\"** strategy if request fails. Exponential backoff is a strategy in which you increase the delays between retries. Constant backoff is a strategy when delay between retries is a constant value\n- [x] Different strategies to validate URLResponse\n- [x] Customizable for different requests schemes from classic **CRUD Rest** to what suits to you\n- [x] Customizable in terms of URLSession\n- [x] Customizable in terms of URLSessionTaskDelegate, URLSessionDelegate\n- [x] Based on interfaces not implementations\n- [x] Customizable with coders You can easily change format from json to xml or text just changing the coder\n\n ![Http requests](https://github.com/swiftuiux/async-http-client-example/blob/main/async-http-client-example/img/image11.gif) \n\n## Fast track\n\n## 1. Use\n```swift\n   try await Http.Get.from(url, retry: 5, validate: [.status(200)])\n```\n```swift\n   try await Http.Post.from(url, taskDelegate : TaskDelegate())\n```\n\n```swift\n   try await Http.Put.from(url, body: data)\n```\n\n```swift\n   try await Http.Delete.from(url)\n```\n\nFast-track functions return **(Data, URLResponse)** if you need to validate status code you can use **func** *validateStatus* check different strategies **Http.Validate.Status**\n\n```swift\n        let (data, response) = try await Http.Get.from(url)\n        let rule : Http.Validate.Status = .range(200..\u003c300)\n        try validateStatus(response, by: rule)\n```\n\n## Extended track\n\n## 1. Create\n```swift\n    let url = URL(string: \"http://localhost:3000\")\n    let http = Http.Proxy(baseURL: url)\n```\n\n### with custom configuration\n```swift\n      let cfg = Http.Configuration(\n                    reader: SomeReader(),\n                    writer: SomeWriter(),\n                    baseURL: baseURL,\n                    session: session)\n     let http = Http.Proxy(config: cfg)\n```\n\n\n## 2. Use\n\n### GET\n```swift\n    try await http.get(path: \"users\")\n```        \n\n### GET with retry\n```swift\n    try await http.get(path: \"users\", retry  : 5)\n``` \n\n### GET with validate status code 200..\u003c300\n```swift\n    try await http.get(path: \"users\", validate: [.status(.range(200..\u003c300))])\n```    \n\n### POST\n```swift\n    try await http.post(\n                        path: \"users\", \n                        body: data, \n                        query: [(\"name\", \"Igor\"), (\"page\",\"1\")], \n                        headers: [\"Content-Type\": \"application/json\"])\n``` \n\n### POST with Delegate collecting metrics\n```swift\n    try await http.post(path: \"users\", taskDelegate: DelegatePickingUpMetrics())\n```\n                 \n### PUT\n```swift\n    try await http.put(path: \"users\", body: data)\n```\n\n### DELETE\n```swift\n    try await http.delete(path: \"users\")\n```\n\n### Custom request\n\n```swift\n        public func send\u003cT\u003e(\n            with request : URLRequest,\n            retry strategy : RetryService.Strategy = .exponential(),\n            _ validate : [Http.Validate] = [.status(200)],\n            _ taskDelegate: ITaskDelegate? = nil\n        ) async throws -\u003e Http.Response\u003cT\u003e where T : Decodable\n```\n\n## Retry strategy\n\nThis package uses stand alone package providing retry policy. The service creates sequence of the delays (nanoseconds) according to chosen strategy for more details folow the link [retry service](https://github.com/swiftuiux/retry-policy-service) \n\n| type | description |\n| --- | --- |\n| constant | The strategy implements constant backoff  |\n| exponential [default] | The strategy implements exponential backoff  |\n\n## Validate\nIs an array of different rules to check URLResponse.\nCurrently is implemented for validating status code.\n\n### Status code\n| type | description |\n| --- | --- |\n| const(Int) [default] 200 | Validate by exact value  |\n| range(Range\u003cInt\u003e) [default] 200..\u003c300 | Validate by range  |\n| predicate(Predicate) | Validate by predicate func if you need some specific processing logic |\n| check(ErrorFn) | Check status and return custom error if status is not valid |\n#### By range\n```swift\n    try await http.get(path: path, validate: [.status(.range(200..\u003c300))])\n```\n\n#### By predicate\n```swift\n    let fn : (Int) -\u003e Bool = { status in status == 201 }\n    \n    try await http.get(path: path, validate: [.status(.predicate(fn))])\n```\n\nThere's an example [replicate toolkit for swift](https://github.com/swiftuiux/replicate-kit-swift) how to use it with a custom response error format that has different format then the successful response\n\n# The concept\n\n* Proxy is defining a communication layer and responsible for exchanging data with data source. There might be Http proxy, File proxy etc or some flavors REST proxy, LongFile proxy.\n* Reader and Writer are used to interpret data.\n\n ![The concept](https://github.com/swiftuiux/async-http-client/blob/main/img/concept.png) \n \n\n## Try it in the real environment\n### Simple server installation (mocking with NodeJS Express)\n\nTo try it in the real environment. I suggest installing the basic NodeJS Express boilerplate. Take a look on the video snippet how easy it is to get it through Webstorm that is accessible for free for a trial period.\n\n[![Server installation (NodeJS Express)](https://github.com/swiftuiux/d3-network-service/blob/main/img/server_install.png)](https://youtu.be/9FPOYHzcE7A)\n\n- Get [**WebStorm Early Access**](https://www.jetbrains.com/webstorm/nextversion)\n- Get [**index.js**](https://github.com/swiftuiux/d3-network-service/blob/main/js/index.js) file from here and replace it with the one in the boilerplate and launch the server.\n\n\n## Used by packages\n\n[Replicate toolkit for swift](https://github.com/swiftuiux/replicate-kit-swift)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswiftuiux%2Fasync-http-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswiftuiux%2Fasync-http-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswiftuiux%2Fasync-http-client/lists"}