Skip to content

Commit 3d6c4e9

Browse files
committed
Update README
1 parent f119ddb commit 3d6c4e9

File tree

1 file changed

+155
-30
lines changed

1 file changed

+155
-30
lines changed

README.md

Lines changed: 155 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,50 @@ The documentation for releases and `main` are available here:
5050
```swift
5151
import 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
6492
let provider = NetworkProvider<UserEndpoint>()
6593

6694
// Make a request
6795
do {
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
97125
do {
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

148259
let 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
209320
do {
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

420531
do {
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

628739
The 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

641766
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.

0 commit comments

Comments
 (0)