1. 概要
こちらのFlutterで実施した内容をNextJSでも行ってみます。
今回はAWS Amplify(Gen2)を使い、認証(Cognito)を行うのとTodoアプリを実装する内容となります。
対象としては開発を1年程やってて自分で最初から開発してみたい方になります。そのため細かい用語などの説明はしません。
「App router」で作成します。
2. 前提条件
2-1. こちらを参考
- Node.js v14.x or later
- npm v6.14.4 or later
- git v2.14.1 or later
- AWS Account
3. レポジトリの作成
3-1. こちらのテンプレートから作成
※GitHubにログインしておく
4. Amplifyへデプロイ
4-1. こちらのURLから
5. アプリへアクセス
5-1. 上記デプロイされたドメインへアクセス
- https://main.12345678901234.amplifyapp.com/
6. ローカル環境のセットアップ
6-1-1. 「amplify_output.json」をダウンロード
- デプロイ画面の「デプロイされたバックエンドリソース」タブをクリックしてダウンロード
6-1-2. 自分PCにRepositoryをクーロン
git clone https://github.com/myAccount/amplify-next-template.git
6-1-3. ライブラリのインストール
cd amplify-next-template && npm install
6-1-4. ルートディレクトリに「amplify_outputs.json」をコピー
6-1-5. ディレクトリ構成
.
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── amplify
│ ├── auth
│ │ └── resource.ts
│ ├── backend.ts
│ ├── data
│ │ └── resource.ts
│ ├── package.json
│ └── tsconfig.json
├── amplify.yml
├── amplify_outputs.json
├── app
│ ├── app.css
│ ├── favicon.ico
│ ├── globals.css
│ ├── layout.tsx
│ ├── page.module.css
│ └── page.tsx
├── next-env.d.ts
├── next.config.js
├── package-lock.json
├── package.json
└── tsconfig.json
4 directories, 22 files
- 主要なファイル
7. 必要なライブラリをインストール
7-1-1. インストール
npm add @aws-amplify/ui-react
8. ローカルにAWS credentialsをセットアップ
8-1-1. こちらを参考
9. Amplifyのcloud sandboxを立ち上げ
npx ampx sandbox
10. ソースコード
10-1-1. amplify/data/resource.ts
import { type ClientSchema, a, defineData } from "@aws-amplify/backend";
/*== STEP 1 ===============================================================
The section below creates a Todo database table with a "content" field. Try
adding a new "isDone" field as a boolean. The authorization rule below
specifies that any user authenticated via an API key can "create", "read",
"update", and "delete" any "Todo" records.
=========================================================================*/
const schema = a.schema({
Todo: a
.model({
content: a.string(),
isDone: a.boolean(),
})
.authorization((allow) => [allow.owner()]),
});
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({
schema,
authorizationModes: {
defaultAuthorizationMode: "userPool",
apiKeyAuthorizationMode: {
expiresInDays: 30,
},
},
});
/*== STEP 2 ===============================================================
Go to your frontend source code. From your client-side code, generate a
Data client to make CRUDL requests to your table. (THIS SNIPPET WILL ONLY
WORK IN THE FRONTEND CODE FILE.)
Using JavaScript or Next.js React Server Components, Middleware, Server
Actions or Pages Router? Review how to generate Data clients for those use
cases: https://docs.amplify.aws/gen2/build-a-backend/data/connect-to-API/
=========================================================================*/
/*
"use client"
import { generateClient } from "aws-amplify/data";
import type { Schema } from "@/amplify/data/resource";
const client = generateClient<Schema>() // use this Data client for CRUDL requests
*/
/*== STEP 3 ===============================================================
Fetch records from the database and use them in your frontend component.
(THIS SNIPPET WILL ONLY WORK IN THE FRONTEND CODE FILE.)
=========================================================================*/
/* For example, in a React component, you can use this snippet in your
function's RETURN statement */
// const { data: todos } = await client.models.Todo.list()
// return <ul>{todos.map(todo => <li key={todo.id}>{todo.content}</li>)}</ul>
10-1-2. app/page.tsx
"use client";
import { useState, useEffect } from "react";
import { generateClient } from "aws-amplify/data";
import type { Schema } from "@/amplify/data/resource";
import "./../app/app.css";
import { Amplify } from "aws-amplify";
import outputs from "@/amplify_outputs.json";
import "@aws-amplify/ui-react/styles.css";
import { Authenticator } from "@aws-amplify/ui-react";
import "@aws-amplify/ui-react/styles.css";
Amplify.configure(outputs);
const client = generateClient<Schema>();
export default function App() {
const [todos, setTodos] = useState<Array<Schema["Todo"]["type"]>>([]);
function listTodos() {
client.models.Todo.observeQuery().subscribe({
next: (data) => setTodos([...data.items]),
});
}
useEffect(() => {
listTodos();
}, []);
function createTodo() {
client.models.Todo.create({
content: window.prompt("Todo content"),
isDone: false,
});
}
function deleteTodo(id: string) {
client.models.Todo.delete({ id });
}
function updateTodo(todo: Schema["Todo"]["type"]) {
client.models.Todo.update({ id: todo.id, isDone: !todo.isDone });
}
return (
<Authenticator>
{({ signOut, user }) => (
<main>
<h1>{user?.signInDetails?.loginId}'s todos</h1>
<h1>My todos</h1>
<button onClick={createTodo}>+ new</button>
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
}}
>
<span
onClick={() => deleteTodo(todo.id)}
style={{
width: "100%",
alignContent: "center",
textAlign: "left",
}}
>
{todo.content}
</span>
<span
style={{
width: "100%",
alignContent: "center",
textAlign: "right",
}}
>
<input
type="checkbox"
checked={todo.isDone!}
onChange={() => updateTodo(todo)}
/>
</span>
</div>
</li>
))}
</ul>
<div>
🥳 App successfully hosted. Try creating a new todo.
<br />
<a href="https://docs.amplify.aws/nextjs/start/quickstart/nextjs-app-router-client-components/">
Review next steps of this tutorial.
</a>
</div>
<button onClick={signOut}>Sign out</button>
</main>
)}
</Authenticator>
);
}
機能
- 認証
- メールアドレス
- パスワード
- データ操作(Todo)
- Create
- Read
- Update
- Delete
11. サーバーを起動
npm run dev
12. ブラウザで確認(ローカル)
- http://localhost:3000
- 画面キャッチャーは下記の14を参照
13. ローカルからAmplifyへデプロイ
git add .
git commit -am "added isDone"
git push
- CI/CDビルドがトリガーされる
- デプロイ後、数分後にブラウザで確認
14. ブラウザで確認(Amplifyのデプロイドメイン)
- https://main.12345678901234.amplifyapp.com/
15. 備考
今回はAWS Amplify(Gen2)を使い、認証(Cognito)を行うのとTodoアプリを実装する内容についてでした。
16. 参考
- Docs | Next.js (nextjs.org)
- Quick Start – React
- TypeScript: Documentation – TypeScript for the New Programmer (typescriptlang.org)
- Next.js App Router – Next.js – AWS Amplify Gen 2 Documentation
投稿者プロフィール
-
開発好きなシステムエンジニアです。
卓球にハマってます。