@@ -50,22 +50,50 @@ The documentation for releases and `main` are available here:
5050```swift
5151import NetworkKit
5252
53- // Define your endpoint
54- struct UserEndpoint: Endpoint {
55- let baseURL = URL(string: "https://api.example.com")!
56- let path = "/users"
57- let method = Http.Method.get
58- let task = Http.Task.requestPlain
59- let headers = [Http.Header.accept("application/json")]
60- let timeout: TimeInterval? = 30
53+ // Define your endpoint using SwiftUI-style DSL
54+ enum UserEndpoint: Endpoint {
55+ case getUsers
56+ case getUser(id: Int)
57+ case createUser(name: String, email: String)
58+
59+ var body: HTTPEndpoint {
60+ switch self {
61+ case .getUsers:
62+ return HTTP {
63+ BaseURL("https://api.example.com")
64+ Path("/users")
65+ Method(.get)
66+ HTTPTask(.requestPlain)
67+ Headers([.accept("application/json")])
68+ Timeout(30.0)
69+ }
70+ case .getUser(let id):
71+ return HTTP {
72+ BaseURL("https://api.example.com")
73+ Path("/users/\(id)")
74+ Method(.get)
75+ HTTPTask(.requestPlain)
76+ Headers([.accept("application/json")])
77+ }
78+ case .createUser(let name, let email):
79+ let user = CreateUserRequest(name: name, email: email)
80+ return HTTP {
81+ BaseURL("https://api.example.com")
82+ Path("/users")
83+ Method(.post)
84+ HTTPTask(.requestJSON(user))
85+ Headers([.contentType("application/json")])
86+ }
87+ }
88+ }
6189}
6290
6391// Create a network provider
6492let provider = NetworkProvider<UserEndpoint>()
6593
6694// Make a request
6795do {
68- let users: [User] = try await provider.request(UserEndpoint() , as: [User].self)
96+ let users: [User] = try await provider.request(.getUsers , as: [User].self)
6997 print("Users: \(users)")
7098} catch {
7199 print("Error: \(error)")
@@ -95,7 +123,7 @@ let provider = NetworkProvider<UserEndpoint>(
95123
96124// Make a request with all enterprise features
97125do {
98- let users: [User] = try await provider.request(UserEndpoint() , as: [User].self)
126+ let users: [User] = try await provider.request(.getUsers , as: [User].self)
99127 print("Users: \(users)")
100128
101129 // Access metrics
@@ -112,25 +140,108 @@ do {
112140
113141### Endpoints
114142
115- Endpoints define your API endpoints using the `Endpoint` protocol:
143+ Endpoints define your API endpoints using the `Endpoint` protocol with a SwiftUI-style DSL:
144+
145+ #### Basic Endpoint Definition
146+
147+ ```swift
148+ enum UserEndpoint: Endpoint {
149+ case getUsers
150+ case getUser(id: Int)
151+
152+ var body: HTTPEndpoint {
153+ switch self {
154+ case .getUsers:
155+ return HTTP {
156+ BaseURL("https://api.example.com")
157+ Path("/users")
158+ Method(.get)
159+ HTTPTask(.requestPlain)
160+ Headers([.accept("application/json")])
161+ }
162+ case .getUser(let id):
163+ return HTTP {
164+ BaseURL("https://api.example.com")
165+ Path("/users/\(id)")
166+ Method(.get)
167+ HTTPTask(.requestPlain)
168+ }
169+ }
170+ }
171+ }
172+ ```
173+
174+ #### Reusable Base Endpoint
175+
176+ For better reusability, you can define a base endpoint with common settings:
116177
117178```swift
118- struct UserEndpoint: Endpoint {
119- let baseURL = URL(string: "https://api.example.com")!
120- let path = "/users"
121- let method = Http.Method.get
122- let task = Http.Task.requestPlain
123- let headers = [Http.Header.accept("application/json")]
124- let timeout: TimeInterval? = 30
179+ enum UserEndpoint: Endpoint {
180+ case getUsers
181+ case getUser(id: Int)
182+ case createUser(name: String, email: String)
183+
184+ // Base endpoint with common settings
185+ private static var baseEndpoint: HTTPEndpoint {
186+ HTTP {
187+ BaseURL("https://api.example.com")
188+ Headers([
189+ .accept("application/json"),
190+ .authorization("Bearer token")
191+ ])
192+ Timeout(30.0)
193+ }
194+ }
195+
196+ var body: HTTPEndpoint {
197+ switch self {
198+ case .getUsers:
199+ return HTTP(base: Self.baseEndpoint) {
200+ Path("/users")
201+ Method(.get)
202+ HTTPTask(.requestPlain)
203+ }
204+ case .getUser(let id):
205+ return HTTP(base: Self.baseEndpoint) {
206+ Path("/users/\(id)")
207+ Method(.get)
208+ HTTPTask(.requestPlain)
209+ }
210+ case .createUser(let name, let email):
211+ let user = CreateUserRequest(name: name, email: email)
212+ return HTTP(base: Self.baseEndpoint) {
213+ Path("/users")
214+ Method(.post)
215+ HTTPTask(.requestJSON(user))
216+ Headers([.contentType("application/json")])
217+ }
218+ }
219+ }
125220}
221+ ```
126222
127- struct CreateUserEndpoint: Endpoint {
128- let baseURL = URL(string: "https://api.example.com")!
129- let path = "/users"
130- let method = Http.Method.post
131- let task = Http.Task.requestJSON(User(name: "John", email: "john@example.com"))
132- let headers = [Http.Header.contentType("application/json")]
133- let timeout: TimeInterval? = 30
223+ #### Request with Parameters
224+
225+ ```swift
226+ enum SearchEndpoint: Endpoint {
227+ case search(query: String, page: Int = 1, perPage: Int = 20)
228+
229+ var body: HTTPEndpoint {
230+ switch self {
231+ case .search(let query, let page, let perPage):
232+ let parameters = [
233+ "q": query,
234+ "page": "\(page)",
235+ "per_page": "\(perPage)"
236+ ]
237+ return HTTP {
238+ BaseURL("https://api.example.com")
239+ Path("/search")
240+ Method(.get)
241+ HTTPTask(.requestParameters(parameters, encoding: .url))
242+ }
243+ }
244+ }
134245}
135246```
136247
@@ -146,7 +257,7 @@ let modifiers: [RequestModifier] = [
146257]
147258
148259let users: [User] = try await provider.request(
149- UserEndpoint() ,
260+ .getUsers ,
150261 as: [User].self,
151262 modifiers: modifiers
152263)
@@ -207,7 +318,7 @@ if let httpResponse = response as? HTTPURLResponse {
207318
208319```swift
209320do {
210- let users: [User] = try await provider.request(UserEndpoint() , as: [User].self)
321+ let users: [User] = try await provider.request(.getUsers , as: [User].self)
211322 // Success - status code is 2xx
212323} catch NetworkError.serverError(let statusCode, let data) {
213324 // Convert integer status code to enum
@@ -419,7 +530,7 @@ let provider = NetworkProvider<UserEndpoint>(
419530
420531do {
421532 // If offline, will return cached data or throw noConnection error
422- let users: [User] = try await provider.request(UserEndpoint() , as: [User].self)
533+ let users: [User] = try await provider.request(.getUsers , as: [User].self)
423534} catch NetworkError.noConnection {
424535 print("No internet connection and no cached data available")
425536}
@@ -617,7 +728,7 @@ class NetworkTests: XCTestCase {
617728 let provider = NetworkProvider<UserEndpoint>(session: mockSession)
618729
619730 // Test request
620- let users: [User] = try await provider.request(UserEndpoint() , as: [User].self)
731+ let users: [User] = try await provider.request(.getUsers , as: [User].self)
621732 XCTAssertNotNil(users)
622733 }
623734}
@@ -627,7 +738,9 @@ class NetworkTests: XCTestCase {
627738
628739The library follows a protocol-oriented design with clear separation of concerns:
629740
630- - **`Endpoint`** - Defines API endpoints
741+ - **`Endpoint`** - Defines API endpoints using SwiftUI-style DSL with `body` property
742+ - **`HTTPEndpoint`** - Concrete endpoint implementation that stores request information
743+ - **`HTTPBuilder`** - Result builder for declarative endpoint definition
631744- **`NetworkProvider`** - Main networking class with enterprise features
632745- **`Session`** - Handles actual network requests
633746- **`NetworkPlugin`** - Extensible plugin system
@@ -636,6 +749,18 @@ The library follows a protocol-oriented design with clear separation of concerns
636749- **`CacheManager`** - Caching functionality
637750- **`NetworkLogger`** - Logging system
638751
752+ ### DSL Components
753+
754+ The HTTP DSL provides the following components:
755+
756+ - **`BaseURL`** - Sets the base URL for the API
757+ - **`Path`** - Defines the endpoint path
758+ - **`Method`** - Specifies the HTTP method (GET, POST, PUT, DELETE, etc.)
759+ - **`HTTPTask`** - Defines the request task (plain, JSON, parameters, multipart, etc.)
760+ - **`Headers`** - Sets HTTP headers
761+ - **`Timeout`** - Sets custom timeout for the request
762+ - **`HTTP(base:)`** - Inherits properties from a base endpoint for reusability
763+
639764## Contributing
640765
641766Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
0 commit comments