Amplify(Next.js, Typescript) 2_複数テーブルのリレーション編
Amplify ドキュメント
https://docs.amplify.aws/start/q/integration/next/
■15. 投稿ページの下準備
uuidというのを利用するので、インストール
yarn add uuid
pages/create-post.jsを作成。
まずは、第一段階目のコーディング。
import { withAuthenticator } from "@aws-amplify/ui-react"; import { useState, useRef, React } from "react"; import { API } from "aws-amplify"; import { useRouter } from "next/router"; import { v4 as uuid } from "uuid"; const initialState = {title: "", content: ""} function CreatePost(){ const [post, setPost] = useState(initialState) const { title, content } = post const router = useRouter function onChange(e){ setPost(() => ({ ...post, [e.target.name]: e.target.value })) } async function createNewPost(){ if(!title || !content) return; const id = uuid(); } } export default CreatePost;
ここからAPIを利用して、GraphQLのMutationでCreatePostができるようにしていく。
import { withAuthenticator } from "@aws-amplify/ui-react"; import { useState, useRef, React } from "react"; import { API } from "aws-amplify"; import { useRouter } from "next/router"; import { v4 as uuid } from "uuid"; import { createPost } from "../src/graphql/mutations" const initialState = {title: "", content: ""} function CreatePost(){ const [post, setPost] = useState(initialState) const { title, content } = post const router = useRouter function onChange(e){ setPost(() => ({ ...post, [e.target.name]: e.target.value })) } async function createNewPost(){ if(!title || !content) return; const id = uuid(); post.id = id await API.graphql({ query: createPost, variables: {input: post}, authMode: "AMAZON_COGNITO_USER_POOLS" }) // router.push(`/posst/${id}`) } return( <div> <h1>Create new Post</h1> </div> ) } export default CreatePost;
ここまではまだ準備段階。
router.pushもコメントアウトしておく。
まだh1が表示されるだけである。
■16. 投稿ページのフォーム作成
15の続き。
wigetフォームを簡単に作成できるモジュールをインストール。
SimpleMDEはコードも書ける!
npm install react-simplemde-editor react-markdown
create-post.jsへインポートする。
(中略) import SimpleMDE from "react-simplemde-editor" import "easymde/dist/easymde.min.css"
タイトルの入力欄と、ウィジェットフォームを表示させるようにする。
(中略) return( <div> <h1 className="text-3xl font-semibold tracking-wide mt-6">Create new Post</h1> <input onChange={onChange} name="title" placeholder="Title" value={post.title} className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2" /> <SimpleMDE value={post.content} onChange={(value) => setPost({...post, content: value})} /> </div> ) (中略)
投稿できるようするために、ウィジェットの下に「投稿を作成する」ボタンを追加する。
<button type="button" className="mb-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg" onClick={createNewPost} > Create Post </button>
非同期で実行されるcreateNewPost関数は、titleまたはcontentがfalsyの場合、何も中身のないものがreturnされる。
中身があれば、uuidで、世界で一つだけのidを取得し、postのidに設定される。
そして、待っていた API,graphqlが稼働する。
実行されるクエリはcreatePost、 variableはinputで投稿(post)されたもの。投稿にはコンテンツタイトルを付ける必要がある。
そして、これにより、authModeがAmazonのコグニートのユーザープールにあるものとして認識されるようになる。
したがって、ログインした人だけが、投稿を作成する権限がある。
しかし、このままでは駄目。
CreatePostコンポーネントは、 withAuthenticator でラップしなければ、機能しない。
export default withAuthenticator(CreatePost);
しかし、これでも、まだ駄目。
更新すると、参照エラーで「ナビゲーターが定義されていない」と出る。
これは、SSR、つまりサーバー側のレンダリングと関係がある。
それは
import SimpleMDE from "react-simplemde-editor"
に原因がある。
そのため、サーバー側のレンダリングをするためには、少し手を加える必要がある。
ここで登場するのがdynamicインポート。
「JavaScriptモジュールを動的にインポートして操作できます。また、SSRでも機能します。」
とのこと。
import dynamic from "next/dynamic"; const SimpleMDE = dynamic(() => import("react-simplemde-editor"), {ssr: false})
この文法通り、SSRのtoggleを渡す必要がある。
ここまでの全体感。
import { withAuthenticator } from "@aws-amplify/ui-react"; import { useState, useRef, React } from "react"; import { API } from "aws-amplify"; import { useRouter } from "next/router"; import { v4 as uuid } from "uuid"; import { createPost } from "../src/graphql/mutations" import dynamic from "next/dynamic"; const SimpleMDE = dynamic(() => import("react-simplemde-editor"), {ssr: false}) // import SimpleMDE from "react-simplemde-editor" import "easymde/dist/easymde.min.css" const initialState = {title: "", content: ""} function CreatePost(){ const [post, setPost] = useState(initialState) const { title, content } = post const router = useRouter function onChange(e){ setPost(() => ({ ...post, [e.target.name]: e.target.value })) } async function createNewPost(){ if(!title || !content) return; const id = uuid(); post.id = id await API.graphql({ query: createPost, variables: {input: post}, authMode: "AMAZON_COGNITO_USER_POOLS" }) // router.push(`/post/${id}`) } return( <div> <h1 className="text-3xl font-semibold tracking-wide mt-6">Create new Post</h1> <input onChange={onChange} name="title" placeholder="Title" value={post.title} className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2" /> <SimpleMDE value={post.content} onChange={(value) => setPost({...post, content: value})} /> <button type="button" className="mb-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg" onClick={createNewPost} > Create Post </button> </div> ) } export default withAuthenticator(CreatePost);
■17. 動的IDと新しく作成された投稿の表示
まずは、pagesディレクトリに新しく posts/[id].js を新規作成。
ここでの考え方は、作成投稿に戻って、先に進むということです。
import { API } from 'aws-amplify' import { useRouter } from 'next/router' import ReactMarkDown from 'react-markdown' import '../../configureAmplify' import { listPosts, getPost } from '../../src/graphql/queries' export default function Post({post}){ const router = useRouter() if(router.isFallback){ return <div>Loading...</div> } return( <div> <h1 className='text-5xl mt-4 font-semibold tracing-wide'> {post.title} </h1> </div> ) }
これで、create-post.jsでコメントアウトしていた、router.pushを解除することができる。
import { withAuthenticator } from "@aws-amplify/ui-react"; import { useState, useRef, React } from "react"; import { API } from "aws-amplify"; import { useRouter } from "next/router"; import { v4 as uuid } from "uuid"; import { createPost } from "../src/graphql/mutations" import dynamic from "next/dynamic"; const SimpleMDE = dynamic(() => import("react-simplemde-editor"), {ssr: false}) // import SimpleMDE from "react-simplemde-editor" import "easymde/dist/easymde.min.css" const initialState = {title: "", content: ""} function CreatePost(){ const [post, setPost] = useState(initialState) const { title, content } = post const router = useRouter function onChange(e){ setPost(() => ({ ...post, [e.target.name]: e.target.value })) } async function createNewPost(){ if(!title || !content) return; const id = uuid(); post.id = id await API.graphql({ query: createPost, variables: {input: post}, authMode: "AMAZON_COGNITO_USER_POOLS" }) router.push(`/post/${id}`) } return( <div> <h1 className="text-3xl font-semibold tracking-wide mt-6">Create new Post</h1> <input onChange={onChange} name="title" placeholder="Title" value={post.title} className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2" /> <SimpleMDE value={post.content} onChange={(value) => setPost({...post, content: value})} /> <button type="button" className="mb-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg" onClick={createNewPost} > Create Post </button> </div> ) } export default withAuthenticator(CreatePost);
しかし、このままでは、ルーターは認識するが、投稿を表示することはできない。
何か足りないか?
「Decrypt」、投稿自体を復号化し、自分自身をレンダリングする、という方法がある。
それは、getStaticPathsを使うことになる。
これによって、表示したい場所へのパスが得られる。
[id].js
import { API } from 'aws-amplify' import { useRouter } from 'next/router' import ReactMarkDown from 'react-markdown' import '../../configureAmplify' import { listPosts, getPost } from '../../src/graphql/queries' export default function Post({post}){ const router = useRouter() if(router.isFallback){ return <div>Loading...</div> } return( <div> <h1 className='text-5xl mt-4 font-semibold tracing-wide'> {post.title} </h1> </div> ) } export async function getStaticPaths(){ const postData = await API.graphql({ query: listPosts }) const paths = postData.data.listPosts.items.map(post => { params: { id:post.id } }) return{ paths, falback: true } }
次に、投稿データを渡すことができるようにする別の関数を作成する必要がある。
getStaticPropsを使う。
全体感としては、以下になる。
import { API } from 'aws-amplify' import { useRouter } from 'next/router' import ReactMarkDown from 'react-markdown' import '../../configureAmplify' import { listPosts, getPost } from '../../src/graphql/queries' export default function Post({post}){ const router = useRouter() if(router.isFallback){ return <div>Loading...</div> } return( <div> <h1 className='text-5xl mt-4 font-semibold tracing-wide'> {post.title} </h1> </div> ) } export async function getStaticPaths(){ const postData = await API.graphql({ query: listPosts }) const paths = postData.data.listPosts.items.map((post) => ({ params: { id:post.id } })) return{ paths, fallback: true } } export async function getStaticProps({params}){ const { id } = params const postData = await API.graphql({ query: getPost, variables: {id}, }) return { props :{ post: postData.data.getPost } } }
■18. インデックスルートにマークアップとスタイリングを追加する
まずは、getStaticPropsにプロパティをもう一つ追加する。
export async function getStaticProps({params}){ const { id } = params const postData = await API.graphql({ query: getPost, variables: {id}, }) return { props :{ post: postData.data.getPost }, revalidate: 1 } }
これで、[id].jsの全体感としては、以上になる。
import { API } from 'aws-amplify' import { useRouter } from 'next/router' import ReactMarkDown from 'react-markdown' import '../../configureAmplify' import { listPosts, getPost } from '../../src/graphql/queries' export default function Post({post}){ const router = useRouter() if(router.isFallback){ return <div>Loading...</div> } return( <div> <h1 className='text-5xl mt-4 font-semibold tracing-wide'> {post.title}</h1> <p className='text-sm font-light my-4'>By {post.username}</p> <div className="mt-8"> <p ReactMarkDown="prose">{post.content}</p> </div> </div> ) } export async function getStaticPaths(){ const postData = await API.graphql({ query: listPosts }) const paths = postData.data.listPosts.items.map((post) => ({ params: { id:post.id } })) return{ paths, fallback: true } } export async function getStaticProps({params}){ const { id } = params const postData = await API.graphql({ query: getPost, variables: {id}, }) return { props :{ post: postData.data.getPost }, revalidate: 1 } }
index.jsのスタイリングなどの微調整
import { useState, useEffect } from "react" import { API } from 'aws-amplify' import { listPosts } from "../src/graphql/queries" import Link from "next/link" export default function Home() { const [posts, setPosts] = useState([]) useEffect(() => { fetchPosts() }, []) async function fetchPosts(){ const postData = await API.graphql({ query: listPosts }) setPosts(postData.data.listPosts.items) } return ( <div> <h1 className="text-sky-400 text-3xl font-bold tracking-wide mt-6 mb-2"> My Post </h1> { posts.map((post, index) => ( <Link key={index} href={`/post/${post.id}`}> <div className="cursor-pointer border-b border-gray-300 mt-8 pb-4"> <h2 className="text-xl font-semibold" key={index}>{post.title}</h2> <p className="text-gray-500 mt-2">Author: {post.username}</p> </div> </Link> )) } </div> ) }
■18. マイ投稿ページの作成
Amplify(Next.js, Typescript) 1_セットアップ編
Amplify ドキュメント
https://docs.amplify.aws/start/q/integration/next/
■0. AWSのセットアップ
アカウントだけは先に作っておくこと。それ以外は何もしなくても大丈夫。I AMユーザーの管理者権限も一応念のために先にあると良いが、このプロジェクトのセットアップには必要ない。
■1. Amplify CLIのインストール
ローカル端末にAmplify CLIのインストール
【mac】sudo npm install -g @aws-amplify/cli 【windows → 管理者権限でpower shellを開く】npm install -g @aws-amplify/cli
※いきなりこちらを実行でOK。
Amplify CLI の初期セットアップ
Amplify を使ったプロジェクト用のI AMユーザを、以下のコマンドで生成する。
amplify configure
プロファイル名を設定しておくと、initするときに、明確に紐付けできる。
(余談)既存カテゴリの更新、削除を行うことも可能
(更新)
amplify update (カテゴリ名)
(削除)
amplify remove (カテゴリ名)
(設定のステータスの確認)
amplify status (カテゴリ名)
再度ステータスを確認
amplify status api
→"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add
(Try "amplify add api" to create a backend API and then "amplify push" to deploy everything)
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify console" to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
■2. AWS AppSyncでコンソール画面をチェック
ログインした状態でaws内で、
AWS AppSync
で検索。
ここがQueryの管理画面のベースになる。
■3. 開発プロジェクトの作成
yarn install *インストールしていない場合
npm install --global yarn yarn --version
Next.jsフレームワークのインストール
npx create-next-app プロジェクト名
※npm同様、プロジェクトをコピーするときは「yarn install」でできるようだ。
○TypeScript の導入
https://nextjs.org/learn/excel/typescript/create-tsconfig
2-1. 空のtsconfig.json作成
touch tsconfig.json(macのターミナル) New-Item tsconfig.json(Windowsのシェルスクリプト)
2-2. 必要moduleのインストール
yarn add -D typescript @types/react @types/node
2-3. 開発server起動
yarn dev
そうすると、tsconfig.json に初期設定が自動的に反映される。
2-4. 「pages」ディレクトリの、_app.jsと index.jsを -> tsx へ拡張子変更
2-5. _app.jsを、AppProps型に編集
import { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return <Component {...pageProps} /> } export default MyApp
※yarn add -D typescript @types/react @types/node でtypescriptをインストールしたとき、tsconfig.jsonで
(中略) "types": ["typed-query-selector"] , (中略) "moduleResolution": "node", (中略)
が欠けた状態で出力された。
windowsでのインストールは気をつけたい。
まずは
yarn add typed-query-selector
で、モジュールをインストール。
で、一度閉じて開きなおしたら、直った。
念のため、完全版は以下。
{ "compilerOptions": { "target": "es5", "lib": [ "dom", "dom.iterable", "esnext", ], "types": ["typed-query-selector"] , "allowJs": true, "skipLibCheck": true, "strict": false, "forceConsistentCasingInFileNames": true, "noEmit": true, "incremental": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve" }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx" ], "exclude": [ "node_modules" ] }
○Tailwind CSS の導入
https://tailwindcss.com/docs/guides/nextjs
3-1. 必要moduleのインストール
yarn add tailwindcss@latest postcss@latest autoprefixer@latest
3-2. tailwind.config.js, postcss.config.jsの生成
npx tailwindcss init -p
3-3. tailwind.config.jsのpurge設定編集
tailwind.cssの適用範囲を意味する。
module.exports = { content: [ "./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], }
3-4. ルートディレクトリに、componentsフォルダを作成
mkdir components
3-5. globals.cssの編集
@tailwind base; @tailwind components; @tailwind utilities;
○SASSを読み込めるようにする
yarn add sass npm install sass
cssをscssにリネーム。pages内のファイルネームも忘れずに。
yarn環境で、間違えてnpmで入れないこと。その後の操作で、コンパイルエラーになって、最初からやり直す。
○React-Bootstrapをインストール
https://react-bootstrap.github.io/getting-started/introduction
yarn add react-bootstrap bootstrap@5.1.3 npm install react-bootstrap bootstrap@5.1.3
こちらの方がよりbootstrapライクである。
○Reactのアイコンライブラリ
https://react-icons.github.io/react-icons/
yarn add react-icons npm install react-icons
○fontawesomeのReact版アイコンライブラリ
https://fontawesome.com/v5/docs/web/use-with/react
yarn add @fortawesome/fontawesome-svg-core yarn add @fortawesome/free-solid-svg-icons yarn add @fortawesome/react-fontawesome yarn add @fortawesome/free-brands-svg-icons npm i --save @fortawesome/fontawesome-svg-core npm install --save @fortawesome/free-solid-svg-icons npm install --save @fortawesome/react-fontawesome npm install --save @fortawesome/free-brands-svg-icons
○React Playerをインストール
https://www.npmjs.com/package/react-player
yarn add react-player npm i -D react-player
■4. Amplifyの導入
プロジェクトのルートディレクトリで初期化コマンドを実行
amplify init
質問が対話形式で出てくる。
? Enter a name for the project?
→プロジェクト名を入れる
? Initialize the project with the above configuration? (Y/n)
→Y で。(プロジェクトを初期化しますか? と聞かれている)
? Select the authentication method you want to use: (Use arrow keys)
→AWS profile で。(使用する認証方法を選択します、と聞かれている)
? Please choose the profile you want to use(Use arrow keys)(使用したいプロファイルを選択してください、と聞かれている)
→default で。
Amplify CLIをインストールした際のユーザー名を選択。
終わると
Some next steps:
"amplify status" will show you what you've added already and if it's locally configured or deployed
"amplify add
"amplify push" will build all your local backend resources and provision it in the cloud
"amplify console" to open the Amplify Console and view your project status
"amplify publish" will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud
Pro tip:
Try "amplify add api" to create a backend API and then "amplify push" to deploy everything
と出てくる。amplify のデプロイ周りの基本コマンドで、よく使うことになる。
○必要な依存関係をインストール
yarn add aws-amplify @aws-amplify/ui-react@1.x.x
■5. AppSync API、GraphQLとスキーマの設計
GraphQL APIをアプリに追加(「カテゴリ」という単位でバックエンドの設定を追加することになる)
amplify add api
いろんな質問が対話形式で出てくる。
AmplifyでのQraphQLの条件抽出や属性値について
まずは、属性値のvariablesとは?
https://docs.amplify.aws/lib/graphqlapi/query-data/q/platform/js/#query-declarations
https://ja.reactjs.org/docs/hooks-effect.html#example-using-hooks-1
https://mo-gu-mo-gu.com/async-await-in-useeffect/
graphql(options: GraphQLOptions, additionalHeaders? : { [key: string] : string }): Promise<GraphQLResult
Amplifyによるデータフェッチと非同期通信について
ほぼ答えに近いコードが掲載してるのが以下。Amplify graphQL Clientを使ったデータフェッチの、
https://qiita.com/otanu/items/2c522a652e5843a5e2c5
また、Amplifyの、getStaticPropsやgetServerSidePropsを使わない、データフェッチのやり方が以下。
https://docs.amplify.aws/lib/graphqlapi/query-data/q/platform/js/
じゃあ、そういう「答え」になる理由は何なのか?ということになると、大前提に「非同期通信のプロセスについて」がある。
以下、それらに関連する、重要な概念等の情報は以下。
■Promiseについて
Promiseオブジェクトは、作成された時点では Pending (待機)状態です。その後のコールバック関数内で resolve() (解決)された時点で Fulfilled 状態となり、then() が実行されます。逆に reject() (失敗)が呼び出された時点で Rejected 状態となり、catch() が実行されます。つまり resolve() も reject() も呼び出されない間は pending 状態のまま、次のチェーンには進みません。
状態が一度 Pending から変化すると、その後の状態は二度と変化しないことが約束されています。resolve() または reject() は一度しか実行されません。
https://kde.hateblo.jp/entry/2018/11/01/042432
https://hidekazu-blog.com/javascript-promise/
https://qiita.com/bow_arrow/items/a88cf7a444fb6045b8e4
■await式 について
async/await式は、Promiseのプロセスがわかった前提で使わないと、思わぬ落とし穴にひっかかる。Async Functionはasync/awaitとも呼ばれることがあります。 この呼ばれ方からも分かるように、Async Functionとawait式は共に利用します。
await式はAsync Function内でのみ利用できます。 await式は右辺のPromiseインスタンスがFulfilledまたはRejectedになるまで、その行(文)で非同期処理の完了を待ちます。 そしてPromiseインスタンスの状態が変わると、次の行(文)から処理を再開します。
https://azu.github.io/promises-book/#async-function-await
■in 演算子について
in 演算子は、指定されたプロパティが指定されたオブジェクトにある場合に true を返します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/in
getServerSidePropsが使えるのは、pages内の一つのページに対して一つだけ。
それはgetStaticPropsも同様だった。
いくらコンポーネントを分けても、どちらからはundefiedになる。
ISR/SSG/SSRのサンプルコード
Pre-rendering = Server-side Rendering みたいなやつの総称。SEO のために必要だったりします。
そしてPre-rendering には 2種類ある。
・ Static Generation: JSのビルド時にページを生成する方法
・ Server-side Rendering: HTTPリクエストが来た時にページを生成する方法
AmplifyのAPIをuseSWRで取得する方法がどうしても見つからない。。。。
https://zenn.dev/thim/articles/d09cc8500d47d3216907
https://github.com/TakahiroHimi/Next-SWR-sample
https://note.com/fz5050/n/nd16f20e932ad
そして、この内容自体はしっかり動く。ただし、Amplifyの「API」を同じように持ってきても、エラーになる。
SWRのBound Mutate に関する記事
https://dev.classmethod.jp/articles/tried-swr-bound-mutate-with-nextjs/
ここまでで、
グローバルスコープに、プリレンダリングを複数設置することはできない。それは、コンポーネントが分かれても、同じページに読み込むのであれば一緒。
ということがわかる。
クエリパラメーターをつけるために。
サーバーサイドでは、以下のやり方がある。
公式ドキュメントからひも解いてみる。
AmplifyGraphQLクライアントの使用
https://docs.amplify.aws/lib/graphqlapi/query-data/q/platform/js/
Amplify Hosting を使用したサーバーサイドレンダリングアプリをデプロイhttps://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/server-side-rendering-amplify.html
APIとデータベースをアプリに接続します
https://docs.amplify.aws/start/getting-started/data-model/q/integration/next/
GraphQLTransformerv1からv2への移行
https://docs.amplify.aws/cli/migration/transformer-migration/
AMPLIFY SNS WORKSHOP
AWS AppSync Javascript SDK で、ApolloClientが使える?この方向性がある?
【公式】
https://github.com/awslabs/aws-mobile-appsync-sdk-js/
【参考ブログ】
Amplifyのデプロイとホスティング
まずは、package.jsonに、デプロイに必要な修正を加える。
Amplifyの情報まとめ
Amplify Docs 公式ドキュメント_トップ
(Libraries、UI components、CLI、などが閲覧頻度高い)
Amplify UI
■認証に関すること
Amplify UI
Authenticator
https://ui.docs.amplify.aws/react/components/authenticator
→認証のコンポーネントの元。
これが、amplify-ui-react v1.x系だと、やり方が変わってくるのと、CSSをオーバーライドできない。結局は、最新版の2系を導入することになった。
Amplify
AUTHENTICATION
Password & user management
https://docs.amplify.aws/lib/auth/manageusers/q/platform/js/#complete-new-password
→aws-amplifyのCLIの「Auth」を利用した、auth認証に関するコードのまとめかたの公式ライブラリ。
Amplify UIのAuthenticator で骨格となるユーザー認証はカバーできるため、使い所の切り分けをきちんとコード内に記録しておく必要がある。
aws-amplify/amplify-js (by GitHub)
→aws-amplifyをreactで使った場合のサンプルコード集。
サービスの切り分けを、これでディレクトリとして分類して確認できる。
■Auth
Auth.currentAuthenticatedUser()
→import { Auth } from 'aws-amplify';
と、aws-amplifyライブラリのAuthオブジェクトを呼び出して使える。
Auth.currentAuthenticatedUser()メソッドの実行で、現在の認証済みユーザーオブジェクトを取得できる。
■API