{"id":21846592,"url":"https://github.com/binarybirds/swift-http","last_synced_at":"2025-04-14T13:23:03.891Z","repository":{"id":37530440,"uuid":"466413538","full_name":"BinaryBirds/swift-http","owner":"BinaryBirds","description":"An awesome Swift HTTP library to rapidly create communication layers with API endpoints.","archived":false,"fork":false,"pushed_at":"2023-06-13T16:50:14.000Z","size":147,"stargazers_count":83,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-05T23:15:06.662Z","etag":null,"topics":["async-await","http","swift"],"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/BinaryBirds.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":"2022-03-05T09:55:31.000Z","updated_at":"2024-10-13T18:49:51.000Z","dependencies_parsed_at":"2022-08-19T04:51:02.915Z","dependency_job_id":null,"html_url":"https://github.com/BinaryBirds/swift-http","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryBirds%2Fswift-http","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryBirds%2Fswift-http/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryBirds%2Fswift-http/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryBirds%2Fswift-http/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BinaryBirds","download_url":"https://codeload.github.com/BinaryBirds/swift-http/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248886784,"owners_count":21177746,"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":["async-await","http","swift"],"created_at":"2024-11-27T23:14:39.587Z","updated_at":"2025-04-14T13:23:03.863Z","avatar_url":"https://github.com/BinaryBirds.png","language":"Swift","readme":"# SwiftHttp\n\nAn awesome Swift HTTP library to rapidly create communication layers with API endpoints. \n\n## Install\n\nYou can simply use `SwiftHttp` as a dependency via the Swift Package Manager:\n\n```swift\n.package(url: \"https://github.com/binarybirds/swift-http\", from: \"1.0.0\"),\n```\n\nAdd the `SwiftHttp` product from the `swift-http` package as a dependency to your target:\n\n```swift\n.product(name: \"SwiftHttp\", package: \"swift-http\"),\n```\n\nImport the framework:\n\n```swift\nimport SwiftHttp\n```\n\nThat's it.\n\n\n## Basic usage\n\nIt is really easy to setup a communication layer with an API endpoint.\n\n```swift\nimport SwiftHttp\n\nstruct Todo: Codable {\n    let id: Int\n    let title: String\n    let completed: Bool\n}\n\nstruct TodoApi: HttpCodablePipelineCollection {\n\n    let client: HttpClient = UrlSessionHttpClient(logLevel: .info)\n    let apiBaseUrl = HttpUrl(host: \"jsonplaceholder.typicode.com\")\n\n    \n    func list() async throws -\u003e [Todo] {\n        try await decodableRequest(\n            executor: client.dataTask,\n            url: apiBaseUrl.path(\"todos\"),\n            method: .get\n        )\n    }    \n}\n\n// api usage\nlet todos = try await api.list()\n\n// curl log\n// curl \"https://jsonplaceholder.typicode.com/todos/\"\n\n```\n\nThe HttpClient provides the executors to perform data, download or upload tasks.\n\nYou can create decodable, encodable, codable or raw request when using a codable pipeline collection.\n\n\n## Using raw requests \u0026 responses\n\nYou can create raw HTTP requests using the HttpUrl and the HttpRawRequest type.   \n\n```swift\nlet url = HttpUrl(\n    scheme: \"https\",\n    host: \"jsonplaceholder.typicode.com\",\n    port: 80,\n    path: [\"todos\"],\n    resource: nil,\n    query: [:],\n    fragment: nil\n)\n\nlet req = HttpRawRequest(\n    url: url, \n    method: .get, \n    headers: [:], \n    body: nil\n)\n\n/// execute the request using the client\nlet client = UrlSessionHttpClient(session: .shared, logLevel: .info)\nlet response = try await client.dataTask(req)\n\n/// use the response data\nlet todos = try JSONDecoder().decode([Todo].self, from: response.data)\n// response.statusCode == .ok\n// response.headers -\u003e response headers as a dictionary\n``` \n\nYou can use a specific HttpClient to execute a request using a data, download or upload task.\n\n\n## Constructing URLs\n\nThe HttpUrl type allows us to construct various URLs using a base URL. \n\n```swift\n\nlet baseUrl = HttpUrl(host: \"jsonplaceholder.typicode.com\")\n\n// https://jsonplaceholder.typicode.com/todos/\nbaseUrl.path(\"todos\")               \n\n// https://jsonplaceholder.typicode.com/todos/1/\nbaseUrl.path(\"todos\", String(1))    \n\n// https://jsonplaceholder.typicode.com/todos/?foo=bar\nbaseUrl.path(\"todos\").query(\"foo\", \"bar\")\n\n// https://jsonplaceholder.typicode.com/todos/?foo=baz\u0026bar=1\nbaseUrl.path(\"todos\").query([\n    \"foo\": \"baz\",\n    \"bar\": \"1\",\n])\n```\n\nYou can transform a HttpUrl object into a Foundation URL by using the `.url` property.\n\n## Requests\n\nYou can create a raw request object using a HttpUrl and a HttpMethod, including additional headers and a body data.\n\n```swift\nlet url = HttpUrl(host: \"localhost\", path: [\"login\"])\n\nlet token: String = \"valid-token\"\nlet body = try JSONEncoder().encode([\n    \"foo\": \"bar\",\n])\nlet req = HttpRawRequest(\n    url: url,\n    method: .post,\n    headers: [\n        .key(.authorization): \"Bearer \\(token)\",\n        .custom(\"my-header\"): \"my-header-value\",\n    ],\n    body: body\n)\n\n/*\ncurl \"https://localhost/login/\" \\\n    -X POST \\\n    -H 'my-header: my-header-value' \\\n    -H 'Authorization: Bearer valid-token' \\\n    -d '{\"foo\":\"bar\"}'\n*/\nprint(req.urlRequest.curlString) \n```\n\nYou can transform a HttpRequest into a URLReequest via the `.urlRequest` property.\nYou can print the cURL representation of a request by using the `.curlString` property on a URLRequest object.\n\n\n## Response validation\n\nYou can validate a response by using a HttpResponseValidator object.\n\n```swift\n// mock response\nlet response = HttpRawResponse(\n    statusCode: .ok,\n    headers: [\n        .key(.contentType): \"application/json\",\n    ],\n    data: .init()\n)\n\n// check if the status code is between 200 and 299               \nlet validator1 = HttpStatusCodeValidator() // -\u003e (.ok), (.notFound), etc.\ntry validator1.validate(response)\n\n\n// check if a header key exists and the value is equal to \"application/json\"\nlet validator2 = HttpHeaderValidator(.key(.contentType)) { value in\n    value == \"application/json\"\n}\n\ntry validator2.validate(response)\n\n// validate using multiple validators\nlet validation = HttpResponseValidation([validator1, validator2])\ntry validation.validate(response)\n```\n\nIt is possible to check for multiple validation criterias using a HttpResponseValidation. \n\n\n## Pipelines\n\nA pipeline allows you to transform a raw request and a raw response using a set of custom actions. \n\nYou can create your own HttpRequestTransformer object to add extra headers to your request and encode a custom body object to a data value.\n\nYou can create your own HttpResponseTransformer object to validate the response and decode a custom value from the response data.\n\nThe codable (encodable, decodable, codable) pipelines are a good example of this approach.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinarybirds%2Fswift-http","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinarybirds%2Fswift-http","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinarybirds%2Fswift-http/lists"}