BottleRocketStudios / iOS-Hyperspace

An extremely lightweight wrapper around URLSession to make working with APIs a breeze.
Apache License 2.0
47 stars 17 forks source link

RFC: Request as a struct #79

Closed wmcginty closed 4 years ago

wmcginty commented 5 years ago

Currently in Hyperspace 3.0, the Request protocol is the sole requirement for use with a BackendService. While the use of a protocol allows for more freedom of implementation and arguably better testability, it also introduces a few issues as we look to expand its capabilities.

func map<U>(_ transform: @escaping (ResponseType) -> U) -> Request<U, ErrorType> { ... }

If we were to migrate from using a Request protocol to a request struct, we would not lose the functionality attached to conformance to the Request protocol.

struct CreatePostRequest: Request {
    // Define the model we want to get back
    typealias ResponseType = Post
    typealias ErrorType = AnyError

    // Define Request property values
    var method: HTTP.Method = .post
    var url = URL(string: "http://jsonplaceholder.typicode.com/posts")!
    var queryParameters: [URLQueryItem]?
    var headers: [HTTP.HeaderKey: HTTP.HeaderValue]? = [.contentType: .applicationJSON]
    var body: Data? {
        let encoder = JSONEncoder()
        return try? encoder.encode(newPost)
    }

    // Define any custom properties needed
    private let newPost: NewPost

    // Initializer
    init(newPost: NewPost) {
        self.newPost = newPost
    }
}
extension Request where ResponseType == Post, ErrorType == AnyError {
  static func createPost(_ post: NewPost) -> Request {
    return Request<Post, AnyError>(method: .get,
                      url: URL(string: "http://jsonplaceholder.typicode.com/posts")!,
          queryParameters: nil,
                  headers: [.contentType: .applicationJSON],
                     body: try? JSONEncoder().encode(post))
  }
}

There is a test implementation available here: https://github.com/BottleRocketStudios/iOS-Hyperspace/tree/requestStruct

wmcginty commented 4 years ago

This was merged as part of #117