0
# HTTP Client Operations
1
2
Core HTTP client functionality for making RESTful API calls, handling responses, and managing connection settings. The Play WS HTTP client provides both static factory methods and dependency injection support for both Scala and Java APIs.
3
4
## Capabilities
5
6
### WS Object - Scala API
7
8
Main entry point for creating HTTP requests using the application's default client.
9
10
```scala { .api }
11
/**
12
* Static object providing HTTP client access
13
*/
14
object WS {
15
/** Get or create the application's default WSClient */
16
def client(implicit app: Application): WSClient
17
18
/** Create a request using the application's default client */
19
def url(url: String)(implicit app: Application): WSRequest
20
21
/** Create a request using a magnet pattern */
22
def url(magnet: WSRequestMagnet): WSRequest
23
24
/** Create a request with an explicit client */
25
def clientUrl(url: String)(implicit client: WSClient): WSRequest
26
}
27
```
28
29
**Usage Examples:**
30
31
```scala
32
import play.api.libs.ws.WS
33
import play.api.Application
34
import scala.concurrent.ExecutionContext.Implicits.global
35
36
implicit val app: Application = // Your Play application
37
38
// Create a simple GET request
39
val response = WS.url("https://api.example.com/users").get()
40
41
// POST with form data
42
val formData = Map("name" -> Seq("John"), "email" -> Seq("john@example.com"))
43
val postResponse = WS.url("https://api.example.com/users").post(formData)
44
```
45
46
### WSClient Interface - Scala API
47
48
HTTP client interface for creating requests and managing connections.
49
50
```scala { .api }
51
/**
52
* HTTP client interface
53
*/
54
trait WSClient {
55
/** Get the underlying implementation (cast explicitly to desired type) */
56
def underlying[T]: T
57
58
/** Create a request builder for the given URL */
59
def url(url: String): WSRequest
60
61
/** Release client resources */
62
def close(): Unit
63
}
64
```
65
66
**Dependency Injection Usage:**
67
68
```scala
69
import javax.inject.Inject
70
import play.api.libs.ws.WSClient
71
72
class MyService @Inject()(ws: WSClient) {
73
def fetchUser(id: String): Future[User] = {
74
ws.url(s"https://api.example.com/users/$id")
75
.get()
76
.map(response => Json.parse(response.body).as[User])
77
}
78
}
79
```
80
81
### WS Object - Java API
82
83
Main entry point for creating HTTP requests using the Java API.
84
85
```java { .api }
86
/**
87
* Static class providing HTTP client access for Java
88
*/
89
public class WS {
90
/** Get the application's default WSClient */
91
public static WSClient client()
92
93
/** Create a request using the application's default client */
94
public static WSRequest url(String url)
95
96
/** Create a test client bound to a specific port */
97
public static WSClient newClient(int port)
98
}
99
```
100
101
**Usage Examples:**
102
103
```java
104
import play.libs.ws.*;
105
import play.libs.F.Promise;
106
107
// Create a simple GET request
108
Promise<WSResponse> response = WS.url("https://api.example.com/users").get();
109
110
// POST with form data
111
Map<String, String> formData = new HashMap<>();
112
formData.put("name", "John");
113
formData.put("email", "john@example.com");
114
Promise<WSResponse> postResponse = WS.url("https://api.example.com/users").post(formData);
115
```
116
117
### WSClient Interface - Java API
118
119
HTTP client interface for creating requests and managing connections.
120
121
```java { .api }
122
/**
123
* HTTP client interface for Java
124
*/
125
public interface WSClient extends Closeable {
126
/** Get the underlying implementation */
127
Object getUnderlying()
128
129
/** Create a request builder for the given URL */
130
WSRequest url(String url)
131
132
/** Release client resources */
133
void close()
134
}
135
```
136
137
**Dependency Injection Usage:**
138
139
```java
140
import javax.inject.Inject;
141
import play.libs.ws.WSClient;
142
143
public class MyService {
144
private final WSClient ws;
145
146
@Inject
147
public MyService(WSClient ws) {
148
this.ws = ws;
149
}
150
151
public Promise<User> fetchUser(String id) {
152
return ws.url("https://api.example.com/users/" + id)
153
.get()
154
.map(response -> Json.fromJson(response.asJson(), User.class));
155
}
156
}
157
```
158
159
### WSRequest Interface - Scala API
160
161
HTTP request builder providing fluent API for configuring and executing requests.
162
163
```scala { .api }
164
/**
165
* HTTP request builder with fluent configuration API
166
*/
167
trait WSRequest {
168
// Properties
169
def url: String
170
def method: String
171
def body: WSBody
172
def headers: Map[String, Seq[String]]
173
def queryString: Map[String, Seq[String]]
174
175
// Configuration methods
176
def withHeaders(hdrs: (String, String)*): WSRequest
177
def withQueryString(parameters: (String, String)*): WSRequest
178
def withFollowRedirects(follow: Boolean): WSRequest
179
def withRequestTimeout(timeout: Long): WSRequest
180
def withVirtualHost(vh: String): WSRequest
181
def withProxyServer(proxyServer: WSProxyServer): WSRequest
182
def withBody(body: WSBody): WSRequest
183
def withMethod(method: String): WSRequest
184
def withAuth(username: String, password: String, scheme: WSAuthScheme): WSRequest
185
def sign(calc: WSSignatureCalculator): WSRequest
186
187
// HTTP method execution
188
def get(): Future[WSResponse]
189
def post[T](body: T)(implicit wrt: Writeable[T]): Future[WSResponse]
190
def put[T](body: T)(implicit wrt: Writeable[T]): Future[WSResponse]
191
def patch[T](body: T)(implicit wrt: Writeable[T]): Future[WSResponse]
192
def delete(): Future[WSResponse]
193
def head(): Future[WSResponse]
194
def options(): Future[WSResponse]
195
def execute(): Future[WSResponse]
196
197
// Streaming support
198
def stream(): Future[(WSResponseHeaders, Enumerator[Array[Byte]])]
199
}
200
```
201
202
**Configuration Examples:**
203
204
```scala
205
import play.api.libs.ws._
206
import scala.concurrent.duration._
207
208
// Configure request with headers, timeout, and query parameters
209
val request = WS.url("https://api.example.com/search")
210
.withHeaders(
211
"Authorization" -> "Bearer token123",
212
"Content-Type" -> "application/json"
213
)
214
.withQueryString(
215
"q" -> "scala",
216
"limit" -> "10"
217
)
218
.withRequestTimeout(5.seconds.toMillis)
219
.withFollowRedirects(false)
220
221
// Execute the configured request
222
val response = request.get()
223
```
224
225
### WSRequest Interface - Java API
226
227
HTTP request builder providing fluent API for configuring and executing requests in Java.
228
229
```java { .api }
230
/**
231
* HTTP request builder with fluent configuration API for Java
232
*/
233
public interface WSRequest {
234
// Properties
235
String getUrl()
236
String getMethod()
237
238
// Configuration methods
239
WSRequest setHeader(String name, String value)
240
WSRequest setQueryParameter(String name, String value)
241
WSRequest setAuth(String username, String password)
242
WSRequest setAuth(String username, String password, WSAuthScheme scheme)
243
WSRequest setFollowRedirects(boolean followRedirects)
244
WSRequest setVirtualHost(String virtualHost)
245
WSRequest setTimeout(long timeout)
246
WSRequest setBody(Object body)
247
WSRequest setMethod(String method)
248
WSRequest sign(WSSignatureCalculator calculator)
249
250
// HTTP method execution
251
Promise<WSResponse> get()
252
Promise<WSResponse> post(Object body)
253
Promise<WSResponse> put(Object body)
254
Promise<WSResponse> patch(Object body)
255
Promise<WSResponse> delete()
256
Promise<WSResponse> head()
257
Promise<WSResponse> options()
258
Promise<WSResponse> execute()
259
}
260
```
261
262
**Configuration Examples:**
263
264
```java
265
import play.libs.ws.*;
266
import java.util.concurrent.TimeUnit;
267
268
// Configure request with headers, timeout, and query parameters
269
WSRequest request = WS.url("https://api.example.com/search")
270
.setHeader("Authorization", "Bearer token123")
271
.setHeader("Content-Type", "application/json")
272
.setQueryParameter("q", "java")
273
.setQueryParameter("limit", "10")
274
.setTimeout(TimeUnit.SECONDS.toMillis(5))
275
.setFollowRedirects(false);
276
277
// Execute the configured request
278
Promise<WSResponse> response = request.get();
279
```
280
281
### WSResponse Interface - Scala API
282
283
HTTP response interface providing access to status, headers, cookies, and body content.
284
285
```scala { .api }
286
/**
287
* HTTP response interface
288
*/
289
trait WSResponse {
290
// Status information
291
def status: Int
292
def statusText: String
293
294
// Headers and cookies
295
def header(key: String): Option[String]
296
def allHeaders: Map[String, Seq[String]]
297
def cookies: Seq[WSCookie]
298
def cookie(name: String): Option[WSCookie]
299
300
// Body content access
301
def body: String
302
def xml: Elem
303
def json: JsValue
304
def bodyAsBytes: Array[Byte]
305
306
// Underlying implementation access
307
def underlying[T]: T
308
}
309
```
310
311
**Response Handling Examples:**
312
313
```scala
314
import play.api.libs.json._
315
import scala.xml.Elem
316
317
WS.url("https://api.example.com/data").get().map { response =>
318
// Check status
319
if (response.status == 200) {
320
// Access different body formats
321
val textBody: String = response.body
322
val jsonBody: JsValue = response.json
323
val xmlBody: Elem = response.xml
324
val bytesBody: Array[Byte] = response.bodyAsBytes
325
326
// Access headers
327
val contentType = response.header("Content-Type")
328
val allHeaders = response.allHeaders
329
330
// Access cookies
331
val sessionCookie = response.cookie("JSESSIONID")
332
val allCookies = response.cookies
333
}
334
}
335
```
336
337
### WSResponse Interface - Java API
338
339
HTTP response interface providing access to status, headers, cookies, and body content in Java.
340
341
```java { .api }
342
/**
343
* HTTP response interface for Java
344
*/
345
public interface WSResponse {
346
// Status information
347
int getStatus()
348
String getStatusText()
349
350
// Headers and cookies
351
String getHeader(String key)
352
Map<String, List<String>> getAllHeaders()
353
List<WSCookie> getCookies()
354
WSCookie getCookie(String name)
355
356
// Body content access
357
String getBody()
358
Document asXml()
359
JsonNode asJson()
360
InputStream getBodyAsStream()
361
byte[] asByteArray()
362
363
// Underlying implementation access
364
Object getUnderlying()
365
}
366
```
367
368
**Response Handling Examples:**
369
370
```java
371
import play.libs.ws.*;
372
import com.fasterxml.jackson.databind.JsonNode;
373
import org.w3c.dom.Document;
374
375
WS.url("https://api.example.com/data").get().map(response -> {
376
// Check status
377
if (response.getStatus() == 200) {
378
// Access different body formats
379
String textBody = response.getBody();
380
JsonNode jsonBody = response.asJson();
381
Document xmlBody = response.asXml();
382
byte[] bytesBody = response.asByteArray();
383
384
// Access headers
385
String contentType = response.getHeader("Content-Type");
386
Map<String, List<String>> allHeaders = response.getAllHeaders();
387
388
// Access cookies
389
WSCookie sessionCookie = response.getCookie("JSESSIONID");
390
List<WSCookie> allCookies = response.getCookies();
391
}
392
return response;
393
});
394
```
395
396
### Request Body Types
397
398
Different body types for HTTP requests.
399
400
```scala { .api }
401
/**
402
* Base trait for request bodies
403
*/
404
sealed trait WSBody
405
406
/** In-memory byte array body */
407
case class InMemoryBody(bytes: Array[Byte]) extends WSBody
408
409
/** File-based body */
410
case class FileBody(file: File) extends WSBody
411
412
/** Streaming body using iteratees */
413
case class StreamedBody(bytes: Enumerator[Array[Byte]]) extends WSBody
414
415
/** Empty body */
416
case object EmptyBody extends WSBody
417
```
418
419
**Body Usage Examples:**
420
421
```scala
422
import java.io.File
423
import play.api.libs.iteratee.Enumerator
424
425
// JSON body (automatically converted to InMemoryBody)
426
val jsonBody = Json.obj("name" -> "John", "age" -> 25)
427
WS.url("https://api.example.com/users").post(jsonBody)
428
429
// File upload
430
val file = new File("/path/to/file.txt")
431
WS.url("https://api.example.com/upload").post(FileBody(file))
432
433
// Form data
434
val formData = Map("field1" -> Seq("value1"), "field2" -> Seq("value2"))
435
WS.url("https://api.example.com/form").post(formData)
436
437
// Raw bytes
438
val bytes = "Hello World".getBytes("UTF-8")
439
WS.url("https://api.example.com/data").post(InMemoryBody(bytes))
440
```
441
442
### Authentication Schemes
443
444
Available authentication schemes for HTTP requests.
445
446
```scala { .api }
447
/**
448
* Authentication scheme marker trait
449
*/
450
trait WSAuthScheme
451
452
/**
453
* Authentication schemes
454
*/
455
object WSAuthScheme {
456
case object BASIC extends WSAuthScheme
457
case object DIGEST extends WSAuthScheme
458
case object NTLM extends WSAuthScheme
459
case object SPNEGO extends WSAuthScheme
460
case object KERBEROS extends WSAuthScheme
461
case object NONE extends WSAuthScheme
462
}
463
```
464
465
**Authentication Examples:**
466
467
```scala
468
// Basic authentication
469
WS.url("https://api.example.com/secure")
470
.withAuth("username", "password", WSAuthScheme.BASIC)
471
.get()
472
473
// Digest authentication
474
WS.url("https://api.example.com/secure")
475
.withAuth("username", "password", WSAuthScheme.DIGEST)
476
.get()
477
```
478
479
### Proxy Configuration
480
481
HTTP proxy server configuration.
482
483
```scala { .api }
484
/**
485
* Proxy server configuration
486
*/
487
trait WSProxyServer {
488
def host: String
489
def port: Int
490
def protocol: Option[String]
491
def principal: Option[String]
492
def password: Option[String]
493
def ntlmDomain: Option[String]
494
def encoding: Option[String]
495
def nonProxyHosts: Option[Seq[String]]
496
}
497
498
/**
499
* Default proxy server implementation
500
*/
501
case class DefaultWSProxyServer(
502
host: String,
503
port: Int,
504
protocol: Option[String] = None,
505
principal: Option[String] = None,
506
password: Option[String] = None,
507
ntlmDomain: Option[String] = None,
508
encoding: Option[String] = None,
509
nonProxyHosts: Option[Seq[String]] = None
510
) extends WSProxyServer
511
```
512
513
**Proxy Usage:**
514
515
```scala
516
val proxy = DefaultWSProxyServer("proxy.company.com", 8080)
517
WS.url("https://external-api.com/data")
518
.withProxyServer(proxy)
519
.get()
520
```
521
522
### Cookie Support
523
524
Cookie handling in responses.
525
526
```scala { .api }
527
/**
528
* HTTP cookie interface
529
*/
530
trait WSCookie {
531
def underlying[T]: T
532
def domain: String
533
def name: Option[String]
534
def value: Option[String]
535
def path: String
536
def expires: Option[Long] // deprecated
537
def maxAge: Option[Int]
538
def secure: Boolean
539
}
540
```
541
542
### Response Headers
543
544
Response header information.
545
546
```scala { .api }
547
/**
548
* HTTP response headers
549
*/
550
trait WSResponseHeaders {
551
def status: Int
552
def headers: Map[String, Seq[String]]
553
}
554
555
/**
556
* Default response headers implementation
557
*/
558
case class DefaultWSResponseHeaders(
559
status: Int,
560
headers: Map[String, Seq[String]]
561
) extends WSResponseHeaders
562
```
563
564
### Streaming Support
565
566
For handling large responses with streaming.
567
568
```scala { .api }
569
// Streaming response handling
570
WS.url("https://api.example.com/large-file").stream().map {
571
case (headers, body) =>
572
// Process headers
573
println(s"Content-Length: ${headers.headers.get("Content-Length")}")
574
575
// Process body stream
576
body |>>> Iteratee.foreach[Array[Byte]] { chunk =>
577
// Process each chunk
578
println(s"Received ${chunk.length} bytes")
579
}
580
}
581
```