Meet `swift-api-client` package

swift-api-client is a comprehensive and modular Swift library for API design.

Main Goals of the Library

  • Minimalistic and intuitive syntax.
  • Reusability, allowing for the injection of configurations across all requests.
  • Extensibility and modularity.
  • A simple core offering a wide range of possibilities.
  • Facilitation of testing and mocking.

Usage

The core of the library is the APIClient struct, serving both as a request builder and executor. It is a generic struct, enabling use for any task associated with URLRequest.

The branching and configuration injection/overriding capabilities of APIClient, extending to all its child instances, facilitate the effortless recycling of networking logic and tasks, thereby eliminating the need for copy-pasting.

While a full example is available in the Example folder, here is a simple usage example:

let client = APIClient(url: baseURL)
  .bodyDecoder(.json(dateDecodingStrategy: .iso8601))
  .bodyEncoder(.json(dateEncodingStrategy: .iso8601))
  .errorDecoder(.decodable(APIError.self))
  .tokenRefresher { client, _ in
    try await client("token").get()
  } auth: {
    .bearer($0)
  }

// Create a `APIClient` instance for the /users path
let usersClient = client("users")

// GET /users?name=John&limit=1
let john: User = try await usersClient
  .query(["name": "John", "limit": 1])
  .auth(enabled: false)
  .get()

// Create a `APIClient` instance for /users/{userID} path
let johnClient = usersClient(john.id)

// GET /user/{userID}
let user: User = try await johnClient.get()

// PUT /user/{userID}
try await johnClient.body(updatedUser).put()

// DELETE /user/{userID}
try await johnClient.delete()
4 Likes

I have some feedback about your naming - putting “networking” in the name made me immediately think this was about low-level TCP/UDP networking instead of high-level HTTP requests, and your ReadMe took a long time to reveal that’s what the package is about. You might want to consider changing the name and/or making it clear at the top of the ReadMe what portion of the networking stack you’re dealing with.

1 Like

thanks, i'll think about it