Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
AWSでサーバレスな書籍管理アプリを作る
Search
Ryosuke Uchiyama
May 09, 2025
Technology
69
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
23
ChatGPT実践
step63r
1
400
IoT実践! 行先予定表を電子ペーパーで作る
step63r
0
50
React x Socket.ioで人狼サーバを作る 第一章 フロントエンド実装
step63r
0
35
深層強化学習で東方AI 第一章 DQNの基本
step63r
0
390
Build 2021 プレイバック
step63r
0
44
WPFで実践アプリ開発! 第四章 機能の実装 Part 2
step63r
0
62
WPFで実践アプリ開発! 第三章 機能の実装 Part 1
step63r
0
140
WPFで実践アプリ開発! 第二章 UI
step63r
0
190
Other Decks in Technology
See All in Technology
Kiro Meetup #8 Kiro アップデート (2026/3/21〜2026/9/24)
katzueno
1
310
React Nativeでの OTA Updateって、 どう説明する?
ichiki1023
0
130
プラットフォームを「作る」、 チームに「入り込む」
sansantech
PRO
0
400
高負荷プロダクション環境におけるAWS Lambdaのリアル 〜スケールとコストを左右する実行ライフサイクルの技術仕様〜
maimyyym
2
830
HacobuにおけるFDEとは/登壇資料(戸井田 裕貴)
hacobu
PRO
1
620
OpenClawでAzure DevOpsのWiki更新を自動化する - クラウドAIだけでは届かない場所へ
yutakaosada
0
130
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
16
120k
人にやさしく、AIにやさしく、書き手を選ばないIaCのガードレール再考 / Rethinking IaC Guardrails for Humans and AI Alike
kohbis
5
1.9k
ボードゲームの遊び相手をFoundation Modelsで作る / iOSDC Japan 2026
genda
0
240
The kernel report
ennael
PRO
1
160
【データ横丁主催】AI Agentがコンテキストを使って仕事をした後、何が残るのか― 組織の経験を次の判断に引き継ぐ「Agent Memory」
shisyu_gaku
2
280
IR Today: Theory, Practice, and Agents
dtunkelang
0
270
Featured
See All Featured
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
3.2k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
Designing for humans not robots
tammielis
254
26k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
Google's AI Overviews - The New Search
badams
0
1.6k
ラッコキーワード サービス紹介資料
rakko
1
5.1M
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
2k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
From π to Pie charts
rasagy
1
380
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
530
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