Amplify HostingでHonoを動かす

## はじめに

AWS Amplifyはフロントエンドアプリケーションの自動ビルド・デプロイや（Hosting）、Auth・Databaseといったバックエンドをさっくり定義するなどの機能を提供する、アプリケーション開発のためのサービスです。

## Amplify HostingでHono？？？

フロントエンドアプリケーションのホスティング環境でHono？なにいってだこいつ　という感じですけれども

安心してください、HostingでExpressを動かすサンプルがオフィシャルで紹介されています。

https://docs.aws.amazon.com/amplify/latest/userguide/deploy-express-server.html

これを参考にすればHonoを動かすこともできるでしょう

## HostingでHonoを動かす設定

https://github.com/Kanahiro/hono-amplify

### デプロイマニフェスト

Amplifyは`deploy-manefiest.json`を読んで、そのアプリケーションをどのように動かすべきかを解釈します。

- 本質部分は`computeResource`の部分です（それ以外の部分はちゃんと理解していない）
- `entrypoint`のJavaScriptファイルを実行してサーバーが起動します
    - この記述だと`compute/default/index.cjs`を参照していることになります
- 今回はNode.js v22を利用することにします

```json:.amplify-hosting/deploy-manifest.json
{
	"version": 1,
	"framework": { "name": "hono", "version": "4.7.2" },
	"imageSettings": {
		"sizes": [100, 200, 1920],
		"domains": [],
		"remotePatterns": [],
		"formats": [],
		"minimumCacheTTL": 60,
		"dangerouslyAllowSVG": false
	},
	"routes": [
		{
			"path": "/_amplify/image",
			"target": {
				"kind": "ImageOptimization",
				"cacheControl": "public, max-age=3600, immutable"
			}
		},
		{
			"path": "/*",
			"target": {
				"kind": "Compute",
				"src": "default"
			}
		}
	],
	"computeResources": [
		{
			"name": "default",
			"runtime": "nodejs22.x",
			"entrypoint": "index.cjs"
		}
	]
}
```

`amplify.yml`はあまり難しいことはありません。

```yml:amplify.yml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - nvm install 22
        - nvm use 22
        - npm install -g pnpm
        - pnpm install
    build:
      commands:
        - pnpm build
  artifacts:
    baseDirectory: .amplify-hosting
    files:
      - '**/*'
```

### Honoアプリケーションの実装

ほとんどデフォルトです。AmplifyはNode.jsで動作するため、`@hono/node-server`を用います。

```typescript:src/index.ts
import { serve } from '@hono/node-server';
import { Hono } from 'hono';

const app = new Hono();

app.get('/', (c) => {
	return c.text('Hello Hono!');
});

app.get('/random', (c) => {
	return c.json({ random: Math.random() });
});

let count = 0;
app.get('/count', (c) => {
	return c.json({ count: count++ });
});

serve(
	{
		fetch: app.fetch,
		port: 3000,
	},
	(info) => {
		console.log(`Server is running on http://localhost:${info.port}`);
	},
);
```

デプロイマニフェストで定義したように、`compute/default/index.cjs`にビルドするよう、`build`コマンドを定義します。`esbuild`を用いることにして、以下のようなコマンドになります。

```json:package.json
	"scripts": {
		"dev": "tsx watch src/index.ts",
		"build": "npx esbuild --bundle src/index.ts --minify --outfile=.amplify-hosting/compute/default/index.cjs --platform=node"
	},
```

## デプロイする

最後に、ここまで実装したプロジェクトをリポジトリにアップロードし、Amplifyから接続してデプロイすれば作業完了です。

![Screenshot 2025-02-26 at 9.40.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73197/d2a05a8d-2738-490b-9812-cf17a889efd8.png)

デプロイされたHonoが動作していることが確認できます。

```sh
curl https://main.<yourappid>.amplifyapp.com
Hello Hono!

curl https://main.<yourappid>.amplifyapp.com/count
{"count":0}
curl https://main.<yourappid>.amplifyapp.com/count
{"count":1}
curl https://main.<yourappid>.amplifyapp.com/count
{"count":2}

curl https://main.<yourappid>.amplifyapp.com/random
{"random":0.5949268287931027}
curl https://main.<yourappid>.amplifyapp.com/random
{"random":0.8967498250872903}
```

もちろん揮発性のインスタンスで動いているのでステートレスな実装である必要があります。コールドスタートは体感で1秒程度でした。

## 所感

先週までだったら単なるお遊びだったかもしれないのですが、実行ロール（Compute Role）の実装により、状況が大きく変わっていると考えています。AWSリソースを安全に利用できるようになった現在、AmplifyでWebAPIを実装することが現実的になっているのでは、と

https://qiita.com/Kanahiro/items/8d46a498e3b370b3652c

Amplify Hostingを「フロントエンドアプリケーションのホスティング環境」ととらえるともったいなくて、「自動デプロイ・ブランチングできるNode.js環境」と考えると、色々と楽しいことができる気がしてきますね。してきますよね？？

もはやAmplify HostingではなくAmplify Computingなのではないか？その謎を解明すべく我々はアマゾンの奥地へと向かった　AWSだけに　完