or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

aop.mdconfiguration.mddependency-injection.mdfunctions.mdhttp-client.mdhttp-server.mdindex.mdmanagement.mdmessaging.mdreactive.mdretry.mdscheduling.mdwebsocket.md

http-server.mddocs/

0

# HTTP Server

1

2

Micronaut's HTTP server provides high-performance request handling with both blocking and non-blocking APIs, comprehensive routing, content negotiation, and error handling.

3

4

## Capabilities

5

6

### Controllers

7

8

Define HTTP endpoints using controller classes with declarative routing annotations.

9

10

```java { .api }

11

/**

12

* Basic controller with GET endpoint

13

*/

14

@Controller("/api/users")

15

public class UserController {

16

17

@Get("/{id}")

18

public User getUser(Long id) {

19

return userService.findById(id);

20

}

21

22

@Get

23

public List<User> getUsers(@QueryValue Optional<String> filter) {

24

return userService.findAll(filter.orElse(null));

25

}

26

27

@Post

28

public HttpResponse<User> createUser(@Body @Valid User user) {

29

User created = userService.save(user);

30

return HttpResponse.created(created);

31

}

32

33

@Put("/{id}")

34

public User updateUser(Long id, @Body @Valid User user) {

35

return userService.update(id, user);

36

}

37

38

@Delete("/{id}")

39

@Status(HttpStatus.NO_CONTENT)

40

public void deleteUser(Long id) {

41

userService.delete(id);

42

}

43

}

44

```

45

46

### Parameter Binding

47

48

Bind HTTP request data to method parameters with type conversion and validation.

49

50

```java { .api }

51

/**

52

* Path parameters, query parameters, and headers

53

*/

54

@Controller("/api/products")

55

public class ProductController {

56

57

@Get("/{id}")

58

public Product getProduct(@PathVariable Long id,

59

@QueryValue Optional<Boolean> includeDetails,

60

@Header("Accept-Language") String language) {

61

return productService.findById(id, includeDetails.orElse(false), language);

62

}

63

64

@Get

65

public Page<Product> searchProducts(@QueryValue String q,

66

@QueryValue @Positive int page,

67

@QueryValue @Positive int size,

68

@QueryValue Optional<String> sort) {

69

return productService.search(q, page, size, sort.orElse("name"));

70

}

71

72

@Post("/bulk")

73

public List<Product> createProducts(@Body List<@Valid Product> products,

74

@Header("X-Batch-Id") String batchId) {

75

return productService.createBatch(products, batchId);

76

}

77

}

78

79

/**

80

* Form data and multipart handling

81

*/

82

@Controller("/upload")

83

public class FileUploadController {

84

85

@Post(value = "/", consumes = MediaType.MULTIPART_FORM_DATA)

86

public HttpResponse<String> upload(@Part CompletedFileUpload file,

87

@Part("description") String description) {

88

String filename = fileService.store(file, description);

89

return HttpResponse.ok("File uploaded: " + filename);

90

}

91

92

@Post(value = "/form", consumes = MediaType.APPLICATION_FORM_URLENCODED)

93

public HttpResponse<String> handleForm(@Body Map<String, String> formData) {

94

return HttpResponse.ok("Form processed");

95

}

96

}

97

```

98

99

### Content Negotiation

100

101

Handle different content types for request and response bodies.

102

103

```java { .api }

104

/**

105

* Content type handling

106

*/

107

@Controller("/api/data")

108

public class DataController {

109

110

@Get(value = "/export", produces = {

111

MediaType.APPLICATION_JSON,

112

MediaType.APPLICATION_XML,

113

"text/csv"

114

})

115

public Object exportData(@Header("Accept") String acceptHeader) {

116

if (acceptHeader.contains("xml")) {

117

return new XmlDataResponse();

118

} else if (acceptHeader.contains("csv")) {

119

return new CsvDataResponse();

120

}

121

return new JsonDataResponse();

122

}

123

124

@Post(value = "/import", consumes = {

125

MediaType.APPLICATION_JSON,

126

MediaType.APPLICATION_XML

127

})

128

public HttpResponse<ImportResult> importData(@Body Object data) {

129

ImportResult result = dataService.importData(data);

130

return HttpResponse.ok(result);

131

}

132

}

133

```

134

135

### Reactive Controllers

136

137

Handle requests reactively using reactive types for non-blocking I/O.

138

139

```java { .api }

140

/**

141

* Reactive endpoints with Single, Maybe, and Flowable

142

*/

143

@Controller("/api/async")

144

public class AsyncController {

145

146

@Get("/user/{id}")

147

public Single<User> getUserAsync(Long id) {

148

return userService.findByIdAsync(id);

149

}

150

151

@Get("/users")

152

public Flowable<User> streamUsers(@QueryValue Optional<String> filter) {

153

return userService.streamAll(filter.orElse(null));

154

}

155

156

@Post("/user")

157

public Single<HttpResponse<User>> createUserAsync(@Body @Valid User user) {

158

return userService.saveAsync(user)

159

.map(HttpResponse::created);

160

}

161

162

@Get(value = "/events", produces = MediaType.TEXT_EVENT_STREAM)

163

public Publisher<Event> streamEvents() {

164

return eventService.streamEvents();

165

}

166

}

167

168

/**

169

* CompletableFuture support

170

*/

171

@Controller("/api/future")

172

public class FutureController {

173

174

@Get("/data/{id}")

175

public CompletableFuture<Data> getDataAsync(Long id) {

176

return dataService.fetchAsync(id);

177

}

178

}

179

```

180

181

### Error Handling

182

183

Handle errors and exceptions with custom error responses.

184

185

```java { .api }

186

/**

187

* Exception handlers

188

*/

189

@Singleton

190

public class GlobalExceptionHandler implements ExceptionHandler<Exception, HttpResponse<?>> {

191

192

@Override

193

public HttpResponse<?> handle(HttpRequest request, Exception exception) {

194

return HttpResponse.serverError()

195

.body(Map.of("error", exception.getMessage()));

196

}

197

}

198

199

/**

200

* Specific exception handlers

201

*/

202

@Singleton

203

public class ValidationExceptionHandler

204

implements ExceptionHandler<ConstraintViolationException, HttpResponse<?>> {

205

206

@Override

207

public HttpResponse<?> handle(HttpRequest request,

208

ConstraintViolationException exception) {

209

List<String> errors = exception.getConstraintViolations()

210

.stream()

211

.map(ConstraintViolation::getMessage)

212

.collect(Collectors.toList());

213

214

return HttpResponse.badRequest()

215

.body(Map.of("errors", errors));

216

}

217

}

218

219

/**

220

* Controller-level error handling

221

*/

222

@Controller("/api/orders")

223

public class OrderController {

224

225

@Get("/{id}")

226

public Order getOrder(Long id) {

227

return orderService.findById(id);

228

}

229

230

@Error(exception = OrderNotFoundException.class)

231

public HttpResponse<Map<String, String>> handleOrderNotFound(OrderNotFoundException ex) {

232

return HttpResponse.notFound(Map.of("error", ex.getMessage()));

233

}

234

235

@Error(status = HttpStatus.BAD_REQUEST)

236

public HttpResponse<Map<String, String>> handleBadRequest() {

237

return HttpResponse.badRequest(Map.of("error", "Invalid request"));

238

}

239

}

240

```

241

242

### Filters

243

244

Implement request/response filtering for cross-cutting concerns.

245

246

```java { .api }

247

/**

248

* HTTP filters for cross-cutting concerns

249

*/

250

@Filter("/api/**")

251

public class AuthenticationFilter implements HttpServerFilter {

252

253

@Override

254

public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request,

255

ServerFilterChain chain) {

256

String authHeader = request.getHeaders().get("Authorization");

257

if (authHeader == null || !isValidToken(authHeader)) {

258

MutableHttpResponse<?> response = HttpResponse.unauthorized();

259

return Publishers.just(response);

260

}

261

return chain.proceed(request);

262

}

263

264

private boolean isValidToken(String token) {

265

// Token validation logic

266

return true;

267

}

268

}

269

270

/**

271

* CORS filter

272

*/

273

@Filter("/**")

274

public class CorsFilter implements HttpServerFilter {

275

276

@Override

277

public Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request,

278

ServerFilterChain chain) {

279

if (request.getMethod() == HttpMethod.OPTIONS) {

280

MutableHttpResponse<?> response = HttpResponse.ok()

281

.header("Access-Control-Allow-Origin", "*")

282

.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE")

283

.header("Access-Control-Allow-Headers", "Content-Type, Authorization");

284

return Publishers.just(response);

285

}

286

287

return chain.proceed(request)

288

.map(response -> response.header("Access-Control-Allow-Origin", "*"));

289

}

290

}

291

```

292

293

### Server Configuration

294

295

Configure the HTTP server with custom settings and SSL support.

296

297

```java { .api }

298

/**

299

* Server configuration properties

300

*/

301

@ConfigurationProperties("micronaut.server")

302

public class ServerConfiguration {

303

private int port = 8080;

304

private String host = "localhost";

305

private Duration readTimeout = Duration.ofSeconds(30);

306

private Duration writeTimeout = Duration.ofSeconds(30);

307

private int maxRequestSize = 1024 * 1024 * 10; // 10MB

308

309

// getters and setters

310

}

311

312

/**

313

* SSL configuration

314

*/

315

@ConfigurationProperties("micronaut.server.ssl")

316

public class SslConfiguration {

317

private boolean enabled = false;

318

private String keyStore;

319

private String keyStorePassword;

320

private String keyStoreType = "JKS";

321

private String trustStore;

322

private String trustStorePassword;

323

324

// getters and setters

325

}

326

327

/**

328

* Custom server configuration

329

*/

330

@Factory

331

public class ServerFactory {

332

333

@Bean

334

@Replaces(NettyHttpServerConfiguration.class)

335

public NettyHttpServerConfiguration customServerConfig() {

336

return new NettyHttpServerConfiguration() {

337

@Override

338

public int getMaxHeaderSize() {

339

return 16384; // 16KB headers

340

}

341

};

342

}

343

}

344

```

345

346

## Types

347

348

```java { .api }

349

// Core HTTP types

350

public interface HttpRequest<B> extends HttpMessage<B> {

351

HttpMethod getMethod();

352

URI getUri();

353

String getPath();

354

HttpParameters getParameters();

355

Map<String, Object> getAttributes();

356

Optional<B> getBody();

357

<T> Optional<T> getBody(Class<T> type);

358

}

359

360

public interface HttpResponse<B> extends HttpMessage<B> {

361

HttpStatus getStatus();

362

int code();

363

String reason();

364

static <T> MutableHttpResponse<T> ok();

365

static <T> MutableHttpResponse<T> created(T body);

366

static <T> MutableHttpResponse<T> badRequest();

367

static <T> MutableHttpResponse<T> notFound();

368

}

369

370

public interface MutableHttpResponse<B> extends HttpResponse<B>, MutableHttpMessage<B> {

371

MutableHttpResponse<B> status(HttpStatus status);

372

MutableHttpResponse<B> header(CharSequence name, CharSequence value);

373

MutableHttpResponse<B> body(B body);

374

}

375

376

// Filter interfaces

377

public interface HttpServerFilter extends ServerFilter {

378

Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request,

379

ServerFilterChain chain);

380

}

381

382

public interface ServerFilterChain {

383

Publisher<MutableHttpResponse<?>> proceed(HttpRequest<?> request);

384

}

385

386

// Exception handling

387

public interface ExceptionHandler<T extends Throwable, R> {

388

R handle(HttpRequest request, T exception);

389

}

390

391

// Route matching

392

public interface Router {

393

<T, R> Stream<UriRouteMatch<T, R>> find(HttpMethod httpMethod,

394

CharSequence uri,

395

HttpRequest<?> context);

396

<T, R> Optional<UriRouteMatch<T, R>> route(HttpMethod httpMethod,

397

CharSequence uri);

398

}

399

400

public interface RouteMatch<R> {

401

R execute(Map<String, Object> argumentValues);

402

Collection<Argument> getRequiredArguments();

403

boolean isExecutable();

404

}

405

406

// File upload

407

public interface CompletedFileUpload extends FileUpload {

408

byte[] getBytes();

409

InputStream getInputStream();

410

void moveTo(File destinationFile);

411

Optional<MediaType> getContentType();

412

}

413

```