Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTTPClient for Web API Client Library #64

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

zunda-pixel
Copy link
Contributor

@zunda-pixel zunda-pixel commented Aug 13, 2024

HTTPClient

Web API Client Library needs HTTPClient for URLSession, SwiftNIO...

Example: GitHub API Client Library

import Foundation
import HTTPTypes
import HTTPClient
import HTTPClientFoundatiaon

let api = GitHubAPI(
  token: <#API_TOKEN#>,
  httpClient: .urlSession(.shared)
)

let user = try await api.user(id: <#USER_ID#>)

struct GitHubAPI<HTTPClient: HTTPClientProtocol>: Sendable where HTTPClient.Data == Foundation.Data, HTTPClient: Sendable {
  let token: String
  let httpClient: HTTPClient

  func user(id: String) async throws -> User {
    let request = HTTPRequest(
      method: .get,
      url: url,
      headerFields: [.authorization: token]
    )
    let (data, response) = try await httpClient.execute(for: request, from: nil)
    let user = try JSONDecoder().decode(User.self, from: data)
    return user
  }
}

@zunda-pixel zunda-pixel changed the title Add HTTPClient Add HTTPClient for Web API Client Library Aug 13, 2024

public protocol HTTPClientProtocol {
associatedtype Body
associatedtype Data
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add associatedType Body, Data for Data, ByteBuffer, [Int8].
#15 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having associated types here is kinda defeating the purpose of having a general protocol level abstraction for an HTTP client. In my opinion, we should come up with standardised types for the type of data.

Furthermore, I see two more outstanding questions:

  1. We should support optional trailers on both the request and response side
  2. We should support bi-direction body streaming

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we adopt 1 or 2?

  1. one associatedType(Data), data, body has same Type.
  2. no associatedType, use Foundation.Data

Copy link
Member

@FranzBusch FranzBusch Aug 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should adopt any of the two. There is currently no "bag-of-bytes" currency type that is used across the ecosystems. Choosing either Data or ByteBuffer will come with downsides.

In my opinion, we have to solve this question in the standard library first before we can tackle providing a common API abstraction here.

Copy link
Contributor Author

@zunda-pixel zunda-pixel Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we adopt Foundation.Data without waiting for the issue to be resolved?
I think solving the standard library issue is difficult and will take too much time.

Does Apple/SwiftLang have any plans to resolve this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we adopt Foundation.Data without waiting for the issue to be resolved?

We can't adopt Foundation.Data across the ecosystem right now since the server ecosystem uses ByteBuffer and is built around that. Adopting Foundation.Data would incur unnecessary allocations at the API boundaries to bridge between the types.

Does Apple/SwiftLang have any plans to resolve this?

There were previous discussions around this topic but there currently is no proposed solution. One of the focus areas of the Swift project right now is tackling ownership and lifetime in the standard library including in collections like Array<UInt8>. This might inform some of the next steps around a common bag-of-bytes type.

Sadly, I think this puts the proposal with creating a shared API abstraction for HTTP clients on hold right now. Until we can solve the bag-of-bytes problem at the language level. Now you can still create this protocol in your own code and conform the various clients to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants