Lambda Smalltalk runs anywhere: CLI, serverless platforms, or FastCGI behind nginx.


REST API with Router

Build APIs with a Sinatra-like routing DSL:

Module import: 'Http'.

| app |
app := WebApp new.

app get: '/' do: [:req :params |
    HttpResponse ok: 'Hello from Lambda Smalltalk!'
].

app get: '/health' do: [:req :params |
    HttpResponse json: #{ 'status' -> 'healthy' }
].

app get: '/users/:id' do: [:req :params |
    | id |
    id := params at: 'id'.
    HttpResponse json: #{ 'id' -> id 'name' -> 'Alice' }
].

app post: '/users' do: [:req :params |
    | body |
    body := req jsonBody.
    HttpResponse json: #{ 'status' -> 'created' 'name' -> (body at: 'name') }
].

app listen: 8080.

Route parameters (:id) are automatically extracted and passed to handlers.


Google Cloud Run / Knative

Cloud Run expects an HTTP server on the PORT environment variable.

server.st:

Module import: 'Http'.

| app port |
app := WebApp new.
port := ((Env at: 'PORT') ifNil: ['8080']) asInteger.

app get: '/' do: [:req :params |
    HttpResponse ok: 'Hello from Lambda Smalltalk!'
].

app get: '/health' do: [:req :params |
    HttpResponse json: #{ 'status' -> 'healthy' }
].

app listen: port.

Dockerfile:

FROM debian:slim
COPY lambda-st /usr/bin/
COPY server.st /app/
WORKDIR /app
CMD ["lambda-st", "run", "server.st"]

The binary is fully self-contained - no external library files needed.


AWS Lambda (API Gateway)

Use Lambda with API Gateway for serverless HTTP endpoints.

handler.st:

Module import: 'Http'.
Module import: 'Lambda'.

| app |
app := WebApp new.

app get: '/' do: [:req :params |
    HttpResponse ok: 'Hello from Lambda!'
].

app get: '/users/:id' do: [:req :params |
    | id |
    id := params at: 'id'.
    HttpResponse json: #{ 'id' -> id }
].

"Lambda adapter wraps WebApp for API Gateway events"
Lambda runHttp: app.

Dockerfile:

FROM amazonlinux:2
COPY lambda-st /usr/bin/
COPY handler.st /var/runtime/
CMD ["lambda-st", "run", "/var/runtime/handler.st"]

The binary is fully self-contained - no external library files needed.


FastCGI (nginx)

Run behind nginx using the FastCGI protocol.

handler.st:

Module import: 'Http'.
Module import: 'FastCGI'.

| app |
app := WebApp new.

app get: '/' do: [:req :params |
    HttpResponse ok: 'Hello from FastCGI!'
].

app get: '/users/:id' do: [:req :params |
    | id |
    id := params at: 'id'.
    HttpResponse json: #{ 'id' -> id }
].

"FastCGI adapter"
FastCGI run: app port: 9000.

nginx.conf:

location /app {
    fastcgi_pass 127.0.0.1:9000;
    include fastcgi_params;
}

Run:

lambda-st run handler.st
# Server listens on port 9000

CLI Scripts (stdin/stdout)

For OpenFaaS or simple CLI tools, use stdin/stdout directly:

handler.st:

| input data name |
input := Stdin readAll.
data := Json parse: input.
name := (data at: 'name') ifNil: ['World'].

(Json generate: #{ 'message' -> ('Hello, ', name, '!') }) printNl.

API Reference

WebApp (Router)

MethodDescription
WebApp newCreate new app instance
app get: path do: blockHandle GET requests
app post: path do: blockHandle POST requests
app put: path do: blockHandle PUT requests
app delete: path do: blockHandle DELETE requests
app patch: path do: blockHandle PATCH requests
app use: middlewareBlockAdd middleware
app listen: portStart HTTP server

Route patterns: /users/:id captures id parameter.

HttpResponse

MethodDescription
HttpResponse ok: body200 OK with text body
HttpResponse json: object200 OK with JSON body
HttpResponse notFound404 Not Found
HttpResponse badRequest: msg400 Bad Request
HttpResponse redirect: url302 Redirect

HttpRequest

MethodDescription
req methodGET, POST, etc.
req pathURL path
req headersDict of headers
req queryParamsDict of query params
req bodyRaw body string
req jsonBodyParse body as JSON