Next.js(Amplify) + Laravel(ECS)でJamstackなアプリを動かす

# Objective
- Next.js(Amplify) + Laravel(ECS)でAPI通信できる環境を構築する
	- Route 53でドメイン取得する
	- ACMで証明書取得する
	- ECSをALBで動かす 

# Precondition
以下の記事でNext.js、Laravelアプリをデプロイ済みであること
- Next.js: https://zenn.dev/hutonman/articles/d7106f3a1f773e
- Laravel: https://zenn.dev/hutonman/articles/0c488c3f87ffcd

# Route 53
Route 53 > Registered domains > Register domainsからドメインを取得する
今回は例として`deploy-test.com`とする

# Certificate Manager
SSL化のために証明書を取得する
Certificate Manager > Certificates > Requestからリクエストを発行する
![](https://storage.googleapis.com/zenn-user-upload/7510c66d3c15-20230819.png)
## Domain names
対象のドメイン名を設定する
今回はアプリ側を`app.deploy-test.com`, API側を`api.deploy-test.com`のようにしたいので、`*.deploy-test.com`としてサブドメインを設定する
![](https://storage.googleapis.com/zenn-user-upload/e2b26e876726-20230819.png)

## After Certificate
証明書の詳細画面に遷移し、Create records in Route 53からレコードを作成する
![](https://storage.googleapis.com/zenn-user-upload/a6c1f25d7229-20230819.png)

# Setting Amplify
Amplify > deploy-front(作成した名前) > Domain management > Add domainからドメインを追加する
アプリ側は`app.deploy-test.com`に設定する
![](https://storage.googleapis.com/zenn-user-upload/ab208995b440-20230819.png)
これでAmplifyの画面でもURLが変更され、指定したURLでアクセスが可能になる
![](https://storage.googleapis.com/zenn-user-upload/bc9db746adfc-20230819.png)

# Setting ECS
ECS側ではLoad Balancerに習得したURLを指定する
## Create LoadBalancer
EC2 > LoadBalancers > Create load balancerからロードバランサーを作成する
### Load balancer types
Application Load Balancer(ALB) を選択
![](https://storage.googleapis.com/zenn-user-upload/c0b9d31c7f54-20230819.png)
VPC, Security groups, Target groupを設定して作成
作成後にAdd Listenerからリスナーを追加
#### Listener details
HTTPS 443を設定
![](https://storage.googleapis.com/zenn-user-upload/0aa59fd4b6d6-20230819.png)

#### Secure listener settings
作成したACMを設定
![](https://storage.googleapis.com/zenn-user-upload/852d73848803-20230819.png)

## Route 53
Route 53 > Hosted zones > deploy-test.com > Create recordからALBへのルーティングを設定する
`api.deploy-test.com`に設定し、AliasをONにして作成したロードバランサーを設定する
![](https://storage.googleapis.com/zenn-user-upload/2223ddd6935c-20230819.png)

以上でロードバランサーの設定はOKなので、ECSにロードバランサーを設定をする

## ECS
起動中のサービスがある場合は停止して、新たにサービスを立ち上げ直す
preconditionの参考記事にある設定 + Load balancingの設定で作成したロードバランサーを設定する
![](https://storage.googleapis.com/zenn-user-upload/cc87bfa1d118-20230819.png)

サービス起動後に`api.deploy-test.com`にアクセスして画面が表示されればOK

# Check API
API動作の確認に適当なものを実装してみる
## Create API
laravel側で`api.php`, `APIController`で以下を実装
```php
// api.php
use App\Http\Controllers\APIController;

Route::get('/test', [APIController::class, 'testResponse']);
```

```php
// APIController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class APIController extends Controller
{
    public function testResponse()
    {
        return response()->json(['success api response']);
    }
}
```

## Call API 
Next.js側で作成したAPIを`pages/index.tsx`から呼び出し(`npm install axios`必要)

```tsx
... 
import axios from 'axios'
import { useEffect, useState } from 'react'
...
export default function Home() {
  const [response, setResponse] = useState(null);
  useEffect(() => {
    axios.get('https://api.deploy-test.com/api/test')
      .then((res: any) => {
        setResponse(res.data);
      });
  }, []);

  return (
...
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org">Next.js!</a>
        </h1>

        <p>response = {response}</p>

        <p className={styles.description}>
          Get started by editing{' '}
          <code className={styles.code}>pages/index.tsx</code>
        </p>
...
```

`app.deploy-test.com`にアクセスして以下のようにレスポンスが表示されればOK
![](https://storage.googleapis.com/zenn-user-upload/f663c96574ce-20230819.png)