dart_cloud_function Package#
Minimal foundation for serverless HTTP functions in Dart.
Overview#
dart_cloud_function is a lightweight Dart package that provides:
- Simple abstract base class for cloud functions
- Lightweight request/response models
- Automatic HTTP parsing and handling
- Convenience response helpers
- Support for binary responses
- Zero-cost abstractions
Installation#
Add to your pubspec.yaml:
dependencies:
dart_cloud_function: ^1.0.0
Import the library:
import 'package:dart_cloud_function/dart_cloud_function.dart';
Quick Start#
Create a function by extending CloudDartFunction and implementing handle():
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 base class for cloud functions.
abstract class CloudDartFunction {
Future<CloudResponse> handle({
required CloudRequest request,
Map<String, String>? env,
});
}
CloudRequest#
Incoming HTTP request.
Properties:
String method- HTTP method (GET, POST, etc.)String path- Request pathMap<String, String> headers- HTTP headersMap<String, String> query- Query parametersdynamic body- Request body (auto-parsed JSON or String)HttpRequest? raw- Access to underlying HttpRequest
CloudResponse#
HTTP response to send back.
Properties:
int statusCode- HTTP status code (default: 200)Map<String, String> headers- Response headersdynamic body- Response body (String, List, or JSON-encodable object)
Constructors:
CloudResponse(statusCode, headers, body)- Full controlCloudResponse.json(Object body, {statusCode, headers})- JSON responseCloudResponse.text(String body, {statusCode, headers})- Text response
Methods:
void writeTo(HttpResponse res)- Write response to HttpResponse
Usage Examples#
Error Handling#
@cloudFunction
class SafeFunction extends CloudDartFunction {
@override
Future<CloudResponse> handle({
required CloudRequest request,
Map<String, String>? env,
}) async {
try {
// business logic
return CloudResponse.json({'ok': true});
} catch (e) {
return CloudResponse.json(
{'error': e.toString()},
statusCode: 500,
);
}
}
}
Custom Status & Headers#
return CloudResponse(
statusCode: 201,
headers: {'cache-control': 'no-store'},
body: {'created': true},
);
Binary Responses#
return CloudResponse(
statusCode: 200,
headers: {'content-type': 'image/png'},
body: pngBytes, // List<int>
);
Basic Routing#
switch (request.path) {
case '/health':
return CloudResponse.text('ok');
case '/users':
return CloudResponse.json({'users': []});
default:
return CloudResponse.text('not found', statusCode: 404);
}
Query Parameters#
final name = request.query['name'] ?? 'World';
return CloudResponse.json({'message': 'Hello, $name!'});
Request Body Parsing#
// Automatic JSON parsing
final data = request.body as Map<String, dynamic>;
final id = data['id'] as int;
Deployment Validation#
The dart_cloud_cli analyzer validates:
- ✓ Exactly one
CloudDartFunctionclass - ✓
@cloudFunctionannotation present - ✓ No
main()function - ✓ Security checks (no process execution, FFI, mirrors)
Common Errors:
No CloudDartFunction class found→ Add a class extendingCloudDartFunctionMissing @cloudFunction annotation→ Add@cloudFunctionabove your classmain() function is not allowed→ Remove themain()functionMultiple CloudDartFunction classes found→ Keep only one class
Testing#
test('echo function works', () async {
final fn = EchoFunction();
final res = await fn.handle(
request: CloudRequest(
method: 'GET',
path: '/test',
headers: {},
query: {'name': 'test'},
),
env: {},
);
expect(res.statusCode, 200);
expect(res.body, isNotNull);
});
Best Practices#
- Keep it simple - One function per package
-
Use descriptive names -
UserAuthFunction,DataProcessorFunction - Document your function - Add doc comments
- Handle errors gracefully - Return appropriate HTTP status codes
- Use environment variables - Access secrets via
envparameter - Minimize dependencies - Keep function size under 5 MB
- Test locally - Verify before deployment
Project Structure#
my-function/
├── main.dart # Your @cloudFunction class
├── pubspec.yaml # Dependencies
├── test/
│ └── main_test.dart # Unit tests
└── README.md # Documentation
Deployment#
Deploy your function using dart_cloud_cli:
dart_cloud deploy ./my-function
The CLI will:
- Validate deployment restrictions (size, files, directories)
- Analyze code structure and security
- Create an archive
- Upload to the platform
See Also#
- dart_cloud_cli Documentation - CLI usage guide
- Backend API Reference - API endpoints
- Backend Architecture - System architecture