HTTP macro

Recently, I had the idea to create a Swift HTTP macro that would streamline requests.

This is how I imagine it to work:

@HTTPClient(
    baseURL: "https://api.example.com",
    contentType: "application/json",
    useCookies: true
)
struct MyAPIClient {
    @Endpoint(method: .GET, path: "/users")
    func getUsers(queryParams: [String: String] = [:], headers: [String: String] = [:], completion: @escaping (Data?, Error?) -> Void)

    @Endpoint(method: .POST, path: "/users", contentType: "application/json")
    func createUser(body: Data, headers: [String: String] = [:], completion: @escaping (Data?, Error?) -> Void)

    @Endpoint(method: .POST, path: "/users", contentType: "application/x-www-form-urlencoded")
    func createUserForm(body: [String: String], headers: [String: String] = [:], completion: @escaping (Data?, Error?) -> Void)
}

Then the goal would be to make it work for Apple, Linux, and WebAssembly.

Since I have never created a Swift macro, I’m not sure if it makes sense to use a macro for that or if it would be better to use the Swift OpenAPI generator instead. What do you think?

Seems like a viable idea: GitHub - joshuawright11/papyrus: A type-safe HTTP client for Swift.

1 Like

Thanks for your reply @t089.

Oh, I remember seeing that one before! Unfortunately, it doesn’t play nice with WebAssembly. Also, when I peeked at the open PR and issues, it seems like the package hasn’t been making much headway lately. But, since I’m new to macros and eager to create something myself, I imagine it would take some time. What do you think?

By no means feel discouraged, take a look at the existing repos and try to improve on them. Would be great to have something that plays nice with Linux and web assembly! Absolutely!

You could take a look at the open api generator runtime package. They have a “transport” protocol which all the http client “backends” implement. This is a good way to make your lib extensible to different platforms / http client implementations.

They should have used FoundationEssentials.URL though :frowning:

1 Like