or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

http-client.mdindex.mdning.mdoauth.mdopenid.mdssl.mdtesting.md

ning.mddocs/

0

# Ning HTTP Client Implementation

1

2

Ning AsyncHttpClient-based implementation providing the actual HTTP transport layer with advanced configuration options. This is the default implementation used by Play WS for HTTP operations.

3

4

## Capabilities

5

6

### Ning WS Client

7

8

Main Ning-based WSClient implementation.

9

10

```scala { .api }

11

/**

12

* WSClient implementation using Ning AsyncHttpClient

13

* @param config AsyncHttpClient configuration

14

*/

15

case class NingWSClient(config: AsyncHttpClientConfig) extends WSClient {

16

def underlying[T]: T

17

def url(url: String): WSRequest

18

def close(): Unit

19

}

20

21

/**

22

* Ning WSClient factory

23

*/

24

object NingWSClient {

25

/** Create client with default configuration */

26

def apply(): NingWSClient

27

28

/** Create client with custom configuration */

29

def apply(config: NingWSClientConfig): NingWSClient

30

}

31

```

32

33

**Basic Ning Client Usage:**

34

35

```scala

36

import play.api.libs.ws.ning._

37

38

// Create client with default configuration

39

val client = NingWSClient()

40

41

// Use the client

42

val response = client.url("https://api.example.com/data").get()

43

44

// Always close the client when done

45

client.close()

46

```

47

48

### Ning WS Request

49

50

Ning-specific WSRequest implementation with additional methods.

51

52

```scala { .api }

53

/**

54

* Ning-specific WSRequest implementation

55

*/

56

case class NingWSRequest(

57

client: NingWSClient,

58

url: String,

59

method: String = "GET",

60

body: WSBody = EmptyBody,

61

headers: Map[String, Seq[String]] = Map.empty,

62

queryString: Map[String, Seq[String]] = Map.empty,

63

calc: Option[WSSignatureCalculator] = None,

64

auth: Option[(String, String, WSAuthScheme)] = None,

65

followRedirects: Option[Boolean] = None,

66

requestTimeout: Option[Int] = None,

67

virtualHost: Option[String] = None,

68

proxyServer: Option[WSProxyServer] = None

69

) extends WSRequest {

70

71

// Additional Ning-specific methods

72

/** Get current request headers */

73

def requestHeaders: Map[String, Seq[String]]

74

75

/** Get specific request header */

76

def requestHeader(name: String): Option[String]

77

78

/** Get current query parameters */

79

def requestQueryParams: Map[String, Seq[String]]

80

81

/** Get current URL (may include signature parameters) */

82

def requestUrl: String

83

84

/** Get request body as byte array */

85

def getBody: Option[Array[Byte]]

86

}

87

```

88

89

### Ning WS Response

90

91

Ning-specific WSResponse implementation.

92

93

```scala { .api }

94

/**

95

* Ning-specific WSResponse implementation

96

* @param ahcResponse Underlying AsyncHttpClient response

97

*/

98

case class NingWSResponse(ahcResponse: AHCResponse) extends WSResponse {

99

def status: Int

100

def statusText: String

101

def header(key: String): Option[String]

102

def allHeaders: Map[String, Seq[String]]

103

def cookies: Seq[WSCookie]

104

def cookie(name: String): Option[WSCookie]

105

def body: String

106

def xml: Elem

107

def json: JsValue

108

def bodyAsBytes: Array[Byte]

109

def underlying[T]: T

110

}

111

```

112

113

### Ning Client Configuration

114

115

Comprehensive configuration options for the Ning AsyncHttpClient.

116

117

```scala { .api }

118

/**

119

* Ning WSClient configuration

120

*/

121

case class NingWSClientConfig(

122

wsClientConfig: WSClientConfig = WSClientConfig(),

123

allowPoolingConnection: Boolean = true,

124

allowSslConnectionPool: Boolean = true,

125

ioThreadMultiplier: Int = 2,

126

maxConnectionsPerHost: Int = -1,

127

maxConnectionsTotal: Int = -1,

128

maxConnectionLifetime: Duration = Duration.Inf,

129

idleConnectionInPoolTimeout: Duration = 1.minute,

130

webSocketIdleTimeout: Duration = 15.minutes,

131

maxNumberOfRedirects: Int = 5,

132

maxRequestRetry: Int = 5,

133

disableUrlEncoding: Boolean = false

134

)

135

```

136

137

**Advanced Ning Configuration:**

138

139

```scala

140

import scala.concurrent.duration._

141

142

val ningConfig = NingWSClientConfig(

143

wsClientConfig = WSClientConfig(

144

connectionTimeout = 10.seconds,

145

requestTimeout = 30.seconds,

146

followRedirects = true

147

),

148

allowPoolingConnection = true,

149

maxConnectionsPerHost = 20,

150

maxConnectionsTotal = 100,

151

maxConnectionLifetime = 5.minutes,

152

idleConnectionInPoolTimeout = 2.minutes,

153

maxNumberOfRedirects = 3,

154

maxRequestRetry = 2

155

)

156

157

val client = NingWSClient(ningConfig)

158

```

159

160

### Ning Configuration Factory

161

162

Factory for creating Ning configurations from WS configurations.

163

164

```scala { .api }

165

/**

166

* Factory for creating Ning configurations

167

*/

168

object NingWSClientConfigFactory {

169

/**

170

* Create Ning configuration from WSClient configuration

171

*/

172

def forClientConfig(config: WSClientConfig): NingWSClientConfig

173

}

174

```

175

176

### AsyncHttpClient Configuration Builder

177

178

Builder for creating AsyncHttpClient configurations.

179

180

```scala { .api }

181

/**

182

* Builder for AsyncHttpClient configuration

183

*/

184

class NingAsyncHttpClientConfigBuilder(ningConfig: NingWSClientConfig) {

185

/** Configure the AsyncHttpClient builder */

186

def configure(): AsyncHttpClientConfig.Builder

187

188

/** Build the final configuration */

189

def build(): AsyncHttpClientConfig

190

191

/** Modify the underlying builder */

192

def modifyUnderlying(

193

modify: AsyncHttpClientConfig.Builder => AsyncHttpClientConfig.Builder

194

): NingAsyncHttpClientConfigBuilder

195

}

196

```

197

198

**Custom AsyncHttpClient Configuration:**

199

200

```scala

201

import com.ning.http.client.AsyncHttpClientConfig

202

203

val builder = new NingAsyncHttpClientConfigBuilder(ningConfig)

204

.modifyUnderlying { ahcBuilder =>

205

ahcBuilder

206

.setUserAgent("MyApp/1.0")

207

.setCompressionEnforced(true)

208

.setFollowRedirect(true)

209

}

210

211

val ahcConfig = builder.build()

212

val client = NingWSClient(ahcConfig)

213

```

214

215

### Dependency Injection Support

216

217

Play Framework dependency injection support for Ning WS client.

218

219

```scala { .api }

220

/**

221

* Play module for Ning WS dependency injection

222

*/

223

class NingWSModule extends Module {

224

def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]]

225

}

226

227

/**

228

* Injectable WSAPI implementation using Ning

229

*/

230

class NingWSAPI @Inject()(client: WSClient) extends WSAPI {

231

def client: WSClient

232

def url(url: String): WSRequest

233

}

234

235

/**

236

* Components trait for manual dependency injection

237

*/

238

trait NingWSComponents {

239

def wsClient: WSClient

240

def wsApi: WSAPI

241

}

242

```

243

244

**Manual Dependency Injection Setup:**

245

246

```scala

247

import play.api.libs.ws.ning._

248

249

trait MyApplicationComponents extends NingWSComponents {

250

// Provide WSClient implementation

251

lazy val wsClient: WSClient = {

252

val config = NingWSClientConfig()

253

NingWSClient(config)

254

}

255

256

// Provide WSAPI implementation

257

lazy val wsApi: WSAPI = new NingWSAPI(wsClient)

258

259

// Don't forget to close client on app shutdown

260

override def applicationLifecycle: ApplicationLifecycle = {

261

val lifecycle = super.applicationLifecycle

262

lifecycle.addStopHook(() => Future.successful(wsClient.close()))

263

lifecycle

264

}

265

}

266

```

267

268

### Connection Pool Management

269

270

Managing connection pools with Ning client.

271

272

```scala

273

// Configuration for connection pooling

274

val poolConfig = NingWSClientConfig(

275

allowPoolingConnection = true,

276

allowSslConnectionPool = true,

277

maxConnectionsPerHost = 50, // Max connections per host

278

maxConnectionsTotal = 200, // Max total connections

279

maxConnectionLifetime = 10.minutes, // Max connection age

280

idleConnectionInPoolTimeout = 5.minutes // Idle timeout

281

)

282

283

val client = NingWSClient(poolConfig)

284

285

// The client will automatically manage the connection pool

286

// Connections are reused for better performance

287

val response1 = client.url("https://api.example.com/endpoint1").get()

288

val response2 = client.url("https://api.example.com/endpoint2").get()

289

290

// Both requests can reuse the same connection to api.example.com

291

```

292

293

### Request Retry Configuration

294

295

Configure automatic request retries for failed requests.

296

297

```scala

298

val retryConfig = NingWSClientConfig(

299

maxRequestRetry = 3, // Retry failed requests up to 3 times

300

maxNumberOfRedirects = 5 // Follow up to 5 redirects

301

)

302

303

val client = NingWSClient(retryConfig)

304

305

// This request will be automatically retried on failure

306

val response = client.url("https://unreliable-api.com/data").get()

307

```

308

309

### WebSocket Configuration

310

311

Configure WebSocket idle timeout (for when using WS client with WebSockets).

312

313

```scala

314

val wsConfig = NingWSClientConfig(

315

webSocketIdleTimeout = 30.minutes // Close idle WebSocket connections after 30 minutes

316

)

317

318

val client = NingWSClient(wsConfig)

319

```

320

321

### Performance Tuning

322

323

Optimize Ning client for different scenarios.

324

325

**High Throughput Configuration:**

326

327

```scala

328

val highThroughputConfig = NingWSClientConfig(

329

wsClientConfig = WSClientConfig(

330

connectionTimeout = 5.seconds,

331

requestTimeout = 30.seconds

332

),

333

allowPoolingConnection = true,

334

allowSslConnectionPool = true,

335

ioThreadMultiplier = 4, // More I/O threads for high concurrency

336

maxConnectionsPerHost = 100,

337

maxConnectionsTotal = 500,

338

maxConnectionLifetime = 30.minutes,

339

idleConnectionInPoolTimeout = 10.minutes

340

)

341

```

342

343

**Low Latency Configuration:**

344

345

```scala

346

val lowLatencyConfig = NingWSClientConfig(

347

wsClientConfig = WSClientConfig(

348

connectionTimeout = 1.second,

349

requestTimeout = 5.seconds

350

),

351

allowPoolingConnection = true,

352

maxConnectionsPerHost = 10, // Smaller pool for faster connection reuse

353

maxConnectionsTotal = 50,

354

idleConnectionInPoolTimeout = 1.minute, // Shorter idle timeout

355

maxRequestRetry = 1 // Fewer retries for lower latency

356

)

357

```

358

359

**Resource-Constrained Configuration:**

360

361

```scala

362

val resourceConstrainedConfig = NingWSClientConfig(

363

allowPoolingConnection = true,

364

maxConnectionsPerHost = 5, // Limit connections

365

maxConnectionsTotal = 20, // Lower total pool size

366

maxConnectionLifetime = 2.minutes, // Shorter connection lifetime

367

idleConnectionInPoolTimeout = 30.seconds, // Quick idle cleanup

368

ioThreadMultiplier = 1 // Fewer threads

369

)

370

```

371

372

### Custom Request/Response Processing

373

374

Access underlying Ning objects for advanced processing.

375

376

```scala

377

client.url("https://api.example.com/data").get().map { response =>

378

// Access underlying Ning response

379

val ningResponse = response.underlying[com.ning.http.client.Response]

380

381

// Get additional response information

382

val responseTime = ningResponse.getResponseTime

383

val uri = ningResponse.getUri

384

val contentLength = ningResponse.getContentLength

385

386

println(s"Response time: ${responseTime}ms")

387

println(s"Content length: $contentLength bytes")

388

}

389

```

390

391

### Complete Example: Production Ning Setup

392

393

```scala

394

import play.api.libs.ws.ning._

395

import play.api.libs.ws.ssl._

396

import scala.concurrent.duration._

397

import scala.concurrent.ExecutionContext.Implicits.global

398

399

// Create production-ready Ning configuration

400

val productionConfig = NingWSClientConfig(

401

wsClientConfig = WSClientConfig(

402

connectionTimeout = 10.seconds,

403

idleTimeout = 60.seconds,

404

requestTimeout = 30.seconds,

405

followRedirects = true,

406

useProxyProperties = true,

407

userAgent = Some("MyApp/2.0"),

408

compressionEnabled = true,

409

ssl = SSLConfig(

410

protocol = "TLSv1.2",

411

enabledProtocols = Some(Seq("TLSv1.2"))

412

)

413

),

414

allowPoolingConnection = true,

415

allowSslConnectionPool = true,

416

ioThreadMultiplier = 2,

417

maxConnectionsPerHost = 20,

418

maxConnectionsTotal = 100,

419

maxConnectionLifetime = 10.minutes,

420

idleConnectionInPoolTimeout = 5.minutes,

421

maxNumberOfRedirects = 3,

422

maxRequestRetry = 2,

423

disableUrlEncoding = false

424

)

425

426

// Create and use the client

427

val client = NingWSClient(productionConfig)

428

429

// Make requests

430

val future = for {

431

response1 <- client.url("https://api.service1.com/data").get()

432

response2 <- client.url("https://api.service2.com/data").get()

433

} yield {

434

(response1.json, response2.json)

435

}

436

437

future.map { case (json1, json2) =>

438

// Process responses

439

println("Data retrieved successfully")

440

}.recover { case ex =>

441

println(s"Request failed: ${ex.getMessage}")

442

}.andThen { case _ =>

443

// Always clean up resources

444

client.close()

445

}

446

```