https://github.com/futuredapp/ftapikit
Declarative and generic REST API framework using Codable.
https://github.com/futuredapp/ftapikit
api-client codable declarative functional protocol rest-api urlsession
Last synced: 4 months ago
JSON representation
Declarative and generic REST API framework using Codable.
- Host: GitHub
- URL: https://github.com/futuredapp/ftapikit
- Owner: futuredapp
- License: mit
- Created: 2018-09-19T11:56:06.000Z (over 6 years ago)
- Default Branch: main
- Last Pushed: 2024-04-05T13:07:37.000Z (about 1 year ago)
- Last Synced: 2025-01-09T09:34:35.816Z (4 months ago)
- Topics: api-client, codable, declarative, functional, protocol, rest-api, urlsession
- Language: Swift
- Homepage:
- Size: 1.19 MB
- Stars: 20
- Watchers: 6
- Forks: 3
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# FTAPIKit




Declarative and generic REST API framework using Codable.
With standard implementation using URLSesssion and JSON encoder/decoder.
Easily extensible for your asynchronous framework or networking stack.## Installation
When using Swift package manager install using Xcode 11+
or add following line to your dependencies:```swift
.package(url: "https://github.com/futuredapp/FTAPIKit.git", from: "1.5.0")
```When using CocoaPods add following line to your `Podfile`:
```ruby
pod 'FTAPIKit', '~> 1.5'
```## Features
The main feature of this library is to provide documentation-like API
for defining web services. This is achieved using declarative
and protocol-oriented programming in Swift.The framework provides two core protocols reflecting the physical infrastructure:
- `Server` protocol defining single web service.
- `Endpoint` protocol defining access points for resources.Combining instances of type conforming to `Server` and `Endpoint` we can build request.
`URLServer` has convenience method for calling endpoints using `URLSession`.
If some advanced features are required then we recommend implementing API client.
This client should encapsulate logic which is not provided by this framework
(like signing authorized endpoints or conforming to `URLSessionDelegate`).
This package contains predefined `Endpoint` protocols.
Use cases like multipart upload, automatic encoding/decoding
are separated in various protocols for convenience.- `Endpoint` protocol has empty body. Typically used in `GET` endpoints.
- `DataEndpoint` sends provided data in body.
- `UploadEndpoint` uploads file using `InputStream`.
- `MultipartEndpoint` combines body parts into `InputStream` and sends them to server.
Body parts are represented by `MultipartBodyPart` struct and provided to the endpoint
in an array.
- `RequestEndpoint` has encodable request which is encoded using encoding
of the `Server` instance.
## Usage
### Defining web service (server)
Firstly we need to define our server. Structs are preferred but not required:
```swift
struct HTTPBinServer: URLServer {
let baseUri = URL(string: "http://httpbin.org/")!
let urlSession = URLSession(configuration: .default)
}
```If we want to use custom formatting we just need to add our encoding/decoding configuration:
```swift
struct HTTPBinServer: URLServer {
...let decoding: Decoding = JSONDecoding { decoder in
decoder.keyDecodingStrategy = .convertFromSnakeCase
}
let encoding: Encoding = JSONEncoding { encoder in
encoder.keyEncodingStrategy = .convertToSnakeCase
}
}
```If we need to create specific request, add some headers, usually to provide
authorization we can override default request building mechanism.```swift
struct HTTPBinServer: URLServer {
...
func buildRequest(endpoint: Endpoint) throws -> URLRequest {
var request = try buildStandardRequest(endpoint: endpoint)
request.addValue("MyApp/1.0.0", forHTTPHeaderField: "User-Agent")
return request
}
}
```### Defining endpoints
Most basic `GET` endpoint can be implemented using `Endpoint` protocol,
all default propertires are inferred.```swift
struct GetEndpoint: Endpoint {
let path = "get"
}
```Let's take more complicated example like updating some model.
We need to supply encodable request and decodable response.```swift
struct UpdateUserEndpoint: RequestResponseEndpoint {
typealias Response = Userlet request: User
let path = "user"
}
```### Executing the request
When we have server and enpoint defined we can call the web service:
```swift
let server = HTTPBinServer()
let endpoint = UpdateUserEndpoint(request: user)
server.call(response: endpoint) { result in
switch result {
case .success(let updatedUser):
...
case .failure(let error):
...
}
}
```## Contributors
Current maintainer and main contributor is [Matěj Kašpar Jirásek](https://github.com/mkj-is), .
We want to thank other contributors, namely:
- [Mikoláš Stuchlík](https://github.com/mikolasstuchlik)
- [Radek Doležal](https://github.com/eRDe33)
- [Adam Bezák](https://github.com/bezoadam)
- [Patrik Potoček](https://github.com/Patrez)## License
FTAPIKit is available under the MIT license. See the [LICENSE file](LICENSE) for more information.