Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
AWSでサーバレスな書籍管理アプリを作る
Search
Ryosuke Uchiyama
May 09, 2025
Technology
58
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
AWSでサーバレスな書籍管理アプリを作る
Ryosuke Uchiyama
May 09, 2025
More Decks by Ryosuke Uchiyama
See All by Ryosuke Uchiyama
PythonでSlack通知botを作る
step63r
0
22
ChatGPT実践
step63r
1
380
IoT実践! 行先予定表を電子ペーパーで作る
step63r
0
31
React x Socket.ioで人狼サーバを作る 第一章 フロントエンド実装
step63r
0
25
深層強化学習で東方AI 第一章 DQNの基本
step63r
0
300
Build 2021 プレイバック
step63r
0
38
WPFで実践アプリ開発! 第四章 機能の実装 Part 2
step63r
0
53
WPFで実践アプリ開発! 第三章 機能の実装 Part 1
step63r
0
130
WPFで実践アプリ開発! 第二章 UI
step63r
0
170
Other Decks in Technology
See All in Technology
SRENEXT_2026_Chairs__Talks_in_Tamachi.sre.pdf
srenext
1
140
『モデル + ハーネス』で読み解く AIエージェント入門
oracle4engineer
PRO
2
160
Network Firewallやっていき!
news_it_enj
0
260
どこまでAIに任せるか 〜確率論と決定論の境界決定〜
shukob
0
440
20260720_クラウド女子会×PyLadiesTokyoコラボ Amazon Bedrock ハンズオン用資料
yuuka51
1
110
複数プロダクトで進めるAI機能実装 ── 実践から得たリアルな学びとロードマップ実現への挑戦 / AICon2026_yanari
rakus_dev
1
270
Playwright × AI Agent でE2Eテストはどう変わるか AI駆動テストの可能性と実用検証の結果
taiga7543
2
780
AI時代のPlaywright活用(システムテストを自動化する ー 実行エンジンにPla ywrightを選んだ理由)
ynisqa1988
2
930
【公開用】AI_Dev_Ex2026_AI_登壇資料
matsuritechnologies
PRO
1
460
CDKで書くECSのベストプラクティス、 改めて考え直す2026 #cdkconf2026
makies
3
930
10年目を迎えた「ABEMA」がどのように AI 活用を推進して、AI 駆動開発にシフトしているのか / How ABEMA, entering its 10th year, is promoting the use of AI and shifting toward AI-driven development
miyukki
0
370
設計レビューとAIハーネスで向き合う AIが生み出した新しいボトルネックの対処法 / Design Reviews and AI Harnesses Against New Bottlenecks Created by AI
nstock
4
420
Featured
See All Featured
SEO for Brand Visibility & Recognition
aleyda
0
4.6k
YesSQL, Process and Tooling at Scale
rocio
174
15k
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
180
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.9k
Unsuck your backbone
ammeep
672
58k
The Language of Interfaces
destraynor
162
27k
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
300
The Invisible Side of Design
smashingmag
301
52k
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Transcript
AWSでサーバレスな 書籍管理アプリを作る Ryosuke UCHIYAMA
はじめに © 2025 minato project. 2
実現したかったこと • 持っている書籍をデータベース管理にする • カメラで読み取るなどできるだけ簡易な方法で登録できる • 読み取った書籍が所有済みであるかをチェックする • 登録した書籍の情報を閲覧、編集できる •
書籍の貸出・返却管理を行う(将来的実装) © 2025 minato project. 3
つくったもの © 2025 minato project. 4 https://sbms.minatoproject.com/
ソースコード © 2025 minato project. 5 step63r/sam-ayano https://github.com/step63r/sam-ayano
システム構成図 © 2025 minato project. 6
システムイメージ © 2025 minato project. 7
Demo © 2025 minato project. 8
実装ハイライト © 2025 minato project. 9
アカウント作成、ログイン機能 © 2025 minato project. 10 AWS Amplify UI Componentsを活用し簡易的な実装とした
root.render( <> <CssBaseline /> <Authenticator.Provider> <LoadingProvider> <App /> </LoadingProvider> </Authenticator.Provider> </> ) index.tsx 32 33 34 35 36 37 38 39 40 41 const Settings: React.FC = () => { const navigate = useNavigate(); const { user, signOut } = useAuthenticator((context) => [context.user]); const [disabled, setDisabled] = useState(false); ... }; Settings.tsx 17 18 19 20 ... 59
キャリアメール対応 © 2025 minato project. 11 Amazon SES設定とDKIMのDNS登録に加え、DMARC準拠の設定が必要だった
なぜキャリアメールへのメールが届かないのか? © 2025 minato project. 12 結論 キャリアが送信ドメイン認証を行っていたから 送信ドメイン認証とは なりすましメールや迷惑メールへの対策として、送信元のIPアドレスとDNSサーバに公開された送信用メールサーバのIPアドレ
スが一致しているかを確認すること。送信元のIPアドレスの確認には、メールヘッダーに含まれるFromフィールドが利用され ている。キャリアにメールを送信するにはDMARCに準拠する必要がある。 DMARCとは SPFやDKIMの認証が失敗した場合の対 応策を定めたもの。送信側は受信側の 認証失敗時の推奨アクションをDNSに 「DMARCポリシー」として宣言してお き、受信側は認証失敗時にこのDMARC ポリシーを参照して、受信メールをど う扱うか判断する。 SPFとは IPアドレスを利用して受信したメール の送信元が詐称されていないかを確認 する。メール送信時に利用するサーバ のIPアドレスを送信側のDNSに「SPF レコード」として事前に登録。受信側 はメール受信時に送信側のSPFレコー ドと照合し、なりすましかどうかを判 断する。 DKIMとは 電子署名を利用してメール送信元が詐 称されていないかを確認する。送信側 がメールに電子署名を付与し、受信側 はそれをメール受信時に検証すること で、なりすましやメールの改ざんを検 知する。
SPFの仕組み © 2025 minato project. 13
DKIMの仕組み © 2025 minato project. 14
DMARCの仕組み © 2025 minato project. 15
バーコード読取 © 2025 minato project. 16 書籍JANコードを読み捨ててISBNだけ取るようにした const handleScan =
useCallback(async (results: IDetectedBarcode[]) => { setIsLoadingOverlay(true); if (results.length > 0) { for (const item of results) { if (item.rawValue.startsWith("978") || item.rawValue.startsWith("979")) { ... } } } setIsLoadingOverlay(false); }, [getBooksAsync, checkExists, navigate, setIsLoadingOverlay, searchOpenBdAsync]); ReadBarcode.tsx 113 114 115 116 117 118 ... 145 146 147 148 149 150
書籍情報の取得、登録 © 2025 minato project. 17 openBDのAPIで書籍情報を取得するようにした try { await
axios.get(url) .then(r => { console.log("response", r); if (r.data.length === 1) { response = createResponse(200, r.data[0]); } else { response = createResponse(500, { message: "検索結果が1件ではありませんでした。" }); } }); } catch (error) { console.log("error", error); response = createResponse(500, error); } search-openbd/app.mjs 32 33 34 35 36 37 38 39 40 41 42 43 44 45
書籍情報の検索、一覧取得 © 2025 minato project. 18 キーワード入力のイベント抑止 (debounce) とフィルタ対応 const
[debouncedKeyword] = useDebounce(keyword, 500); ... const result = await getBooksAsync({ pageSize: PAGE_SIZE, lastEvaluatedKey: undefined, keyword: debouncedKeyword, sortKeyId: sortKeyId, desc: isDesc, }); Books.tsx 89 ... 174 175 176 177 178 179 180 // 取得件数がpageSizeに到達するまでQueryし続ける while (currentLength < pageSize) { ... } ... // 取得結果がpageSizeより多い場合はスライスする if (items.length > pageSize) { items = items.slice(0, pageSize); currentLastEvaluatedKey.username = userName; currentLastEvaluatedKey.seqno = items[items.length - 1].seqno; } get-books/app.mjs 84 85 ... 103 ... 105 106 107 108 109 110
APIGWにCognito認証を追加する © 2025 minato project. 19 OPTIONSに認証設定を入れてはいけない(戒め) Resources: ... ApiGateway:
Type: AWS::Serverless::Api Properties: ... Auth: DefaultAuthorizer: CognitoAuthorizer AddDefaultAuthorizerToCorsPreflight: false Authorizers: CognitoAuthorizer: UserPoolArn: arn:aws:cognito-idp:... template.yaml 22 ... 72 73 74 ... 87 88 89 90 91 92 const session = await fetchAuthSession(); const token = session?.tokens?.idToken.toString(); const options = { 'headers': { 'Content-Type': 'application/json', 'Authorization': token, }, }; TypeScript
残課題 • 異常系の強化 • openBDにデータがない場合に他サービスへの問い合わせ • サブスクリプション対応 • バーコード読み取りのライブラリ、他に良いのないか •
UI改善 © 2025 minato project. 20
参考資料 • QR コードスキャンライブラリ @yudiel/react-qr-scanner で IScannerComponents を設定してスキャン時の UI をカスタマイズしてみた
| DevelopersIO • Authenticator | Amplify UI for React • 【React開発】処理待機中に画面全体を覆うオシャレなローディング画面を表示させる方法! #個人開発 - Qiita • Amazon Cognito からキャリアのアドレスにメールを送信するためにやったこと #AWS - Qiita • 送信ドメイン認証(SPF / DKIM / DMARC)の仕組みと、なりすましメール対策への活用法を徹底解説 – エン タープライズIT [COLUMNS] • API GatewayのOPTIONSメソッド(CORS)でAPIキーを不要にする(AWS SAM) | DevelopersIO © 2025 minato project. 21