Open9

AWSでNext.jsプロジェクトを始める

296u296u

Amplify CLIをインストールする。公式だとglobalにインストールするように言われるが、nodenvを使っているせいかうまくPATHが通ってくれてないので、ローカルにインストールする
$ npm install -g @aws-amplify/cli
以下のコマンドで初期設定を開始
$ amplify configure
ブラウザが立ち上がってユーザー作成を促されるので、そのままフローに沿って用意。
終わったらアクセスキーとシークレットキーをCLIで入力すると完了する

296u296u

以下のコマンドを叩いてローカルでのバックエンド動作をさせる。
$ amplify pull --appId d2t8qtnkobs4x3 --envName staging

? Choose your default editor: IntelliJ IDEA
✔ Choose the type of app that you're building · javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  app
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start
No AppSync API configured. Please add an API
? Do you plan on modifying this backend? Yes
✔ Successfully pulled backend environment staging from the cloud.

色々聞かれて適当に入れたけどあっているか不安。

認証を追加するために必要なライブラリを入れる。
$ npm install aws-amplify @aws-amplify/ui-react

aws-amplifyはAWSのサービスとインタラクションするためのクライアント側のAPI。
@aws-amplify/ui-reactライブラリにはフレームワーク固有のUIコンポーネントとなる。
多分後者はいづれ不要になる気がする。

認証サービスの作成
$ amplify add auth

その後のオプションはよくわからないので、チュートリアルに沿って設定

 Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Username
 Do you want to configure advanced settings? No, I am done.
✅ Successfully added auth resource caravanaws3dc808c0 locally

認証サービスをデプロイする
$ amplify push --y

296u296u

/app/layout.tsxにコードを追加

import { Amplify } from 'aws-amplify';
import config from './aws-exports';
Amplify.configure(config);

CLIはaws-exports.jsというファイルを作成して継続して更新していく。このファイルを使用してAmplifyプロジェクトで使用できる様々なAWSリソースについてReactプロジェクトに伝える。

認証フローを追加しようとするが、うまいことはいらない。多分チュートリアルがReact寄りになっており、NextJsのAPPRouter周りでうまくいかないんじゃないかなと思う

https://zenn.dev/gentamura/articles/a9834076fcc101

296u296u

こっちの記事を参考に進めていく
https://zenn.dev/gentamura/articles/a9834076fcc101

$ npm install @aws-amplify/adapter-nextjs

そのままAPIを追加

$ amplify add api

? Select from one of the below mentioned services: GraphQL
? Here is the GraphQL API that we will create. Select a setting to edit or continue Continue
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)

⚠️  WARNING: your GraphQL API currently allows public create, read, update, and delete access to all models via an API Key. To configure PRODUCTION-READY authorization rules, review: https://docs.amplify.aws/cli/graphql/authorization-rules

✅ GraphQL schema compiled successfully.

Edit your schema at /Users/fukui_takanori/JetBrains/Webstorm/caravan-aws/amplify/backend/api/caravanaws/schema.graphql or place .graphql files in a directory at /Users/fukui_takanori/JetBrains/Webstorm/caravan-aws/amplify/backend/api/caravanaws/schema
✔ Do you want to edit the schema now? (Y/n) · yes
Edit the file in your editor: /Users/fukui_takanori/JetBrains/Webstorm/caravan-aws/amplify/backend/api/caravanaws/schema.graphql
✅ Successfully added resource caravanaws locally

✅ Some next steps:
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

完了
注意点としてAPIキー(7日間有効)で認証を通しているので、今のままでは誰でもDBへのCRUDが可能

このままだとJSなので、TSに変更する
$ amplify configure codegen

? Choose the code generation language target typescript
? Enter the file name pattern of graphql queries, mutations and subscriptions app/graphql/**/*.ts
? Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions Yes
? Enter maximum statement depth [increase from default if your schema is deeply nested] 2
? Enter the file name for the generated code app/API.ts
? Do you want to generate code for your newly created GraphQL API Yes
✔ Generated GraphQL operations successfully and saved at app/graphql
✔ Code generated successfully and saved in file app/API.ts

ここまでをpushしておく

$ amplify push

296u296u

今のままだとどのユーザーが登録してもすべてのユーザーで登録データをCRUDできてしまう。
そのため、Amazon Cognito User Poolを利用して、ログインユーザーごとで認可をするように変更する。

/amplify/backend/api/caravanaws/schema.graphql@authディレクティブを追加する。

type Todo @model @auth(rules: [{ allow: owner }]) {
  id: ID!
  name: String!
  description: String
}

次に再生成しておく
$ amplify condegen

296u296u

API KeyからAmazon Cognite User Pookに変更する

$ amplify update api

? Select from one of the below mentioned services: GraphQL

General information
- Name: caravanaws
- API endpoint: https://jpgkkoatwvbmpccpab7pbr5oe4.appsync-api.ap-northeast-1.amazonaws.com/graphql

Authorization modes
- Default: API key expiring Thu Apr 25 2024 09:00:00 GMT+0900 (Japan Standard Time): da2-3y7ei6afazbutbk4xz3dsjp2nm

Conflict detection (required for DataStore)
- Disabled

? Select a setting to edit Authorization modes
? Choose the default authorization type for the API Amazon Cognito User Pool
Use a Cognito user pool configured as a part of this project.
? Configure additional auth types? No
⚠️ WARNING: owners may reassign ownership for the following model(s) and role(s): Todo: [owner]. If this is not intentional, you may want to apply field-level authorization rules to these fields. To read more: https://docs.amplify.aws/cli/graphql/authorization-rules/#per-user--owner-based-data-access.
✅ GraphQL schema compiled successfully.

Edit your schema at /Users/fukui_takanori/JetBrains/Webstorm/caravan-aws/amplify/backend/api/caravanaws/schema.graphql or place .graphql files in a directory at /Users/fukui_takanori/JetBrains/Webstorm/caravan-aws/amplify/backend/api/caravanaws/schema
⚠️ The API_KEY auth type has been removed from the API.
⚠️ If other resources depend on this API, run "amplify update <category>" and reselect this API to remove the dependency on the API key.
⚠️ This must be done before running "amplify push" to prevent a push failure
✅ Successfully updated resource

最後にプッシュしておくこと

$ amplify push

296u296u

Amplify ライブラリの読み込み
React Server Components, Client Componentの両方でAmplifyライブラリを利用するので、それぞれ異なる方法でライブラリを読み込ませる。

src/components/ConfigureAmplifyClientSide.ts

'use client'

import { Amplify } from 'aws-amplify'
import { generateClient } from 'aws-amplify/api'
import config from '@/app/amplifyconfiguration.json'

Amplify.configure(config, { ssr: true })
export const client = generateClient()

export default function ConfigureAmplifyClientSide() {
  return null
}

app/layout.tsx

import ConfigureAmplifyClientSide from '@/components/ConfigureAmplifyClientSide';
import AuthProvider from '@/components/AuthProvider';

export const dynamic = 'force-dynamic';

const RootLayout = async ({ children }: { children: React.ReactNode }) => {
  return (
    <html lang="en">
      <head>
        <link rel="icon" href="/favicon.png" />
      </head>
      <body>
        <ConfigureAmplifyClientSide />
        <AuthProvider>{children}</AuthProvider>
      </body>
    </html>
  );
};

export default RootLayout;

続いてReact Server Component側

ここからはコード記載通りに配置していく。