Skip to content

Refactoring #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ doc/api/
# Further artifacts
*.exe
*.zip
bootstrap
bootstrap

.idea
File renamed without changes.
11 changes: 5 additions & 6 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ import 'package:aws_lambda_dart_runtime/aws_lambda_dart_runtime.dart';

void main() async {
/// This demo's handling an API Gateway request.
final Handler<AwsApiGatewayEvent> helloApiGateway = (context, event) async {
final response = {"message": "hello ${context.requestId}"};
final helloApiGateway = (context, event) async {
final response = {'message': 'hello ${context.requestId}'};

/// it returns an encoded response to the gateway
return InvocationResult(
context.requestId, AwsApiGatewayResponse.fromJson(response));
/// it returns an response to the gateway
return AwsApiGatewayResponse.fromJson(response);
};

/// The Runtime is a singleton. You can define the handlers as you wish.
Runtime()
..registerHandler<AwsApiGatewayEvent>("hello.apigateway", helloApiGateway)
..registerHandler<AwsApiGatewayEvent>('hello.apigateway', helloApiGateway)
..invoke();
}
92 changes: 42 additions & 50 deletions lib/client/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import 'dart:io';
import 'dart:async';
import 'dart:convert';

import 'package:meta/meta.dart';
import 'package:http/http.dart' as http;

/// Next invocation data wraps the data from the
/// invocation endpoint of the Lambda Runtime Interface.
class NextInvocation {
Expand Down Expand Up @@ -35,28 +38,26 @@ class NextInvocation {
final String cognitoIdentity;

/// Digesting a [HttpClientResponse] into a [NextInvocation].
static Future<NextInvocation> fromResponse(
HttpClientResponse response) async {
return NextInvocation(
response: json
.decode((await response.transform(Utf8Decoder()).toList()).first),
requestId: response.headers.value(runtimeRequestId),
deadlineMs: response.headers.value(runtimeDeadlineMs),
invokedFunctionArn: response.headers.value(runtimeInvokedFunctionArn),
traceId: response.headers.value(runtimeTraceId),
clientContext: response.headers.value(runtimeClientContext),
cognitoIdentity: response.headers.value(runtimeCognitoIdentity));
}

const NextInvocation(
{this.requestId,
this.deadlineMs,
this.traceId,
this.clientContext,
this.cognitoIdentity,
this.invokedFunctionArn,
this.response})
: assert(requestId != null);
static Future<NextInvocation> fromResponse(http.Response response) async =>
NextInvocation(
response: (json.decode(utf8.decode(response.bodyBytes)) as Map)
.cast<String, dynamic>(),
requestId: response.headers[runtimeRequestId],
deadlineMs: response.headers[runtimeDeadlineMs],
invokedFunctionArn: response.headers[runtimeInvokedFunctionArn],
traceId: response.headers[runtimeTraceId],
clientContext: response.headers[runtimeClientContext],
cognitoIdentity: response.headers[runtimeCognitoIdentity]);

const NextInvocation({
@required this.requestId,
this.deadlineMs,
this.traceId,
this.clientContext,
this.cognitoIdentity,
this.invokedFunctionArn,
this.response,
}) : assert(requestId != null);
}

/// Invocation result is the result that the invoked handler
Expand Down Expand Up @@ -92,8 +93,7 @@ class InvocationError {
/// representation for the Runtime Interface.
Map<String, dynamic> toJson() => {
'errorMessage': error.toString(),
'errorType': "InvocationError",
'stackTrace': this.stackTrace.toString()
'errorType': 'InvocationError',
};

const InvocationError(this.error, this.stackTrace);
Expand All @@ -103,7 +103,7 @@ class InvocationError {
/// It is implemented as a singleton whereby [Client.instance]
/// always returns the already instantiated client.
class Client {
HttpClient _client;
http.Client _client;

static final Client _singleton = Client._internal();

Expand All @@ -112,53 +112,45 @@ class Client {
}

Client._internal() {
_client = HttpClient();
_client = http.Client();
}

static const runtimeApiVersion = '2018-06-01';
static final runtimeApi = Platform.environment["AWS_LAMBDA_RUNTIME_API"];

/// Get the next inovation from the AWS Lambda Runtime Interface (see https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html).
static String get runtimeApi =>
Platform.environment['AWS_LAMBDA_RUNTIME_API'];

static String get handlerName => Platform.environment['_HANDLER'];

/// Get the next invocation from the AWS Lambda Runtime Interface (see https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html).
Future<NextInvocation> getNextInvocation() async {
final request = await _client.getUrl(Uri.parse(
final response = await _client.get(Uri.parse(
'http://${runtimeApi}/${runtimeApiVersion}/runtime/invocation/next'));
final response = await request.close();
return NextInvocation.fromResponse(response);
}

/// Post the invocation response to the AWS Lambda Runtime Interface.
Future<HttpClientResponse> postInvocationResponse(
InvocationResult result) async {
final request = await _client.postUrl(
Future<http.Response> postInvocationResponse(
String requestId, dynamic payload) async {
return await _client.post(
Uri.parse(
'http://${runtimeApi}/${runtimeApiVersion}/runtime/invocation/${result.requestId}/response',
'http://${runtimeApi}/${runtimeApiVersion}/runtime/invocation/$requestId/response',
),
body: jsonEncode(payload),
);
request.add(
utf8.encode(
json.encode(result.body),
),
);

return await request.close();
}

/// Post an invocation error to the AWS Lambda Runtime Interface.
/// It takes in an [InvocationError] and the [requestId]. The [requestId]
/// is used to map the error to the execution.
Future<HttpClientResponse> postInvocationError(
Future<http.Response> postInvocationError(
String requestId, InvocationError err) async {
final request = await _client.postUrl(
return await _client.post(
Uri.parse(
'http://${runtimeApi}/${runtimeApiVersion}/runtime/invocation/$requestId/error',
),
body: jsonEncode(err),
headers: {'Content-type': 'application/json'},
);
request.add(
utf8.encode(
json.encode(err)
)
);

return await request.close();
}
}
33 changes: 20 additions & 13 deletions lib/events/alb_event.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import 'dart:io';

import 'package:aws_lambda_dart_runtime/runtime/event.dart';
import 'package:json_annotation/json_annotation.dart';

part 'alb_event.g.dart';

/// Event send by an Application Load Balancer to the
/// invocation to the Lambda.
@JsonSerializable()
class AwsALBEvent {
class AwsALBEvent extends Event {
/// Request context in which this request is executed.
/// For the ELB this is the ARN of the target group.
@JsonKey()
Expand Down Expand Up @@ -43,14 +44,15 @@ class AwsALBEvent {

Map<String, dynamic> toJson() => _$AwsALBEventToJson(this);

const AwsALBEvent(
{this.context,
this.httpMethod,
this.path,
this.headers,
this.queryStringParameters,
this.body,
this.isBase64Encoded});
const AwsALBEvent({
this.context,
this.httpMethod,
this.path,
this.headers,
this.queryStringParameters,
this.body,
this.isBase64Encoded,
});
}

/// Response for a request from an Application Load Balancer.
Expand Down Expand Up @@ -100,13 +102,18 @@ class AwsALBResponse {

/// The Response that should be returned to the Application Load Balancer.
/// It is constructed with some default values for the optional parameters.
AwsALBResponse(
{body, headers, isBase64Encoded, statusCode, statusDescription}) {
AwsALBResponse({
String body,
Map<String, String> headers,
bool isBase64Encoded,
int statusCode,
String statusDescription,
}) {
this.body = body ?? '';
this.isBase64Encoded = isBase64Encoded ?? false;
this.headers = headers ?? {"Content-Type": "text/html; charset=utf-8"};
this.headers = headers ?? {'Content-Type': 'text/html; charset=utf-8'};
this.statusCode = statusCode ?? HttpStatus.ok;
this.statusDescription = statusDescription ?? "200 OK";
this.statusDescription = statusDescription ?? '200 OK';
}
}

Expand Down
3 changes: 2 additions & 1 deletion lib/events/alexa_event.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:aws_lambda_dart_runtime/runtime/event.dart';
import 'package:json_annotation/json_annotation.dart';

part 'alexa_event.g.dart';
Expand Down Expand Up @@ -28,7 +29,7 @@ class AwsAlexaEventHeader {
/// Event send by an Application Load Balancer to the
/// invocation to the Lambda.
@JsonSerializable()
class AwsAlexaEvent {
class AwsAlexaEvent extends Event {
/// Meta information about the event.
@JsonKey()
final AwsAlexaEventHeader header;
Expand Down
Loading