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
54
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
21
ChatGPT実践
step63r
1
370
IoT実践! 行先予定表を電子ペーパーで作る
step63r
0
27
React x Socket.ioで人狼サーバを作る 第一章 フロントエンド実装
step63r
0
22
深層強化学習で東方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
製造現場での生成AIの活用、およびエージェントAIの実装のあり方、AVEVAの取り組み
iotcomjpadmin
0
180
Oracle Cloud Infrastructure:2026年6月度サービス・アップデート
oracle4engineer
PRO
1
370
自作お家AIエージェントスタックチャンFWで困っている所紹介
74th
0
110
從觀望到全公司落地:AI Agentic Coding 導入實戰 — 流程整合與安全治理
appleboy
0
160
コミュニティの有益性 ~JAWS Days 2026 での体験を通して~ / The Benefits of a Community ~Through My Experience at JAWS Days 2026~
seike460
PRO
0
300
コミットの「なぜ」を読む
ota1022
0
120
AWS Security Agent といっしょに脅威モデリングをやってみよう
amarelo_n24
1
210
気軽に使える"情報のハブ"としてのNotion活用 〜フロー情報の集積点 と、 Claude Code × Notion AI〜
syucream
1
210
Hatena Engineer Seminar 37 jj1uzh
jj1uzh
0
140
脱SaaS!FDEを支えるプロビジョニングと分離設計
knih
0
300
トークン最適化のためのユーザーストーリー分析 / User Story Analysis for Token Optimization
oomatomo
0
120
本当の”仕事”を手放せる未来が見えた
mu7889yoon
0
190
Featured
See All Featured
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Utilizing Notion as your number one productivity tool
mfonobong
4
330
Thoughts on Productivity
jonyablonski
76
5.2k
Prompt Engineering for Job Search
mfonobong
0
350
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
330
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
740
It's Worth the Effort
3n
188
29k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
220
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.4k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
370
Producing Creativity
orderedlist
PRO
348
40k
How to Ace a Technical Interview
jacobian
281
24k
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