NTT東日本の中村です。
プレビュー版であるAmplify Gen2のバージョンがGAとなり、コマンドの変更など、いくつかの大きな変更が発生しているようです。
変更の概要
@aws-amplify/backendのモジュールからbetaの文字が無くなり、1.0.0にバージョンが上がっています。
% npm info @aws-amplify/backend
@aws-amplify/backend@1.0.0 | Apache-2.0 | deps: 13 | versions: 70
This package is the entry point for customers to define their Amplify backend using `defineBackend`. It also pulls in functions for defining other feature verticals.
dist
.tarball: https://registry.npmjs.org/@aws-amplify/backend/-/backend-1.0.0.tgz
.shasum: da74d13159db782191684964dd3e9b3ddb958714
.integrity: sha512-QKLdTFtXnff4VUHmZBs+XK3xeXe0TZAZkR4Ke2kwWo6engaYahZ3UQO7Ndkt1D/xcq08e4QayGgRB+XGr7B8Wg==
.unpackedSize: 174.4 kB
dependencies:
@aws-amplify/backend-auth: ^1.0.0 @aws-amplify/client-config: ^1.0.0
@aws-amplify/backend-data: ^1.0.0 @aws-amplify/data-schema: ^1.0.0
@aws-amplify/backend-function: ^1.0.0 @aws-amplify/platform-core: ^1.0.0
@aws-amplify/backend-output-schemas: ^1.0.0 @aws-amplify/plugin-types: ^1.0.0
@aws-amplify/backend-output-storage: ^1.0.0 @aws-sdk/client-amplify: ^3.465.0
@aws-amplify/backend-secret: ^1.0.0 lodash.snakecase: ^4.1.1
@aws-amplify/backend-storage: ^1.0.0
maintainers:
- amplify-data-dev-npm <amplify-data-dev+npm@amazon.com>
- amplify-studio-uibuilder <aws-amplify-uibuilder@amazon.com>
- amplify-codegen <amplify-codegen+npm@amazon.com>
- amzn-oss <osa-3p@amazon.com>
- undefobj <rthrelkeld1980@gmail.com>
- aws-amplify-ops <aws-amplify@amazon.com>
- manuel.iglesias <manuel.iglesias@gmail.com>
- thaddmt <thaddmt@gmail.com>
- mattsb42-aws <bullocm@amazon.com>
dist-tags:
alpha: 0.1.1-alpha.0 latest: 1.0.0
beta: 0.13.0-beta.20 test: 0.0.0-test-20240327212405
published 13 hours ago by aws-amplify-ops <aws-amplify@amazon.com>
diff --git a/package.json b/package.json
index 38ed219..8a7878f 100644
--- a/package.json
+++ b/package.json
- "@aws-amplify/backend": "^0.13.0-beta.14",
- "@aws-amplify/backend-cli": "^0.12.0-beta.16",
+ "@aws-amplify/backend": "^1.0.0",
+ "@aws-amplify/backend-cli": "^1.0.1",
参考までに、5/2時点で チュートリアルに従い、NextJS(Server Components)で、npm create amplify@latestを実行した時の package.jsonです。
{
"name": "next-amplify-gen2",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"aws-amplify": "^6.2.0",
"next": "14.1.0",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@aws-amplify/backend": "^1.0.0",
"@aws-amplify/backend-cli": "^1.0.1",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"aws-cdk": "^2.139.1",
"aws-cdk-lib": "^2.139.1",
"constructs": "^10.3.0",
"esbuild": "^0.20.2",
"eslint": "^8",
"eslint-config-next": "14.1.0",
"tsx": "^4.8.2",
"typescript": "^5.4.5"
}
}
変更点
amplify→ampxコマンドに変更
実行コマンドがampxに変更になりました。amplifyって長くて打つのが大変でしたよね。私は大変でした。
amplifyの設定ファイルが、amplify_outputs.jsonに変更
昔はaws-exports.js、V6ではamplifyconfiguration.jsonという名前だった設定ファイルが、 amplify_outputs.jsonに変更になりました。
amplify_outputs.jsonの生成と、プログラム内でamplifyconfiguration.jsonを読み出している部分が幾つかあるため、ファイル名の置き換えが必要になります。
その他確認できた修正点
UIメニューが刷新
執筆のタイミングでUIが移行中だったようで、本日時点でUIが新しくなり、カスタムドメインも使えるようになりました。 詳細はこちらの記事でまとめられています。
StorageAccessLevelがDeprecatedとなりました
つい先日書いたばかりのStorage機能ですが、accessLevelでのアップロードが非推奨となりました。
aws-amplify@6.2.0では、accessLevelではなく、pathオプションでアップロード先を指定するように求められています。
import { uploadData } from 'aws-amplify/storage';
try {
const result = await uploadData({
path: 'public/album/2024/1.jpg',
// Alternatively, path: ({identityId}) => `protected/${identityId}/album/2024/1.jpg`
data: file,
options: {
onProgress // Optional progress callback.
}
}).result;
console.log('Succeeded: ', result);
} catch (error) {
console.log('Error : ', error);
}
ドキュメントの更新
5/2に順次各種ドキュメントのアップデートがされていますが、一部amplifyコマンドが残っているなどもあり、置き換えが必要そうです。
既存のアプリケーションをアップデートしてみた
新しいpackage.jsonに従い、モジュールを入れ替えただけでは動作しないので、一部ソースの修正を行う必要があります。 NextJS Server Componentsのアプリをアップデートしてみました。 先日のStorage機能がベースとなっています。
新しい設定ファイルの取得
存在しない設定ファイルを参照しようとしてエラーになるので、generate configコマンドを実行し、amplify-output.jsonを作成します。 なお、階層構造が異なるので、amplifyconfigration.jsonをリネームすればよい、というわけではありません。
ampxコマンド以外の所は従来と同様で、CloudFormationのスタック名を確認し、パラメータに含めればOKです。
npx ampx generate config --stack amplify-hogehoge-master-branch-9c38f4b63a
新しい設定ファイルをimportするように修正
設定ファイルの読み込みを全て修正します。
diff --git a/components/ConfigureAmplify.tsx b/components/ConfigureAmplify.tsx
index 792c2ef..a39cbe0 100644
--- a/components/ConfigureAmplify.tsx
+++ b/components/ConfigureAmplify.tsx
@@ -2,10 +2,10 @@
import { Amplify } from "aws-amplify";
-import config from "@/amplifyconfiguration.json";
+import outputs from "../amplify_outputs.json";
-Amplify.configure(config, { ssr: true });
+Amplify.configure(outputs, { ssr: true });
export default function ConfigureAmplifyClientSide() {
return null;
-}
+}
Dataのモデルのauthorizationの定義方法を修正
関数として定義するようになりました。 カスタムクエリも同様です。
diff --git a/amplify/data/resource.ts b/amplify/data/resource.ts
index 6ff2cf6..d2227f5 100644
--- a/amplify/data/resource.ts
+++ b/amplify/data/resource.ts
@@ -17,7 +17,7 @@ const schema = a.schema({
priority: a.enum(["low", "medium", "high"]),
})
.identifier(["tag", "createDate"])
- .authorization([a.allow.owner()]),
+ .authorization((allow) => [allow.owner()]),
StorageのGroupの定義方法を修正
groupの定義を配列で行うように修正しました。
diff --git a/amplify/storage/resource.ts b/amplify/storage/resource.ts
index 6ff2cf6..d2227f5 100644
--- a/amplify/storage/resource.ts
+++ b/amplify/storage/resource.ts
@@ -6,7 +6,7 @@ name: "myProjectFiles",
access: (allow) => ({
- "admin/*": [allow.group("admin").to(["read", "write", "delete"])],
+ "admin/*": [allow.groups(["admin"]).to(["read", "write", "delete"])],
createServerRunnerのパラメータを修正
DocではcreateServerRunnerのパラメータが{outputs}となっていますが、{config:outputs}で動作しました。
utils/amplifyServerUtils.ts
import { createServerRunner } from "@aws-amplify/adapter-nextjs";
import outputs from "@/amplify_outputs.json";
export const { runWithAmplifyServerContext } = createServerRunner({
config: outputs,
});
Amplify UIのStorageコンポーネントの呼び出しを修正
Amplify V6、及びAmplify UIも、accessLevelではなく、pathを使うように修正されています。
app/page.tsx
"use client";
import { useEffect, useState } from "react";
import { Amplify } from "aws-amplify";
import type { StorageAccessLevel } from "@aws-amplify/core";
import { getCurrentUser } from "aws-amplify/auth";
import { list, downloadData } from "aws-amplify/storage";
import { StorageImage, StorageManager } from "@aws-amplify/ui-react-storage";
import "@aws-amplify/ui-react/styles.css";
import outputs from "@/amplify_outputs.json";
const ACCESS_LEVEL: string = "admin"
const download = async (key: string) => {
const task = downloadData({
path: ({ identityId }) => `${getPath(identityId, ACCESS_LEVEL)}${key}`
});
const { body } = await task.result;
const blob = new Blob([await body.blob()]);
const link = document.createElement("a");
link.download = key;
link.href = URL.createObjectURL(blob);
link.click();
URL.revokeObjectURL(link.href);
};
const getPath = (identityId: string | undefined, ACCESS_LEVEL: string): string => {
if (ACCESS_LEVEL === "admin") {
return "admin/";
} else if (ACCESS_LEVEL === "protected") {
return `content/${identityId ?? ""}/`;
} else {
return `content/${identityId ?? ""}/`;
}
}
export function App() {
const [user, setUser] = useState("");
const [fileList, setFileList] = useState<string[]>([]);
useEffect(() => {
(async () =>
setUser((await getCurrentUser()).signInDetails?.loginId ?? ""))();
}, []);
useEffect(() => {
(async () => {
const response = await list({
path: ({ identityId }) => getPath(identityId, ACCESS_LEVEL)
})
setFileList(response.items.map((item) => item.path.split("/").pop() ?? ""))
})()
}, []);
return (
<div style={{ padding: "2rem" }}>
<span>{user}</span>
<h2>accessLevel:{ACCESS_LEVEL}(custom)</h2>
<div style={{ margin: "0 2rem" }}>
<StorageManager
acceptedFileTypes={["image/*"]}
path={({ identityId }) => getPath(identityId, ACCESS_LEVEL)}
maxFileCount={1}
/>
</div>
<h2>{ACCESS_LEVEL} file list</h2>
<ul style={{ margin: "0 2rem" }}>
{fileList.map((key, _i) => (
<li key={_i}>
{key}
<button onClick={() => download(key)}>download</button>
<StorageImage
alt={key}
path={({ identityId }) => `${getPath(identityId, ACCESS_LEVEL)}${key}`}
/>
</li>
))}
</ul>
</div>
);
}
export default App;
問題なくストレージアクセスまで完了しました。 amplify v5からv6に変更するほどの手間は無さそうです。
まとめ
Amplify Gen2のGAにより、betaの文字が無くなり、コマンドの変更、設定ファイルの名称変更など、大きな修正が加えられました。
更新された機能についても、細かなアップデートを行っていこうと思います。