Contents

danielsaidi/apikit

ApiKit is a Swift library that makes it easy to integrate with any REST API and map its response data to Swift types.

Installation

ApiKit can be installed with the Swift Package Manager:

https://github.com/danielsaidi/ApiKit.git

Getting Started

Consider that you want to integrate with the Yelp API, which can return restaurants, reviews, etc.

You would first define the various API environments that you want to integrate with. In this case, let's just integrate with the v3 environment, which requires an API header token for all requests:

import ApiKit

enum YelpEnvironment: ApiEnvironment {

    case v3(apiToken: String)
    
    var url: String {
        switch self {
        case .v3: "https://api.yelp.com/v3/"
        }
    }
 
    var headers: [String: String]? {
        switch self {
        case .v3(let token): ["Authorization": "Bearer \(token)"]
        }
    }
}

We can then define the routes to request from the Yelp API. In this case, let's just fetch a business by unique ID:

import ApiKit

enum YelpRoute: ApiRoute {

    case business(id: String)

    var path: String {
        switch self {
        case .business(let id): "businesses/\(id)"
        }
    }

    var httpMethod: HttpMethod { .get }
    var headers: [String: String]? { nil }
    var formParams: [String: String]? { nil }
    var postData: Data? { nil }
    
    var queryParams: [String: String]? {
        switch self {
        case .business: nil
        }
    }
}

With an environment and route in place, we can now fetch a YelpBusiness with any `ApiClient or URLSession`:

let client = URLSession.shared
let env = YelpEnvironment.v3(apiToken: "YOUR_TOKEN")
let route = YelpRoute.business(id: "abc123") 
let business: YelpBusiness = try await client.request(route, in: env)
// or...
// let business = try await client.request(route, as: YelpBusiness.self, in: environment)

If you make this call in a function that defines the return type, you don't even have to define the type:

func fetchBusiness(
    withId id: String
) async throws -> YelpBusiness {
    try await client.request(.business(id: id), in: env)
}

The request will automatically map the raw response to the requested type, and throw any error that occurs. There are also non-generic variants if you want to get the raw data, or use custom error handling.

See the online [getting started guide][Getting-Started] for more information.

Documentation

The online [documentation][Documentation] has more information, articles, code examples, etc.

Demo Application

The Demo folder has a demo app that lets you explore the library and integrate with a few APIs.

Support My Work

You can [become a sponsor][Sponsors] to help me dedicate more time on my various [open-source tools][OpenSource]. Every contribution, no matter the size, makes a real difference in keeping these tools free and actively developed.

Contact

Feel free to reach out if you have questions, or want to contribute in any way:

  • Website: [danielsaidi.com][Website]
  • E-mail: [daniel.saidi@gmail.com][Email]
  • Bluesky: [@danielsaidi@bsky.social][Bluesky]
  • Mastodon: [@danielsaidi@mastodon.social][Mastodon]

License

ApiKit is available under the MIT license. See the [LICENSE][License] file for more info.

[Email]: mailto:daniel.saidi@gmail.com [Website]: https://danielsaidi.com [GitHub]: https://github.com/danielsaidi [OpenSource]: https://danielsaidi.com/opensource [Sponsors]: https://github.com/sponsors/danielsaidi

[Bluesky]: https://bsky.app/profile/danielsaidi.bsky.social [Mastodon]: https://mastodon.social/@danielsaidi [Twitter]: https://twitter.com/danielsaidi

[Documentation]: https://danielsaidi.github.io/ApiKit [Getting-Started]: https://danielsaidi.github.io/ApiKit/documentation/apikit/getting-started [License]: https://github.com/danielsaidi/ApiKit/blob/master/LICENSE

Package Metadata

Repository: danielsaidi/apikit

Default branch: main

README: README.md