blob: c11928ef3f3f4cd8da99ebbfdf4ce9d851a21f39 [file] [log] [blame]
{
"name": "RestingKit",
"version": "0.0.1",
"summary": "Networking made easy.",
"description": "# RestingKit\n\n[![CI Status](https://img.shields.io/travis/moray95/RestingKit.svg?style=flat)](https://travis-ci.org/moray95/RestingKit)\n[![Version](https://img.shields.io/cocoapods/v/RestingKit.svg?style=flat)](https://cocoapods.org/pods/RestingKit)\n[![License](https://img.shields.io/cocoapods/l/RestingKit.svg?style=flat)](https://cocoapods.org/pods/RestingKit)\n[![Platform](https://img.shields.io/cocoapods/p/RestingKit.svg?style=flat)](https://cocoapods.org/pods/RestingKit)\n\n## Introduction\n\nRestingKit is a higher-level wrapper around [Alamofire](https://github.com/Alamofire/Alamofire) and [PromiseKit](https://github.com/mxcl/PromiseKit) written in Swift that allows developers to concentrate on the important stuff instead of writing boiler-plate code for their REST API.\n\n## Features\n\n- Configurable HTTP client (Alamofire is currently the only one provided, but you can write your own!)\n- Path variable expansion powered by [GRMustache.swift](https://github.com/groue/GRMustache.swift)\n- Interception (and modification) of all requests and responses\n\n## Requirements\n\n- iOS 10.0+\n\n- Swift 4.2\n\n## Installation\n\nRestingKit is available through [CocoaPods](https://cocoapods.org). To install it, simply add the following line to your Podfile:\n\n```ruby\npod 'RestingKit'\n```\n\n## Usage\n\n### Basic example\n\n1. Create a `RestingClient`\n\n```swift\nimport RestingKit\n\nlet encoder = JSONEncoder()\nlet decoder = JSONDecoder()\nlet requestConverter = RestingRequestConverter(jsonEncoder: encoder, jsonDecoder: decoder)\nlet restingClient = RestingClient(baseUrl: \"https://jsonplaceholder.typicode.com\",\n decoder: decoder,\n requestConverter: requestConverter)\n```\n\n- `RestingClient` is the core class within RestingKit that does the heavy lifting by executing the requests. It is configured to use a single base URL, so if you need to access multiple APIs, you'll need to create multiple clients.\n- `RequestConverter` s transforms a `RestingRequest` to a `URLRequestConvertible`. `RestingRequestConverter` is the provided implementation that supports path templating.\n\n2. Define your models and endpoints\n\n ```swift\n struct PostCreateModel: Codable {\n let userId: Int\n let title: String\n let body: String\n\n init(userId: Int, title: String, body: String) {\n self.userId = userId\n self.title = title\n self.body = body\n }\n }\n\n struct PostModel: Codable {\n let id: Int\n let userId: Int\n let title: String\n let body: String\n }\n\n let createPostEndpoint = Endpoint<PostCreateModel, PostModel>(path: \"/posts\",\n method: .post,\n encoding: .json)\n ```\n\nAn `Endpoint` is defined by the models of the request and response, the path (relative to the `RestingClient`'s `baseUrl`, the HTTP method to use and the encoding. If the request doesn't expect any content or doesn't return anything, you can use the special `Nothing` class. Ideally, we would use `Void`, but it is not possible to make it `Encodable` or `Decodable`.\n\n3. Create the request and make the actual call\n\n ```swift\n let postCreateModel = PostCreateModel(userId: 1,\n title: \"Hello world\",\n body: \"Some awesome message\")\n let request = RestingRequest(endpoint createPostEndpoint,\n body: postCreateModel)\n restingClient.done { response in\n print(\"Headers: \\(response.headers)\")\n let post = response.body\n print(\"Created post with id: \\(post.id)\")\n }.catch { error in\n print(\"An error occurred: \\(error)\")\n }\n ```\n\nThe promise will fail when the request encountered networking issues or the server responded with an HTTP status >299.\n\nAnd that's it!\n\n### Handling responses with no content\n\nIf a request might provide a response that might be empty, you can create an `Endpoint` with an optional response type. That way, if the response is empty, `nil` will be returned.\n\n```swift\nlet createPostEndpoint = Endpoint<PostCreateModel, PostModel?>(path: \"/posts\",\n method: .post,\n encoding: .json)\nrestingClient.done { response in\n print(\"Headers: \\(response.headers)\")\n if let post = response.body {\n print(\"Created post with id: \\(post.id)\")\n } else {\n print(\"Empty body\")\n }\n}.catch { error in\n print(\"An error occurred: \\(error)\")\n}\n```\n\n**Note:** For this feature to work, the response needs to be truely empty. An empty JSON object will produce a decoding error.\n\n### Path variables\n\nThe provided `RestingRequestConverter` allows templating in paths by using [Mustache.swift](https://github.com/groue/GRMustache.swift).\n\n```swift\nlet getPostEndpoint = Endpoint<Nothing, PostModel>(path: \"/posts/{{post_id}}\",\n method: .get,\n encoding: .query)\nlet request = RestingRequest(endpoint: Endpoints.Posts.get,\n body: Nothing(),\n pathVariables: [\"post_id\": 1])\n\nrestingClient.perform(request).done { response in\n print(\"Got post: \\(response.body)\")\n}.catch { error in\n print(\"An error occurred: \\(error)\")\n}\n```\n\n### Interceptors\n\nInterceptors allow to intercept any request and response, and modify it before the request is sent or the response processed. Some basic usages of interceptors include:\n\n- Logging requests and responses\n- Injecting headers\n\nTo use interceptors, you will need to implement the `RestingInterceptor` protocol and provide your interceptor to your `RestingClient`.\n\n```swift\nclass LogInterceptor: RestingInterceptor {\n func intercept(request: URLRequest,\n execution: (URLRequest) -> Promise<HTTPDataResponse>) -> Promise<HTTPDataResponse>\n print(\"sending request \\(request)\")\n return execution.get { response in\n print(\"got response \\(response)\")\n }\n}\n\nclass DeviceIdInjector: RestingInterceptor {\n func intercept(request: URLRequest,\n execution: (URLRequest) -> Promise<HTTPDataResponse>)\n -> Promise<HTTPDataResponse> {\n var request = request\n request.setValue(UIDevice.current.identifierForVendor?.uuidString,\n forHTTPHeaderField: \"device-id\")\n return execution(request)\n }\n}\n\nlet restingClient = RestingClient(baseUrl: \"https://jsonplaceholder.typicode.com\",\n decoder: decoder,\n requestConverter: requestConverter,\n interceptors: [DeviceIdInjector(), LogInterceptor()])\n```\n\nThe `RestingClient` will pass the request to the interceptors in the provided order, while the response is passed in the reverse order. Therefore, it is important to place `LogInterceptor` at the end of the array (otherwise, it will not be able to log the `device-id` header added by `DeviceIdInjector`).\n\nRestingKit provides an interceptor for logging requests and responses: `RequestResponseLoggingInterceptor`\n\n**Important**: It is required for each interceptor to call the `execution` parameter, as it is what will run the next interceptors and finally the request. Unless, of course, you do not want to run additional interceptors or send the request.\n\n### Using a custom HTTPClient\n\n`HTTPClient` s are the class that performs the requests, takes a `URLRequest` and returns a `Promise<HTTPDataResponse>` without doing anything. `AlamofireClient` is the provided implementation that uses Alamofire to perform the requests and the default client used by `RestingClient`. You can configure a `RestingClient` to use your own implementation:\n\n```swift\nclass MyHTTPClient: HTTPClient {\n public func perform(urlRequest: URLRequest) -> Promise<HTTPDataResponse> {\n // Do your stuff here\n }\n}\n\nlet restingClient = RestingClient(baseUrl: \"https://jsonplaceholder.typicode.com\",\n decoder: decoder,\n httpClient: MyHTTPClient(),\n requestConverter: requestConverter)\n```\n\n\n\n## Work in progress\n\nAs RestingKİt is still new and in development, there are some missing features that needs implementation:\n\n- File uploads and downloads\n- Multipart requests and responses\n- Progress callbacks\n- Any other feature you might request!\n\nAdditionally, there might be some api-breaking changes until the project reaches full-maturity.\n\n## Contributing\n\nIf you need help with getting started or have a feature request, just open up an issue. Pull requests are also welcome for bug fixes and new features.\n\n## Author\n\nMoray Baruh\n\n## License\n\nRestingKit is available under the MIT license. See the LICENSE file for more info.",
"homepage": "https://github.com/moray95/RestingKit",
"license": {
"type": "MIT",
"file": "LICENSE"
},
"authors": {
"Moray Baruh": "contact@moraybaruh.com"
},
"source": {
"git": "https://github.com/moray95/RestingKit.git",
"tag": "0.0.1"
},
"platforms": {
"ios": "10.0"
},
"source_files": "RestingKit/Classes/**/*",
"dependencies": {
"Alamofire": [
"~> 4.8"
],
"GRMustache.swift4": [
"~> 3.0"
],
"PromiseKit": [
"~> 6.8"
]
}
}