Lambda SmalltalkはどこでもOK:CLI、サーバーレス、nginx背後のFastCGI。


REST API(ルーター)

Sinatra風のルーティングDSLでAPIを構築:

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.

ルートパラメータ(:id)は自動的に抽出され、ハンドラに渡される。


Google Cloud Run / Knative

Cloud Runは環境変数PORTで指定されたポートでHTTPサーバーを待機。

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"]

バイナリは完全に自己完結 - 外部ライブラリファイル不要。


AWS Lambda(API Gateway)

API Gatewayと連携してサーバーレスHTTPエンドポイントを構築。

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アダプタがWebAppをAPI Gatewayイベント用にラップ"
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"]

バイナリは完全に自己完結 - 外部ライブラリファイル不要。


FastCGI(nginx)

FastCGIプロトコルでnginxの背後で実行。

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アダプタ"
FastCGI run: app port: 9000.

nginx.conf:

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

実行:

lambda-st run handler.st
# ポート9000でサーバー待機

CLIスクリプト(標準入出力)

OpenFaaSやシンプルなCLIツール向けに、標準入出力を直接使用:

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リファレンス

WebApp(ルーター)

メソッド説明
WebApp new新しいアプリインスタンスを作成
app get: path do: blockGETリクエストを処理
app post: path do: blockPOSTリクエストを処理
app put: path do: blockPUTリクエストを処理
app delete: path do: blockDELETEリクエストを処理
app patch: path do: blockPATCHリクエストを処理
app use: middlewareBlockミドルウェアを追加
app listen: portHTTPサーバーを起動

ルートパターン: /users/:idid パラメータをキャプチャ。

HttpResponse

メソッド説明
HttpResponse ok: body200 OK(テキストボディ)
HttpResponse json: object200 OK(JSONボディ)
HttpResponse notFound404 Not Found
HttpResponse badRequest: msg400 Bad Request
HttpResponse redirect: url302 リダイレクト

HttpRequest

メソッド説明
req methodGET, POST など
req pathURLパス
req headersヘッダーのDict
req queryParamsクエリパラメータのDict
req body生のボディ文字列
req jsonBodyボディをJSONとしてパース