Jetway
A Swift framework for creating and calling statically-typed API endpoints
alpha
. Expect frequent changes and additions to the public API.
Usage
Rigorous documentation will come later. Here's a small sample from JetwayTests.xctest:
enum SampleSongsAPI {
private static let api = API(baseUrl: "https://itunes.apple.com")
static func songs(for query: String) -> PublicEndpoint<Void, SongResponse> {
return api.endpoint(.GET, "search?term=\(query.percentEncoded)&entity=song")
}
}
struct SongResponse: Codable {
let results: [Song]
}
struct Song: Codable {
let trackName: String
let artistName: String
}
// calling an Endpoint
SampleSongsAPI.songs(for: "Earth, Wind, & Fire").call().then { response in
// SongsResponse
// ▿ results : 50 elements
// ▿ 0 : Song
// - trackName : "September"
// - artistName : "Earth, Wind & Fire"
// ▿ 1 : Song
// - trackName : "Let's Groove"
// - artistName : "Earth, Wind & Fire"
// ▿ 2 : Song
// - trackName : "Boogie Wonderland"
// - artistName : "Earth, Wind & Fire"
// ...
}.catch { error in
someErrorHandler(error)
}
Example API from Window.app
I'm using Jetway as the networking layer in Window.app:
import Jetway
public enum SocialAPI {
static let api: API = {
let api = API(
baseUrl: "https://api.windowfasting.app",
requestHeaders: ["API-Key": "..."])
api.credentialsStore.registerCredentialsProvider({
return try UserManager.currentSession()
})
return api
}()
}
public typealias AuthenticatedEndpoint<RequestType, ResponseType>
= Endpoint<RequestType, ResponseType, Requires<AuthenticatedSession>>
// MARK: - User Endpoints
public extension SocialAPI {
public static func createNewUser() -> PublicEndpoint<User.Registration, User> {
return api.endpoint(.POST, "/users")
}
public static func getUser(with id: User.ID) -> Endpoint<Void, User, Requires<AuthorizationToken>> {
return api.endpoint(.GET, "/users/\(id)")
}
public static func updateProfile(for user: User) -> AuthenticatedEndpoint<User.Profile, User> {
return api.endpoint(.PUT, "/users/\(user.id)/profile")
}
public static func updateProfilePicture(for user: User) -> AuthenticatedEndpoint<CodableImage, User> {
return api.endpoint(.PUT, "/users/\(user.id)/profile/picture", additionalRequestConfiguring: { request in
request.setValue("image/jpeg", forHTTPHeaderField: "Content-Type")
})
}
public static func getProfilePicture(for user: User) -> PublicEndpoint<Void, CodableImage> {
return api.endpoint(.GET, "/users/\(user.id)/profile/picture")
}
public static func registerDevice(for user: User) -> AuthenticatedEndpoint<Device, Void> {
return api.endpoint(.POST, "/users/\(user.id)/devices")
}
}
...