0
# Request Building
1
2
The request building API provides a type-safe DSL for constructing HTTP requests with comprehensive configuration options for URLs, headers, parameters, and body content.
3
4
## Core Types
5
6
```kotlin { .api }
7
class HttpRequestBuilder : HttpMessageBuilder {
8
public var method: HttpMethod = HttpMethod.Get
9
public val url: URLBuilder = URLBuilder()
10
public override val headers: HeadersBuilder = HeadersBuilder()
11
public var body: Any = EmptyContent
12
public var bodyType: TypeInfo?
13
public var executionContext: Job = SupervisorJob()
14
public val attributes: Attributes = Attributes(concurrent = true)
15
16
public fun url(block: URLBuilder.(URLBuilder) -> Unit): Unit
17
}
18
19
// Extension functions for HttpRequestBuilder
20
fun HttpRequestBuilder.url(url: String)
21
fun HttpRequestBuilder.url(url: Url)
22
fun HttpRequestBuilder.url(
23
scheme: String? = null,
24
host: String? = null,
25
port: Int? = null,
26
path: String? = null,
27
block: URLBuilder.() -> Unit = {}
28
)
29
30
var HttpRequestBuilder.host: String
31
var HttpRequestBuilder.port: Int
32
33
fun HttpRequestBuilder.parameter(key: String, value: Any?)
34
35
// Extension functions for HttpMessageBuilder (inherited by HttpRequestBuilder)
36
fun HttpMessageBuilder.header(key: String, value: Any?)
37
fun HttpMessageBuilder.cookie(
38
name: String,
39
value: String,
40
maxAge: Int = 0,
41
expires: GMTDate? = null,
42
domain: String? = null,
43
path: String? = null,
44
secure: Boolean = false,
45
httpOnly: Boolean = false,
46
extensions: Map<String, String?> = emptyMap()
47
)
48
fun HttpMessageBuilder.accept(contentType: ContentType)
49
fun HttpMessageBuilder.basicAuth(username: String, password: String)
50
fun HttpMessageBuilder.bearerAuth(token: String)
51
52
// Body setting functions
53
inline fun <reified T> HttpRequestBuilder.setBody(body: T)
54
fun HttpRequestBuilder.setBody(body: Any?, bodyType: TypeInfo)
55
```
56
57
interface HttpRequest : HttpMessage, CoroutineScope {
58
val call: HttpClientCall
59
val method: HttpMethod
60
val url: Url
61
val attributes: Attributes
62
val content: OutgoingContent
63
}
64
```
65
66
## URL Configuration
67
68
### Basic URL Setting
69
```kotlin
70
client.request {
71
url("https://api.example.com/users/123")
72
}
73
```
74
75
### URL Components
76
```kotlin
77
client.request {
78
url {
79
protocol = URLProtocol.HTTPS
80
host = "api.example.com"
81
port = 443
82
path("users", "123")
83
}
84
}
85
```
86
87
### URL Parameters
88
```kotlin
89
client.request {
90
url("https://api.example.com/users")
91
parameter("page", 1)
92
parameter("limit", 10)
93
parameter("sort", "name")
94
parameter("fields", listOf("id", "name", "email"))
95
}
96
// Results in: https://api.example.com/users?page=1&limit=10&sort=name&fields=id&fields=name&fields=email
97
```
98
99
## Headers Configuration
100
101
### Individual Headers
102
```kotlin
103
client.request {
104
header("Authorization", "Bearer $token")
105
header("X-Custom-Header", "custom-value")
106
accept(ContentType.Application.Json)
107
contentType(ContentType.Application.Json)
108
userAgent("MyApp/1.0")
109
}
110
```
111
112
### Headers Block
113
```kotlin
114
client.request {
115
headers {
116
append("X-Request-ID", requestId)
117
append("X-Client-Version", "1.2.3")
118
if (debugMode) {
119
append("X-Debug", "true")
120
}
121
}
122
}
123
```
124
125
### Authentication Headers
126
```kotlin
127
// Basic authentication
128
client.request {
129
basicAuth("username", "password")
130
}
131
132
// Bearer token
133
client.request {
134
bearerAuth("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
135
}
136
```
137
138
## Request Body
139
140
### JSON Body
141
```kotlin
142
client.request {
143
method = HttpMethod.Post
144
contentType(ContentType.Application.Json)
145
setBody("""{"name": "John", "email": "john@example.com"}""")
146
}
147
```
148
149
### Serializable Object Body
150
```kotlin
151
@Serializable
152
data class User(val name: String, val email: String)
153
154
client.request {
155
method = HttpMethod.Post
156
contentType(ContentType.Application.Json)
157
setBody(User("John", "john@example.com"))
158
}
159
```
160
161
### Form Data Body
162
```kotlin
163
client.request {
164
method = HttpMethod.Post
165
setBody(FormDataContent(Parameters.build {
166
append("name", "John")
167
append("email", "john@example.com")
168
}))
169
}
170
```
171
172
### Multipart Form Body
173
```kotlin
174
client.request {
175
method = HttpMethod.Post
176
setBody(MultiPartFormDataContent(
177
formData {
178
append("name", "John")
179
append("file", "document.pdf", ContentType.Application.Pdf) {
180
writeFully(fileBytes)
181
}
182
}
183
))
184
}
185
```
186
187
### Binary Body
188
```kotlin
189
client.request {
190
method = HttpMethod.Put
191
contentType(ContentType.Application.OctetStream)
192
setBody(byteArrayOf(0x01, 0x02, 0x03))
193
}
194
```
195
196
### Channel Body
197
```kotlin
198
client.request {
199
method = HttpMethod.Post
200
setBody(object : OutgoingContent.WriteChannelContent() {
201
override suspend fun writeTo(channel: ByteWriteChannel) {
202
channel.writeStringUtf8("streaming data")
203
channel.close()
204
}
205
})
206
}
207
```
208
209
## HTTP Methods
210
211
### Setting Method Explicitly
212
```kotlin
213
client.request {
214
method = HttpMethod.Patch
215
url("https://api.example.com/users/123")
216
setBody("""{"name": "Updated Name"}""")
217
}
218
```
219
220
### Custom HTTP Methods
221
```kotlin
222
val customMethod = HttpMethod("CUSTOM")
223
client.request {
224
method = customMethod
225
url("https://api.example.com/custom-endpoint")
226
}
227
```
228
229
## Request Attributes
230
231
Attributes allow storing custom data with requests:
232
233
```kotlin
234
val RequestIdKey = AttributeKey<String>("RequestId")
235
236
client.request {
237
attributes.put(RequestIdKey, "req-123")
238
url("https://api.example.com/users")
239
}
240
241
// Access in plugins or interceptors
242
val requestId = request.attributes[RequestIdKey]
243
```
244
245
## Timeout Configuration
246
247
With the HttpTimeout plugin installed:
248
249
```kotlin
250
client.request {
251
timeout {
252
requestTimeoutMillis = 30000
253
connectTimeoutMillis = 10000
254
socketTimeoutMillis = 20000
255
}
256
url("https://slow-api.example.com")
257
}
258
```
259
260
## Unix Socket Requests
261
262
Support for Unix domain sockets:
263
264
```kotlin
265
client.request {
266
url.protocol = URLProtocol.createOrDefault("unix")
267
url.host = "/tmp/socket"
268
url.encodedPath = "/path"
269
}
270
```
271
272
## Advanced URL Building
273
274
### Path Segments
275
```kotlin
276
client.request {
277
url {
278
appendPathSegments("users", userId.toString(), "profile")
279
}
280
}
281
```
282
283
### Encoded Parameters
284
```kotlin
285
client.request {
286
url {
287
parameters.append("query", "hello world") // Automatically encoded
288
parameters.appendAll("tags", listOf("kotlin", "http"))
289
}
290
}
291
```
292
293
### Fragment
294
```kotlin
295
client.request {
296
url {
297
fragment = "section1"
298
}
299
}
300
```
301
302
## Request Validation
303
304
### URL Validation
305
```kotlin
306
try {
307
client.request {
308
url("not-a-valid-url")
309
}
310
} catch (e: URLParserException) {
311
println("Invalid URL: ${e.message}")
312
}
313
```
314
315
### Content Type Validation
316
```kotlin
317
client.request {
318
// Ensure Content-Type matches body type
319
contentType(ContentType.Application.Json)
320
setBody(jsonString) // Must be valid JSON
321
}
322
```