dart_cloud_function
Minimal foundation for serverless HTTP functions in Dart. Extend CloudDartFunction, implement handle(), and deploy.
Note: This package is still in development and subject to change. Not Fully opensource we will make opensource when our early access platform become available
Install
dependencies:
dart_cloud_function: ^0.1.0
import 'package:dart_cloud_function/dart_cloud_function.dart';
Quick Start
import 'package:dart_cloud_function/dart_cloud_function.dart';
@cloudFunction
class EchoFunction extends CloudDartFunction {
@override
Future<CloudResponse> handle({
required CloudRequest request,
Map<String, String>? env,
}) async {
return CloudResponse.json({
'method': request.method,
'path': request.path,
'query': request.query,
'body': request.body,
});
}
}
Required Structure
When deploying with dart_cloud_cli, your function must follow these rules:
✓ Exactly One CloudDartFunction Class
Your main.dart must contain exactly one class extending CloudDartFunction.
✓ @cloudFunction Annotation
The class must be annotated with @cloudFunction.
✓ No main() Function
Do not include a main() function. The platform handles invocation.
Example - Valid ✅
@cloudFunction
class MyFunction extends CloudDartFunction {
@override
Future<CloudResponse> handle({
required CloudRequest request,
Map<String, String>? env,
}) async {
return CloudResponse.json({'message': 'Hello'});
}
}
Example - Invalid ❌
// Missing @cloudFunction annotation
class MyFunction extends CloudDartFunction { ... }
// Multiple classes not allowed
@cloudFunction
class Function1 extends CloudDartFunction { ... }
@cloudFunction
class Function2 extends CloudDartFunction { ... }
// main() not allowed
void main() { }
API Reference
CloudDartFunction(abstract)Future<CloudResponse> handle({required CloudRequest request, Map<String, String>? env})
CloudRequestString methodString pathMap<String, String> headersMap<String, String> querydynamic body(JSON-decoded object whencontent-type: application/json, otherwiseString)HttpRequest? raw
CloudResponseint statusCodeMap<String, String> headersdynamic body(String,List<int>for binary, or any JSON-encodable object)- Helpers:
CloudResponse.json(Object body, {int statusCode, Map<String,String>? headers}),CloudResponse.text(String body, {int statusCode, Map<String,String>? headers}) void writeTo(HttpResponse res)to flush the response on adart:ioserver.
Request Body Parsing
CloudRequestis framework-agnostic; construct it from your platform’s incoming request.- Recommended mapping with
dart:io:Future<CloudRequest> toCloudRequest(HttpRequest req) async { dynamic body; if (req.method != 'GET' && req.method != 'HEAD') { final bytes = await req.fold<List<int>>(<int>[], (p, e) { p.addAll(e); return p; }); final mime = req.headers.contentType?.mimeType ?? ''; if (mime == 'application/json') { body = jsonDecode(utf8.decode(bytes)); } else { body = utf8.decode(bytes); } } return CloudRequest( method: req.method, path: req.uri.path, headers: { for (final e in req.headers.entries) e.key: e.value.join(',') }, query: req.uri.queryParameters, body: body, raw: req, ); }
Error Handling
- Handle errors inside
handleand return aCloudResponsewith the appropriate status and body. - Example:
try { // business logic return CloudResponse.json({'ok': true}); } catch (e) { return CloudResponse.json({'error': e.toString()}, statusCode: 500); }
Advanced Usage
- Custom status and headers:
return CloudResponse(statusCode: 201, headers: {'cache-control': 'no-store'}, body: {'created': true}); - Binary responses (e.g., images):
return CloudResponse(statusCode: 200, headers: {'content-type': 'image/png'}, body: pngBytes); - Basic routing inside
handle:switch (request.path) { case '/health': return CloudResponse.text('ok'); case '/users': return CloudResponse.json({'users': []}); default: return CloudResponse.text('not found', statusCode: 404); }
Testing
- Unit test your function classes by directly invoking
handle:class TestFn extends CloudDartFunction { @override Future<CloudResponse> handle(CloudRequest request) async => CloudResponse.text('ok'); } final res = await TestFn().handle(CloudRequest(method: 'GET', path: '/', headers: {}, query: {})); - See
test/dart_cloud_function_test.dartfor an example.
Source Layout
- Public API:
lib/dart_cloud_function.dart - Core implementation:
lib/src/dart_cloud_function_base.dart - Example app:
example/dart_cloud_function_example.dart