{"id":25832633,"url":"https://github.com/lukas-simonson/swift-cobweb","last_synced_at":"2026-05-09T20:33:44.186Z","repository":{"id":278665923,"uuid":"859568017","full_name":"Lukas-Simonson/Swift-Cobweb","owner":"Lukas-Simonson","description":"A thin and light wrapper around Foundations Networking APIs","archived":false,"fork":false,"pushed_at":"2025-02-21T01:51:43.000Z","size":30,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-21T02:34:57.060Z","etag":null,"topics":["async-await","builder-pattern","network","swift","swiftui"],"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/Lukas-Simonson.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}},"created_at":"2024-09-18T22:21:17.000Z","updated_at":"2025-02-21T01:50:03.000Z","dependencies_parsed_at":"2025-02-21T02:45:00.831Z","dependency_job_id":null,"html_url":"https://github.com/Lukas-Simonson/Swift-Cobweb","commit_stats":null,"previous_names":["lukas-simonson/swift-cobweb"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lukas-Simonson%2FSwift-Cobweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lukas-Simonson%2FSwift-Cobweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lukas-Simonson%2FSwift-Cobweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lukas-Simonson%2FSwift-Cobweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lukas-Simonson","download_url":"https://codeload.github.com/Lukas-Simonson/Swift-Cobweb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241245520,"owners_count":19933295,"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","builder-pattern","network","swift","swiftui"],"created_at":"2025-02-28T21:40:13.459Z","updated_at":"2026-05-09T20:33:44.138Z","avatar_url":"https://github.com/Lukas-Simonson.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e🕸️ Cobweb\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cstrong\u003eSwift Networking Made Better\u003c/strong\u003e\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://developer.apple.com/swift/\"\u003e\u003cimg alt=\"Swift 6.0\" src=\"https://img.shields.io/badge/swift-6.0-orange.svg?style=flat\"\u003e\u003c/a\u003e\n    \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"license\" src=\"https://img.shields.io/badge/license-MIT-black.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Overview\nCobweb is a thin and light wrapper around Foundation.URLSession and its functionality. Cobweb is meant to provide a cleaner way to make URLRequests and work with the information received back from them.\n\n## Quickstart Guide\n\n### Making URLs\n\nCobweb is meant to make the entire process of making network requests easy and fun! This includes the process of creating URLs. By leveraging a builder pattern, Cobweb allows you to create URLs in a declarative manner.\n\nHere is an example of how you can create a URL for `https://www.google.com/`\n\n```swift\nCobweb.URL.host(\"google.com\")\n```\nCobweb uses https as its default schema, but you can also choose to set your schema by chaining another function, or even starting with that function.\n\nFor example if you wanted to go to `http://www.google.com`.\n\n```swift\nCobweb.URL.scheme(.http).host(\"google.com\")\n```\nYou can continue to modify the URL by chaining more functions. For example, if we want to change what path we are going to, we can chain the `.path` function.\n\n```swift\nCobweb.URL.host(\"example.com\")\n    .path(\"/sub/page\")\n```\nI could then set the query of my URL by chaining the `.query` function.\n\n```swift\nCobweb.URL.host(\"example.com\")\n    .path(\"/sub/page\")\n    .query(\"param1=400,param2=hello\")\n```\n#### Creating a `Cobweb.HTTP.Request` from a `Cobweb.URL`\n\nOnce you have created your `Cobweb.URL` you can easily convert it into a `Cobweb.HTTP.Request` by using the `.request` function. This function takes a parameter for what HTTP Method you want to use for your request. There are also some short hand functions such as `.get` that create the request for the most common HTTP Methods.\n\nThis function can throw if you haven't provided enough information to create a URL from.\n\n```swift\ntry Cobweb.URL.host(\"example.com\")\n    .path(\"/sub/page\")\n    .query(\"param1=400,param2=hello\")\n    .request(method: .get)\n\n// OR\n\ntry Cobweb.URL.host(\"example.com\")\n    .path(\"/sub/page\")\n    .query(\"param1=400,param2=hello\")\n    .get()\n```\n\n### Working With `Cobweb.HTTP.Request`\n\n#### Creating a `Cobweb.HTTP.Request`\nIf you don't want / need to work with `Cobweb.URL` you can still create a `Cobweb.HTTP.Request` using either a Foundation `URL` or just a `String`. There are several static functions built in to help you create requests.\n\nSimilar to how there is a `.request` function for `Cobweb.URL` there is also a static version for `Cobweb.HTTP.Request` that lets you specify a HTTP Method and a URL to use for the request. There are also the same convenience functions for the most common HTTP methods such as `.get`.\n\nHere is how you could create the same request we made in the last `Cobweb.URL` example just using a `String`.\n\n```swift\ntry Cobweb.HTTP.Request\n    .get(\"https://www.example.com/sub/page?param1=400,param2=hello\")\n```\n\n#### Setting Request Headers\nIn order to set the request headers of a `Cobweb.HTTP.Request` there are a couple of different functions you can use. Each of these different functions rely on being passed a `Cobweb.HTTP.Header` value.\n\n`Cobweb.HTTP.Header` is a type used to represent an individual header in a `Cobweb.HTTP.Request`. You can create one of these headers using the `.custom` static function, or by using one of the many provided static functions for commonly used headers, such as `.authorization`.\n\nFor this example, lets set a few different headers onto the request we made in the Creating a `Cobweb.HTTP.Request` section.\n\n```swift\ntry Cobweb.HTTP.Request\n    .get(\"https://www.example.com/sub/page?param1=400,param2=hello\")\n    .withHeaders(.contentType(value: \"application/json\"), .custom(\"X-API-KEY\", value: \"myapikeyhere\"))\n```\n#### Setting The Request Body\nSetting the body of a request is as easy as all of the other things. You use the `.withBody` function of the `Cobweb.Request`. There are 3 different versions of this function.\n\n1. `withBody(_ jsonEncodable: Encodable, encoder: JSONEncoder = JSONEncoder())`\n2. `withBody(_ str: String)`\n3. `withBody(_ data: Data)`\n\nEach of these options does the same thing, just using a different type of data.\n\nAs an example, here is a continuation of the last example, while adding a String as the body of the request.\n\n```swift\ntry Cobweb.HTTP.Request\n    // Changed to post as you cannot have a body on a get request.\n    .post(\"https://www.example.com/sub/page?param1=400,param2=hello\")\n    .withHeaders(.contentType(value: \"application/json\"), .custom(\"X-API-KEY\", value: \"myapikeyhere\"))\n    .withBody(\"This is my Response Body\")\n```\n#### Getting Data From The Request\n\nTo make send a `Cobweb.HTTP.Request` you use the `async` `.response` function. This will cause the set `URLSession` to make the actual request and it will return the information you get back in the form of a `Cobweb.HTTP.Response`\n\nHere is how you could get the data back from the previous example.\n\n```swift\n// Added await as the call to `.response` is async\ntry await Cobweb.HTTP.Request\n    .post(\"https://www.example.com/sub/page?param1=400,param2=hello\")\n    .withHeaders(.contentType(value: \"application/json\"), .custom(\"X-API-KEY\", value: \"myapikeyhere\"))\n    .withBody(\"This is my Response Body\")\n    .response()\n```\nIf you only care about the body of your request, you can choose to skip the response in favor of just getting the body data back. You can do this by using one of the various `.responseBody` functions.\n\n```swift\n// Added await as the call to `.response` is async\ntry await Cobweb.HTTP.Request\n    .post(\"https://www.example.com/sub/page?param1=400,param2=hello\")\n    .withHeaders(.contentType(value: \"application/json\"), .custom(\"X-API-KEY\", value: \"myapikeyhere\"))\n    .withBody(\"This is my Response Body\")\n    .responseBody(as: ExampleDecodable.self)\n```\n### Working With `Cobweb.HTTP.Response`\nThe only way to get an instance of a `Cobweb.HTTP.Response` is by using the `.response` function from a `Cobweb.HTTP.Request`. After this is done, there are several functions that help you handle the response you receive.\n\n#### Reading the Response Body\nYou can get the data from the responses body via the `.body` and `.bodyData` functions. These functions either convert `Decodable` types using a `JSONDecoder` or give back the `Data` object respectively.\n\n```swift\ntry await Cobweb.HTTP.Request\n    .post(\"https://www.example.com/sub/page?param1=400,param2=hello\")\n    .withHeaders(.contentType(value: \"application/json\"), .custom(\"X-API-KEY\", value: \"myapikeyhere\"))\n    .withBody(\"This is my Response Body\")\n    .response()\n    .bodyData() // Get the Data object from the `Cobweb.HTTP.Response`\n```\n\n#### Responding to Response Status Codes\nOften you need to verify the status codes of the response you get back from the network request. You can use the `.verifyStatusCode` function to throw errors based on the status code.\n\n```swift\ntry await Cobweb.HTTP.Request\n    .post(\"https://www.example.com/sub/page?param1=400,param2=hello\")\n    .withHeaders(.contentType(value: \"application/json\"), .custom(\"X-API-KEY\", value: \"myapikeyhere\"))\n    .withBody(\"This is my Response Body\")\n    .response()\n    .verifyStatusCode(is: 200, orThrow: NetworkError.invalidResponse)\n    .bodyData() // Get the Data object from the `Cobweb.HTTP.Response`\n```\n## See The Difference\n\n### With Normal URLSession\n```swift\nfunc postUser(user: User, bearerToken token: String) async throws -\u003e User {\n    guard let url = URL(string: \"https://example.com/user\")\n    else { throw ServiceError.invalidURL }\n    \n    var request = URLRequest(url: url)\n    request.httpMethod = \"POST\"\n    request.setValue(\"application/json\", forHTTPHeaderField: \"Content-Type\")\n    request.setValue(\"Bearer \\(token)\", forHTTPHeaderField: \"Authorization\")\n    request.httpBody = try JSONEncoder().encode(user)\n    \n    let (data, response) = try await URLSession.shared.data(for: request)\n    \n    switch (response as? HTTPURLResponse)?.statusCode {\n        case 200: break\n        case 400: throw ServiceError.badRequest\n        case 500: throw ServiceError.serverError\n        default: throw ServiceError.unknownError\n    }\n    \n    return try JSONDecoder().decode(User.self, from: data)\n}\n```\n### With ComposeHTTP\n```swift\nfunc postUser(user: User, bearerToken token: String) async throws -\u003e User {\n    try await Cobweb.HTTP.Request\n        .post(\"https://example.com/user\")\n        .withHeaders(.contentType(value: \"application/json\"), .authorization(value: \"Bearer \\(token)\"))\n        .withBody(user)\n        .response()\n        .verifyStatusCode(isNot: 400, orThrow: ServiceError.badRequest)\n        .verifyStatusCode(isNot: 500, orThrow: ServiceError.serverError)\n        .verifyStatusCode(is: 200, orThrow: ServiceError.unknownError)\n        .body()\n}\n```\n\n## Installation\n\n### Swift Package Manager\n\n[Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the Swift compiler.\n\nTo add [ComposeHTTP](https://github.com/Lukas-Simonson/swift-composehttp) to your project do the following.\n- Open Xcode\n- Click on `File -\u003e Add Packages`\n- Use this repositories URL (https://github.com/Lukas-Simonson/Swift-ComposeHTTP.git) in the top right of the window to download the package.\n- When prompted for a Version or a Branch, we suggest you use the branch: main\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukas-simonson%2Fswift-cobweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flukas-simonson%2Fswift-cobweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flukas-simonson%2Fswift-cobweb/lists"}