building services on lambda should be easy and fun.
a project scaffold for a backend service on aws with an infrastructure set ready-to-deploy with libaws.
the project scaffold makes it easy to:
authenticate callers.
implement fast synchronous apis that return all results immediately.
implement slow asynchronous apis with streaming logs, exit code, and 15 minutes max duration.
use the cli admin interface, executing locally or on lambda.
use the api interface, calling efficiently from other backend services.
synchronous apis are normal http on lambda.
asynchronous apis are a http post that triggers an async lambda which invokes a command via rpc or subprocess and stores the results in s3.
each invocation creates 3 objects in s3:
objects are stored in either:
to follow invocation status, the caller:
there are three ways to invoke an asynchronous api:
add to api/.
duplicate the httpExecGet or httpExecPost handler and modify it to introduce new functionality.
add to cmd/.
duplicate the listdir command and modify it to introduce new functionality.
use the included Dockerfile or install the following dependencies:
aws route53 has the domain or its parent from env.sh
aws acm has a wildcard cert for the domain or its parent from env.sh
go install github.com/nathants/libaws@latest
export PATH=$PATH:$(go env GOPATH)/bin
cp env.sh.template env.sh # update values
bash bin/check.sh # lint
bash bin/preview.sh # preview changes to aws infra
bash bin/ensure.sh # ensure aws infra
bash bin/dev.sh # iterate on backend and frontend
bash bin/logs.sh # tail the logs
bash bin/delete.sh # delete aws infra
bash bin/cli.sh -h # interact with the service via the cli
# bash bin/dev.sh # this needs upload bandwidth
bash bin/dev_frontend.sh # iterate on localhost frontend
bash bin/relay.sh # iterate on backend via ec2 relay
cp env.sh.template env.sh # update values
docker build -t aws-exec:latest .
docker run -it --rm \
-v $(pwd):/code \
-e AWS_DEFAULT_REGION \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
aws-exec:latest \
bash -c '
cd /code
bash bin/ensure.sh
'
bash bin/cli.sh auth-new test-user
go install github.com/nathants/aws-exec@latest
export PATH=$PATH:$(go env GOPATH)/bin
export AUTH=$AUTH
export PROJECT_DOMAIN=$DOMAIN
aws-exec exec -- whoami
go get github.com/nathants/aws-exec@latest
package cmd
import (
"context"
"encoding/json"
"fmt"
"os"
awsexec "github.com/nathants/aws-exec/exec"
)
func main() {
val, err := json.Marshal(map[string]interface{}{
"path": ".",
})
if err != nil {
panic(err)
}
exitCode, err := awsexec.Exec(context.Background(), &awsexec.Args{
Url: "https://%s" + os.Getenv("PROJECT_DOMAIN"),
Auth: os.Getenv("AUTH"),
RpcName: "listdir",
RpcArgs: string(val),
LogDataCallback: func(logs string) {
fmt.Print(logs)
},
})
if err != nil {
panic(err)
}
os.Exit(exitCode)
}