universal-lambda-zig/README.md
Emil Lerch e5a1099f74
All checks were successful
AWS-Zig Build / build-zig-0.11.0-amd64-host (push) Successful in 1m28s
update build options module name and readme
2023-10-28 15:51:41 -07:00

154 lines
5.4 KiB
Markdown

"Univeral Lambda" for Zig
=========================
This a Zig 0.11 project intended to be used as a package to turn a zig program
into a function that can be run as:
* A command line executable
* A standalone web server
* An AWS Lambda function
* A shared library in [flexilib](https://git.lerch.org/lobo/FlexiLib)
* Cloudflare
* etc
Usage - Development
-------------------
From an empty directory, with Zig 0.11 installed:
`zig init-exe`
Create a `build.zig.zon` with the following contents:
```
.{
.name = "univeral-zig-example",
.version = "0.0.1",
.dependencies = .{
.universal_lambda_build = .{
.url = "https://git.lerch.org/lobo/universal-lambda-zig/archive/07366606696081f324591b66ab7a9a176a38424c.tar.gz",
.hash = "122049daa19f61d778a79ffb82c64775ca5132ee5c4797d7f7d76667ab82593917cd",
},
.flexilib = .{
.url = "https://git.lerch.org/lobo/flexilib/archive/c44ad2ba84df735421bef23a2ad612968fb50f06.tar.gz",
.hash = "122051fdfeefdd75653d3dd678c8aa297150c2893f5fad0728e0d953481383690dbc",
},
},
}
```
Due to limitations in the build apis related to relative file paths, the
dependency name currently must be "universal_lambda_build". Also, note that
the flexilib dependency is required at all times. This requirement may go away
with zig 0.12 (see [#17135](https://github.com/ziglang/zig/issues/17135))
and/or changes to this library.
**Build.zig:**
* Add an import at the top:
```zig
const universal_lambda = @import("universal_lambda_build");
```
* Set the return of the build function to return `!void` rather than `void`
* Add a line to the build script, after any modules are used, but otherwise just
after adding the exe is fine:
```zig
try universal_lambda.configureBuild(b, exe);
```
This will provide most of the magic functionality of the package, including
several new build steps to manage the system, and a new import to be used. For
testing, it is also advisable to add the modules to your tests by adding a line
like so:
```zig
_ = try universal_lambda.addModules(b, main_tests);
```
**main.zig**
The build changes above will add several modules:
* universal_lambda_handler: Main import, used to register your handler
* universal_lambda_interface: Contains the context type used in the handler function
* flexilib-interface: Used as a dependency of the handler. Not normally needed
Add imports for the handler registration and interface:
```zig
const universal_lambda = @import("universal_lambda_handler");
const universal_lambda_interface = @import("universal_lambda_interface");
```
Another module `universal_lambda_build_options` is available if access to the
environment is needed. The build type is stored under a `build_type` variable.
Add a handler to be executed. The handler must follow this signature:
```zig
pub fn handler(allocator: std.mem.Allocator, event_data: []const u8, context: universal_lambda_interface.Context) ![]const u8
```
Your main function should return `!u8`. Let the package know about your handler in your main function, like so:
```zig
return try universal_lambda.run(null, handler);
```
The first parameter above is an allocator. If you have a specific handler you
would like to use, you may specify it. Otherwise, an appropriate allocator
will be created and used. Currently this is an ArenaAllocator wrapped around
an appropriate base allocator, so your handler does not require deallocation.
A fully working example of usage is at https://git.lerch.org/lobo/universal-lambda-example/.
Usage - Building
----------------
The build configuration will add the following build steps when building with
Linux:
```
awslambda_package Package the function
awslambda_deploy Deploy the function
awslambda_iam Create/Get IAM role for function
awslambda_run Run the app in AWS lambda
cloudflare Deploy as Cloudflare worker (must be compiled with -Dtarget=wasm32-wasi)
flexilib Create a flexilib dynamic library
standalone_server Run the function in its own web server
```
AWS Lambda is not currently available if building with other operating systems,
as that set of build steps utilize system commands using the AWS CLI. This is
likely to change in the future to enable other operating systems. All other
build steps are available for all targets.
Note that AWS Lambda will require that credentials are established using the
same methods as checked by the AWS CLI and the AWS CLI is installed.
If using Cloudflare deployment, either CLOUDFLARE_API_TOKEN or
CLOUDFLARE_EMAIL/CLOUDFLARE_API_KEY environment variables must be set for
successful deployment.
To run as an executable, a simple `zig build` will build, or `zig build run`
will run as expected. `zig build standalone_server run` will also build/run
as a standalone web server.
Limitations
-----------
Limitations include standalone web server port customization and linux/aws cli requirements for Linux.
Also, within the context, AWS Lambda is unable to provide proper method, target,
and headers for the request. This may be important for routing purposes. Suggestion
here is to use API Gateway and pass these parameters through the event_data content.
Lastly, support for specifying multiple targets in the downstream (your) application
is somewhat spotty. For example, `zig build standalone_server run` works fine.
However, `zig build test flexilib` is broken.