Endpoint

public protocol Endpoint

A protocol used to group ServiceRequests with a common path.

If you have multiple requests which share a common path (or other properties), use an Endpoint to group them. When you set the ServiceRequest.endpoint property to the endpoint type, the Endpoint.path property will automatically be used as the base path for the request (without needing to include it in the ServiceRequest.pathComponents property).

For example, if you have an endpoint /users, with a full url of https://example.com/api/users, you can define your API as follows:

 struct Example: Service {
    static let baseURL = URL(string: "https://example.com/api")!
    enum Users: Endpoint {
        static let path = "users"

        struct Get: ServiceRequest {
            let endpoint = Users.self
            let httpMethod = .get

            var userID: String?
            // The endpoint path "users" does not need to be specified here
            var pathComponents: [String] {
                [userID].compactMap { $0 }
            }
        }

        struct Add: ServiceRequest {
            let endpoint = Users.self
            let httpMethod = .post

            let userID: String
            let name: String

            var body: Data? {
                // Create JSON from arguments
                let dictionary = ["id": userID, "name": name]
                return try? JSONSerialization.data(withJSONObject: dictionary, options: [])
            }
        }
    }
 }

Note how the endpoint path of users does not need to be specified in the Get requests pathComponents property.

The above allows get requests to be made by specifying a specific userID, or fetching all users:

 do {
    // Fetch all users
    // GET: https://example.com/api/users
    let allUsers: (request, response, data) = try await Example().request(Example.Users.Get())
    // Fetch user 123
    // GET: https://example.com/api/users/123
    let user123: (request, response, data) = try await Example().request(Example.Users.Get(userID: "123"))
 } catch {
     print("Request failed with error- \(error)")
 }

We have defined the POST method on the users endpoint for adding users:

 do {
    // Fetch all users
    // POST: https://example.com/api/users
    try await Example().request(Example.Users.Add(userID: "456", name: "Someone"))
 } catch {
     print("Request failed with error- \(error)")
 }