LoginSignup
18
12

More than 3 years have passed since last update.

Amplify Admin UIを試してみる(ブログ構築)

Last updated at Posted at 2020-12-13

re:Invent2020で発表されたAmplify Admin UIを試してみます。
確認ポイントとしては、以下で、特に1.については可能性を探ってみたいポイントです。

  1. 今後、管理画面の構築が不要になる!?
  2. HeadlessCMSとの違い

Amplify Admin UIとは

以下の2つの機能を提供してくれるツール(管理画面)です。

  • (アプリ管理者 ※非開発者向け機能)アプリケーションのユーザーおよびコンテンツ管理など
  • (システム管理者 ※開発者向け機能)データベースのモデリング、認証・認可機能の追加、管理画面のユーザー管理(システム管理者・アプリ管理者)など

作成したサンプルアプリ

画面収録 2020-12-13 0.10.55.mov.gif

Demo Page
https://thirosue.github.io/amplify-admin-ui-sample/

ソースコードの全量はGitHubにあります。
https://github.com/Thirosue/amplify-admin-ui-sample

前提

  • nodeがインストールされていること
  • yarnがインストールされていること

大まかな流れ

  1. 初期アプリセットアップ
  2. Amplifyセットアップ
  3. Admin UI有効化
  4. Admin UIユーザ払い出し
  5. データモデル定義
  6. データ登録
  7. アプリ修正

初期アプリセットアップ

$ git clone git@github.com:Thirosue/amplify-admin-ui-sample.git
$ cd amplify-admin-ui-sample
$ yarn
$ yarn start

ここまで実行のあと、以下URLにアクセスすると、簡単な「ブログ一覧」、「ブログページ」が表示されるはずです。

Compiled successfully!

You can now view amplify-admin-ui-sample in the browser.

  Local:            http://localhost:3000/amplify-admin-ui-sample
  On Your Network:  http://192.168.11.11:3000/amplify-admin-ui-sample

Note that the development build is not optimized.
To create a production build, use yarn build.

Amplify セットアップ

Amplifyはこちらを参考にセットアップします。
AWS Amplify CLIの使い方〜インストールから初期セットアップまで〜

Amplify Admin UI有効化

AWSマネジメントコンソールで以下に移動します。

「AWS Amplify」 - 「作成したアプリ」 - 「Set up Admin UI」 - 「on」 - 「Invite users」でユーザ招待 - メールを確認してログイン(※初期PWセットアップとかとか)

最初は、データモデル定義する(For 開発者)ため、「admin」ユーザを招待します。

  • 「AWS Amplify」 遷移のあと

スクリーンショット 2020-12-12 16.21.05.png

  • 「作成したアプリ」 クリックのあと

スクリーンショット 2020-12-12 16.21.41.png

  • 「Set up Admin UI」 クリックのあと

スクリーンショット 2020-12-12 16.23.43.png

  • 「on」のあと

スクリーンショット 2020-12-12 16.26.06.jpg

  • 「Invite user(s)」でユーザ招待

スクリーンショット 2020-12-12 16.27.55.png

  • 招待メール

スクリーンショット 2020-12-12 16.30.14.jpg

  • ログイン後トップ画面

スクリーンショット 2020-12-12 16.35.41.png

コンテンツ(Blog)のモデリング

Admin UIで以下を行う。

  • 「Data」へ移動

スクリーンショット 2020-12-12 16.39.26.jpg

  • 「Add」 - 「Add model」

スクリーンショット 2020-12-12 16.41.32.png

  • データモデル定義

ブログに必要な最低限のデータ定義をします。

スクリーンショット 2020-12-12 16.44.54.png

  • 作成中...(裏でCfnが走っている)

スクリーンショット 2020-12-12 16.47.18.png

スクリーンショット 2020-12-12 16.48.34.png

コンテンツ管理者ユーザ作成

AWSマネジメントコンソールに戻って、次は非開発者向けの管理者用のユーザ(「Manage only」ユーザ)を作成します。

スクリーンショット 2020-12-12 16.53.33.png

ここでブログを投稿していきたいところですが、2020/12/12現在では、以下のようになってしまいます。

スクリーンショット 2020-12-12 16.58.57.png

コンテンツ投稿

仕方ないので、Adminユーザからブログを投稿していきます。

  • 1投目

スクリーンショット 2020-12-12 17.05.51.png

  • 2投目

スクリーンショット 2020-12-12 17.08.23.png

  • 3投目

スクリーンショット 2020-12-12 17.10.47.png

  • 最終的な一覧はこんな感じ

スクリーンショット 2020-12-12 18.06.55.png

Dynamoに登録されているはずだから見にいくと...

2020/12/12現在ではDynamoDBは空っぽ...

公式ブログ では、

この画面から、レストランのオーナーはメニューに項目を追加、削除、編集をいつでも行うことが出来ます。また、ここで変更した項目は保存後すぐにウェブサイトに反映されます。

こう書いてあるので、Betaが外れる(Bugfixされる)と、DynamoDBに登録されるはずです。

  • DynamoDB

スクリーンショット 2020-12-12 18.10.46.png

  • Cfn(Dynamoの物理名)も念のため、確認

スクリーンショット 2020-12-12 18.10.28.jpg

  • この状態でamplify pullしてみると、API(AppSync)が作成されている (=amplify add apiでGraphQLのAPIを作成した状態)
% amplify pull

Pre-pull status:

Current Environment: dev

| Category | Resource name        | Operation | Provider plugin   |
| -------- | -------------------- | --------- | ----------------- |
| Api      | amplifyadminuisample | No Change | awscloudformation |

✔ Successfully pulled backend environment dev from the cloud.


Post-pull status:

Current Environment: dev

| Category | Resource name        | Operation | Provider plugin   |
| -------- | -------------------- | --------- | ----------------- |
| Api      | amplifyadminuisample | No Change | awscloudformation |
  • Admin UIで作成すると、スタックが作成済みの状態からpullすることになるため、クライアントのコードの自動生成もスキップされてしまう...(amplify cliの以下フロー)
? Do you want to generate code for your newly created GraphQL API Yes
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
? 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

結論、Beta版の現状(2020/12/12時点)では、amplify cliで作成した方が無難...(当たり前か...)

まとめ

1. 管理画面の構築が不要になる!?

  • 非開発者向けの管理画面は、Admin UI自体をカスタマイズ可能(Lambdaのボイラーテンプレート出力みたいに)になれば、かなり嬉しいかも
  • 開発者向け機能は、当分cliで (アップデートまち)

2. HeadlessCMSとの違い

  • ContentFulなどとほぼ同様の使用感
  • コンテンツ以外の管理(ユーザ管理など)もできるので、今後アップデートが進めば一元管理できるかも

参考リンク

以下、蛇足 (仕方ないのでamplify cliで、Amplifyを利用したブログを完成させる)

一旦、Admin UIで作成したAppSyncは削除

AppSync 追加

こんな感じで、Admin UIで作成したものと同様のModelを生成し、amplify pushする。

% amplify add api
? Please select from one of the below mentioned services: GraphQL
? Provide API name: amplifyadminuisample
? Choose the default authorization type for the API API key
? Enter a description for the API key: 1df1c9bb-1bd8-1fde-b2d6-cea1ee234285
? After how many days from now the API key should expire (1-365): 7
? Do you want to configure advanced settings for the GraphQL API No, I am done.
? Do you have an annotated GraphQL schema? No
? Choose a schema template: Single object with fields (e.g., “Todo” with ID, name, description)
? Do you want to generate code for your newly created GraphQL API Yes
? Choose the code generation language target javascript
? Enter the file name pattern of graphql queries, mutations and subscriptions src/graphql/**/*.js
? 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
  • Model定義
amplify/backend/api/amplifyadminuisample/schema.graphql
type Blog @model {
  id: ID!
  title: String!
  description: String!
  body: String!
  imagePath: String!
}

コンテンツ追加

管理コンソールから手で登録
→bodyはMD形式です

スクリーンショット 2020-12-12 23.02.21.png

ソースコード修正

  • GraphQL クエリ
/src/graphql/queries.js
export const listBlogs = /* GraphQL */ `
  query ListBlogs(
    $filter: ModelBlogFilterInput
    $limit: Int
    $nextToken: String
  ) {
    listBlogs(filter: $filter, limit: $limit, nextToken: $nextToken) {
      items {
        id
        title
        description
        body
        imagePath
      }
      nextToken
    }
  }
`;

  • Amplify Import
/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
import Amplify from 'aws-amplify'; // <---- 追加
import awsconfig from './aws-exports'; // <---- 追加
Amplify.configure(awsconfig); // <---- 追加

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
  • サービスクラス作成
/src/service/blog.js
import { API, graphqlOperation } from 'aws-amplify';
import { listBlogs } from '../graphql/queries';

async function list() {
    const results = await API.graphql(graphqlOperation(listBlogs));
    return results.data.listBlogs.items
}

export default list;
  • カスタムフック作成
/src/hook/useBlog.js
import { useState, useEffect } from 'react';
import getBlogs from '../service/blog';

// eslint-disable-next-line
export default () => {
    const [blogs, setBlogs] = useState([]);

    // このカスタムフックを利用しているコンポーネントがマウントされたら ブログ一覧 を取得する。
    useEffect(() => {
        const fetchAll = async () => {
            const results = await getBlogs();
            setBlogs(results)
        }

        fetchAll()
    }, []);

    return { blogs };
};
  • ページコンポーネント修正

リストレンダリングするように修正

/src/App.js
function App() {
  const classes = useStyles();
  const [detail, setDetail] = React.useState(false);
  const { blogs } = useBlog(); // <------ カスタムフックを利用する
  const [id, setId] = React.useState(1); // <------ 選択したブログID用

  React.useEffect(() => {
    console.log(blogs)
  }, [blogs]);

  const handleClick = async id => {
    console.log('select blog id : %s', id);
    setId(id - 1) // ブログIDをセットする
    setDetail(true)
  }

  return (
    <DialogContent>
      {!detail && (
        <>
          <ThemeProvider theme={theme}>
            <Typography variant="h4">Sample Blog</Typography>
          </ThemeProvider>
          <Box mb="1.5rem" />
          <Grid container spacing={3}>
            {/* リストレンダリング */}
            {0 < blogs.length && blogs.sort((a, b) => a.id - b.id).map(blog =>
              <Grid key={blog.id} item xs={12} sm={4} md={3}>
                {/* ブログ選択時はブログIDを渡す */}
                <Card onClick={() => handleClick(blog.id)}>
                  <CardMedia
                    className={classes.media}
                    image={"/amplify-admin-ui-sample/" + blog.imagePath}
                  />
                  <CardContent>
                    <Typography gutterBottom variant="h5" component="h2">
                      {blog.title}
                    </Typography>
                    <Typography variant="body2" color="textSecondary" component="div">
                      {blog.description}
                    </Typography>
                  </CardContent>
                </Card>
              </Grid>
            )}
          </Grid>
        </>
      )}
      {!!detail && (
        <div className={classes.root}>
          <Grid container spacing={3}>
            <Grid item xs={12} sm={12} md={12}>
              {/* 選択したブログを表示する */}
              <Card>
                <CardMedia
                  className={classes.detail}
                  image={"/amplify-admin-ui-sample/" + blogs[id].imagePath}
                />
                <CardContent>
                  <Typography className={classes.title} gutterBottom variant="h4" component="h2">
                    {blogs[id].title}
                  </Typography>
                  <Typography className={classes.content} variant="subtitle1" color="textSecondary" component="div">
                    <ReactMarkdown>{blogs[id].body}</ReactMarkdown>
                  </Typography>
                </CardContent>
              </Card>
            </Grid>
          </Grid>
          <Box mb="1rem" />
          <Link
            component="button"
            variant="subtitle1"
            onClick={() => setDetail(false)}
          >
            Back
          </Link>
        </div>
      )}
    </DialogContent>
  );
}
  • 修正差分

https://github.com/Thirosue/amplify-admin-ui-sample/commit/e4abc73bb77347000bc0e7627d295b332a2308f9
※ amplifyフォルダはコミット対象外にしています。

  • 対象ブランチ

18
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
12