0
# Function as a Service
1
2
Micronaut provides comprehensive support for serverless functions with integration for AWS Lambda, Google Cloud Functions, Azure Functions, and local function execution.
3
4
## Capabilities
5
6
### Function Beans
7
8
Define functions using the standard Java Function interface.
9
10
```java { .api }
11
/**
12
* Simple function bean
13
*/
14
@FunctionBean("hello")
15
public class HelloFunction implements Function<String, String> {
16
17
@Override
18
public String apply(String input) {
19
return "Hello " + input;
20
}
21
}
22
23
/**
24
* Function with dependency injection
25
*/
26
@FunctionBean("userProcessor")
27
public class UserProcessorFunction implements Function<UserRequest, UserResponse> {
28
29
private final UserService userService;
30
31
public UserProcessorFunction(UserService userService) {
32
this.userService = userService;
33
}
34
35
@Override
36
public UserResponse apply(UserRequest request) {
37
User user = userService.processUser(request);
38
return new UserResponse(user.getId(), user.getName());
39
}
40
}
41
```
42
43
### Reactive Functions
44
45
Create functions that return reactive types for asynchronous processing.
46
47
```java { .api }
48
/**
49
* Reactive function implementations
50
*/
51
@FunctionBean("asyncProcessor")
52
public class AsyncProcessorFunction implements Function<ProcessRequest, Single<ProcessResponse>> {
53
54
private final ProcessingService processingService;
55
56
public AsyncProcessorFunction(ProcessingService processingService) {
57
this.processingService = processingService;
58
}
59
60
@Override
61
public Single<ProcessResponse> apply(ProcessRequest request) {
62
return processingService.processAsync(request)
63
.map(result -> new ProcessResponse(result.getId(), result.getStatus()));
64
}
65
}
66
67
/**
68
* Streaming function
69
*/
70
@FunctionBean("dataStream")
71
public class DataStreamFunction implements Function<Publisher<DataInput>, Publisher<DataOutput>> {
72
73
@Override
74
public Publisher<DataOutput> apply(Publisher<DataInput> input) {
75
return Flowable.fromPublisher(input)
76
.map(this::transform)
77
.filter(Objects::nonNull);
78
}
79
80
private DataOutput transform(DataInput input) {
81
// Transform input to output
82
return new DataOutput(input.getValue().toUpperCase());
83
}
84
}
85
```
86
87
### HTTP Functions
88
89
Create functions that handle HTTP requests and responses.
90
91
```java { .api }
92
/**
93
* HTTP function handling
94
*/
95
@FunctionBean("httpHandler")
96
public class HttpHandlerFunction implements Function<HttpRequest<?>, HttpResponse<?>> {
97
98
@Override
99
public HttpResponse<?> apply(HttpRequest<?> request) {
100
String method = request.getMethod().toString();
101
String path = request.getPath();
102
103
Map<String, Object> response = Map.of(
104
"method", method,
105
"path", path,
106
"timestamp", Instant.now().toString()
107
);
108
109
return HttpResponse.ok(response);
110
}
111
}
112
113
/**
114
* Typed HTTP function
115
*/
116
@FunctionBean("apiEndpoint")
117
public class ApiEndpointFunction implements Function<ApiRequest, Single<ApiResponse>> {
118
119
private final ApiService apiService;
120
121
public ApiEndpointFunction(ApiService apiService) {
122
this.apiService = apiService;
123
}
124
125
@Override
126
public Single<ApiResponse> apply(ApiRequest request) {
127
return apiService.handleRequest(request)
128
.map(result -> new ApiResponse(result, "success"));
129
}
130
}
131
```
132
133
### AWS Lambda Integration
134
135
Deploy functions as AWS Lambda functions with event handling.
136
137
```java { .api }
138
/**
139
* AWS Lambda event handling
140
*/
141
@FunctionBean("s3Handler")
142
public class S3EventHandler implements Function<S3Event, String> {
143
144
private final S3Service s3Service;
145
146
public S3EventHandler(S3Service s3Service) {
147
this.s3Service = s3Service;
148
}
149
150
@Override
151
public String apply(S3Event event) {
152
for (S3EventNotification.S3EventNotificationRecord record : event.getRecords()) {
153
String bucketName = record.getS3().getBucket().getName();
154
String objectKey = record.getS3().getObject().getKey();
155
156
s3Service.processObject(bucketName, objectKey);
157
}
158
159
return "Processed " + event.getRecords().size() + " records";
160
}
161
}
162
163
/**
164
* API Gateway Lambda function
165
*/
166
@FunctionBean("apiGateway")
167
public class ApiGatewayFunction
168
implements Function<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
169
170
@Override
171
public APIGatewayProxyResponseEvent apply(APIGatewayProxyRequestEvent request) {
172
String httpMethod = request.getHttpMethod();
173
String path = request.getPath();
174
String body = request.getBody();
175
176
// Process the request
177
Map<String, Object> responseBody = Map.of(
178
"message", "Request processed",
179
"method", httpMethod,
180
"path", path
181
);
182
183
return APIGatewayProxyResponseEvent.builder()
184
.withStatusCode(200)
185
.withHeaders(Map.of("Content-Type", "application/json"))
186
.withBody(toJson(responseBody))
187
.build();
188
}
189
}
190
```
191
192
### Function Configuration
193
194
Configure function deployment and runtime settings.
195
196
```java { .api }
197
/**
198
* Function configuration
199
*/
200
@ConfigurationProperties("function")
201
public class FunctionConfiguration {
202
203
private String runtime = "java11";
204
private int timeout = 30;
205
private int memorySize = 512;
206
private Map<String, String> environment = new HashMap<>();
207
208
// getters and setters
209
}
210
211
/**
212
* AWS-specific configuration
213
*/
214
@ConfigurationProperties("aws.lambda")
215
public class LambdaConfiguration {
216
private String role;
217
private String functionName;
218
private String handler;
219
private List<String> layers = new ArrayList<>();
220
221
// getters and setters
222
}
223
```
224
225
### Local Function Testing
226
227
Test functions locally during development.
228
229
```java { .api }
230
/**
231
* Local function testing
232
*/
233
@Singleton
234
public class FunctionTestRunner {
235
236
private final ApplicationContext applicationContext;
237
238
public FunctionTestRunner(ApplicationContext applicationContext) {
239
this.applicationContext = applicationContext;
240
}
241
242
public <T, R> R executeFunction(String functionName, T input, Class<R> returnType) {
243
Function<T, R> function = applicationContext.getBean(Function.class,
244
Qualifiers.byName(functionName));
245
return function.apply(input);
246
}
247
248
public <T> void executeVoidFunction(String functionName, T input) {
249
Consumer<T> function = applicationContext.getBean(Consumer.class,
250
Qualifiers.byName(functionName));
251
function.accept(input);
252
}
253
}
254
```
255
256
### Cold Start Optimization
257
258
Optimize functions for minimal cold start times.
259
260
```java { .api }
261
/**
262
* Cold start optimization
263
*/
264
@Introspected
265
@Serdeable
266
public class OptimizedFunction implements Function<OptimizedRequest, OptimizedResponse> {
267
268
// Use @Introspected for compile-time reflection
269
// Use @Serdeable for compile-time serialization
270
271
@Override
272
public OptimizedResponse apply(OptimizedRequest request) {
273
// Function logic optimized for fast startup
274
return new OptimizedResponse(process(request.getData()));
275
}
276
277
private String process(String data) {
278
// Minimal processing to reduce cold start impact
279
return data.toUpperCase();
280
}
281
}
282
```
283
284
## Types
285
286
```java { .api }
287
// Function annotations
288
@Target({ElementType.TYPE})
289
@Retention(RetentionPolicy.RUNTIME)
290
public @interface FunctionBean {
291
String value();
292
}
293
294
// Core function interfaces
295
public interface Function<T, R> {
296
R apply(T t);
297
}
298
299
public interface Consumer<T> {
300
void accept(T t);
301
}
302
303
public interface Supplier<T> {
304
T get();
305
}
306
307
public interface BiFunction<T, U, R> {
308
R apply(T t, U u);
309
}
310
311
// HTTP function types
312
public interface HttpRequest<B> extends HttpMessage<B> {
313
HttpMethod getMethod();
314
URI getUri();
315
String getPath();
316
HttpParameters getParameters();
317
HttpHeaders getHeaders();
318
Optional<B> getBody();
319
}
320
321
public interface HttpResponse<B> extends HttpMessage<B> {
322
HttpStatus getStatus();
323
int code();
324
String reason();
325
HttpHeaders getHeaders();
326
Optional<B> getBody();
327
328
static <T> MutableHttpResponse<T> ok(T body);
329
static <T> MutableHttpResponse<T> created(T body);
330
static MutableHttpResponse<String> badRequest(String error);
331
}
332
333
// AWS Lambda types (when using AWS integration)
334
public class S3Event {
335
public List<S3EventNotificationRecord> getRecords();
336
}
337
338
public class APIGatewayProxyRequestEvent {
339
public String getHttpMethod();
340
public String getPath();
341
public String getBody();
342
public Map<String, String> getHeaders();
343
public Map<String, String> getQueryStringParameters();
344
}
345
346
public class APIGatewayProxyResponseEvent {
347
public static Builder builder();
348
349
public static class Builder {
350
public Builder withStatusCode(int statusCode);
351
public Builder withHeaders(Map<String, String> headers);
352
public Builder withBody(String body);
353
public APIGatewayProxyResponseEvent build();
354
}
355
}
356
357
// Function context for runtime information
358
public interface FunctionContext {
359
String getFunctionName();
360
String getFunctionVersion();
361
int getRemainingTimeInMillis();
362
int getMaxMemoryInMB();
363
String getRequestId();
364
}
365
```