KINTOテクノロゞヌズのブログ - TECH PLAY

TECH PLAY

KINTOテクノロゞヌズ

KINTOテクノロゞヌズ の技術ブログ

å…š991ä»¶

こんにちは、Engineering Office  もずい、技術広報グルヌプのemimです。 䞻業務はEngineering Officeのデザむナヌなのですが、瀟倖亀流や瀟内の勉匷䌚、さらに今回のようなむベント出展にお技術広報メンバヌの手を煩わせる機䌚が倚くなりそうだな  ずいう詊算から、少し前から技術広報チヌムの䞀員ずしおも掻動しおいたす。 この蚘事は、 KINTOテクノロゞヌズ Advent Calendar 2025 の18日目の蚘事ずしお執筆しおいたす。 今回は、銖題のずおり、アクセシビリティカンファレンス犏岡2025にKINTOテクノロゞヌズ株匏䌚瀟以䞋KTCが「おや぀スポンサヌ」ずしお協賛したので、そのレポヌトを行いたす。 アクセシビリティカンファレンス犏岡ずは https://fukuoka.a11yconf.net/ アクセシビリティカンファレンス犏岡は、2023幎より毎幎犏岡で開催されおいる「アクセシビリティ」をテヌマずしたカンファレンスです。今幎で3回目の開催です。私は過去2回も珟地で参加しおいたす。 犏岡から始たった地方カンファレンスですが、これたで賛同者による掟生版ずしお、名叀屋愛知、石川、千葉など他地方でも開催されおいたす。「アクセシビリティカンファレンス」は衚蚘も発話も長いので、いずれの堎合でも略しお「アッカン」ず衚されたす。 さお、アクセシビリティずは、誰もがどんな状況にあっおも容易に利甚・参加できる状態や仕組み、及びその状態利甚可胜性のこずを指す蚀葉です。物理的な環境や情報、サヌビスなど、さたざたな面で誰もが平等にアクセスできるこずを意味し、特に゜フトりェア分野では最䜎限の品質の閟倀ずしお捉えおも霟霬はないでしょう。 そのため、アクセシビリティぞの興味関心の高いあらゆる職皮の方は、総じお、高いスキルず感床を持ち合わせおいるず個人的に考えおいたす。 話をKTCに戻すず、今幎はたたたた圓瀟の 犏岡オフィスの開所が決たった 幎でした。そこで、そんなに意識の高い方たちの集たるカンファレンスが、タむミングよく犏岡で開催されるならばず採甚ずKTCの感床の高さアピヌルを目的に、なんらかスポンサヌができないか、ず考えたのが始たりです。 そうは蚀っおも、KTCでの具䜓的なアクセシビリティに関する取り組みはただほずんどありたせん。 過去2回の参加経隓から、 䌚堎参加者の印象に残りやすい 䌚堎で䞀定の亀流ができる 展瀺物や具䜓の成果アピヌルが必ずしも必芁ではない ずいう3点をカバヌできる「おや぀スポンサヌ」がKTCには適しおいるず考え、前のめり気味で応募したした。 おや぀スポンサヌの内容 おや぀   参加されおいない方には䜕も䌝わらないですよね。かくいう圓瀟でも、このゆるふわなスポンサヌ区分名に぀いお「これでは嚁厳期埅倀が薄れお申請が通らないかもしれない」ずいう懞念が䞊がり、内郚的な申請の際に暪文字な名称でカモフラヌゞュされたずかなんずか   個人的には、これがずおもアッカンらしいナヌモラスな名称でいいな、ず感じおいたす。 具䜓的なおや぀スポンサヌの圹割は、クッキヌずコヌヒヌ及びアッカン公匏チロルチョコを食べ攟題飲み攟題の圢で提䟛する、ブヌスぞのスポンサヌです。ブヌスで担圓者がクッキヌやコヌヒヌを提䟛する぀いでに、自瀟の事業内容などをアピヌルする機䌚を埗られたす。 この軜食サヌビスは、カンファレンスの最初の開催の2023幎圓初から提䟛されおいたす。 他のカンファレンスに比べ、アッカンでは色々な障害がある人でも「ここにいる。^[「ここにいる。」ずは、アクセシビリティカンファレンス犏岡2023のテヌマでした。]」こずが圓たり前の䞖界です。長時間同じ姿勢がしんどいような方や、ずっず同じ所に居続けるこずに䞍安のある方もいるかもしれたせん。䌚堎内には蚗児所などもあるので、子䟛の声も聞こえおいたした。そんな方々でもカンファレンスを楜しめるように、各セッションの時間が短めだったり、䌑憩時間が長めだったりずいう工倫がなされおいたす。 そこにマッチするのが、コヌヒヌ^[䞭にはコヌヒヌが苊手な方もいらっしゃったようで、提䟛はコヌヒヌだけなので少し窮屈な思いをさせおしたったようです。]ずクッキヌです。甘いものず苊いもので、疲れた脳ず心を癒やしおくれたす。䌚堎のみの提䟛ずなっおしたいたすが、参加者が長䞁堎のカンファレンスで疲れないように配慮されたサヌビスです。 昚幎たではアむシングクッキヌが配られおいたしたが、今幎はシンプルなクッキヌに垌望の図柄のプリントされたクッキヌに倉曎ずなっおいたした。 埌日、隣垭の同僚が「なんだ〜、アむシングの方がいいじゃん  っお最初思ったけど高玚クッキヌじゃん」ず小躍りしたクッキヌです。 コヌヒヌは、犏岡で有名な REC COFFEE ずスタヌバックスのものがサヌバヌで甚意されたした。 カンファレンスの様子ず前倜祭の様子 前倜祭に぀いお カンファレンスの前日倜には、LINEダフヌさんの博倚オフィスにお、 アクセシビリティカンファレンス犏岡 前倜祭 が開催されおいたした。 私は別件の予定があり䞍参加だったのですが、圓瀟からは 11月からゞョむンした蟻 がLTで登壇し、スクリヌンリヌダヌの NVDA を甚いおKindleの曞籍を読む方法「『聎く』読曞から『読む』読曞ぞ」ずいう副題が添えられおいたすが玹介された他、犏岡オフィスのメンバヌなどが聎講者ずしお参加をしたした。蟻に぀いおは、転職の蚘事が公開されおいない時期だったこずもあり、䌚堎でざわめきを䜜ったず聞いおいたす。 さらに埌から聞いた感想では、自称アクセシビリティ初心者な人たちでも「自分にもできるかもしれない」ずなれるような、代替テキストに぀いおなどの話題提䟛が心に残ったそうです。圓瀟の参加メンバヌから、圓日犏岡にいなかったチヌムメンバヌにも「ぜひ聞いおほしかった」ずの声を聞きたした。 カンファレンス圓日に぀いお カンファレンス圓日は、開堎より少し早めに䌚堎入りをしおブヌス蚭営などを行いたした。我々は他のカンファレンスなどでも利甚する、KINTOのキャラクタヌである「 くもびぃ 」ずずもにブヌスに立ちたした。 ちなみに、アッカンは他のカンファレンスやセミナヌに比べお、運営メンバヌにも参加者にも女性が倚い印象です。ブヌスに来おくれる方々も、すれ違う方々も、開堎前のアッカン犏岡実行委員䌚やボランティアスタッフなど、ずにかく倚くの方から「かわいい〜」ずいう声を聞けたのが嬉しかったです。 スポンサヌブヌス゚リアは本䌚堎ず別ながらも、倧きなスクリヌンずクリアな音声スピヌカヌで、カンファレンス本線の内容がサテラむト攟映されおいたした。スポンサヌブヌスにずっずいたずしおも、講挔内容が楜しめるようになっおいたす。 KTCブヌスでは、前日にLTを行った蟻も端にずっず居お、普段利甚しおいるスクリヌンリヌダヌや点字ディスプレむを利甚し、デモの披露など行っおいたした。途䞭、カンファレンスの手話通蚳の方が「芖芚障害者がどのように情報を受け取られおいるのか」ず話しを聞きにきおくれたり、聎芚障害の方も点字ディスプレむの様子を芋に来おくれたりしたそうです。 他のむベントではスポンサヌブヌスに居るず、なかなかカンファレンス本線を楜しめなかったりするのですが、その蟺りもみんなで楜しめるように蚈算されおいるように感じたす。「お客さんず楜しむ」だけではないこずが幞いし、スポンサヌブヌスにいただけでも孊びの倚かったKTCスタッフは「せっかくなら、アクセシビリティに興味のあるメンバヌも参加できたらよかった 次回はぜひ」ず話しおいたした。 たた、珟地ではカンファレンスの埌に懇芪䌚も開催されたした。KTC犏岡のスタッフ陣が、熱冷めやらぬたた犏岡の各瀟の方々ず情報亀換を行い「匕き続き勉匷䌚などを開催したしょう」ず意気投合したず聞いおいたす。倧倉楜しみです。 この蚘事では本線の様子に党然觊れられおいないのですが、前倜祭ず圓日のXの様子が公匏にたずめられおいたす。圓日Xでは、ハッシュタグ付きポストの倚さからか床々「本日のニュヌス」に取り䞊げられたりしおいたした。少しでも盛り䞊がりを感じたい方は、以䞋のたずめをご芧ください。 https://posfie.com/@FukuokaA11yconf/p/OD58dzG 埌日アヌカむブも公開されるそうです。 https://x.com/FukuokaA11yconf/status/1997858020148330885?s=20 アクセシビリティカンファレンス犏岡実行員䌚の皆様及び、ご登壇の皆様、のみならず各スポンサヌブヌスの方々、オフラむンオンラむンの各参加者の皆様、お疲れ様でした。そしお亀流くださっお、ありがずうございたす。たた来幎も開催が予告されたアッカン犏岡に参加できるこずを楜しみにしおいたす。 おたけレポヌトブヌス出展に䌎う制䜜物 今回、ブヌスでの配垃物にくもびぃの玙クリップを甚意したした。過去、別の機䌚でも配垃しおいたノベルティです。せっかくなので觊っお圢のわかっおもらえるもの、そしお䜿えそうなもの、か぀お菓子ずいっしょにもらっおも困らないサむズのもの、ずいうこずで遞びたした。この「觊っおわかる」ずいう点は奜評でした。 さらに、スタッフずしお参加しおいないのに「これがあるず『今日䌚堎に来おいるのはこの人』っお説明ができるんです」ず参加スタッフのアクスタアクリルスタンドを ゆかちさん が䜜っおくれたした。たさかのアクスタデビュヌです。 土台の郚分にはNFCタグが組み蟌たれおおり、個々人のSNSに繋がっおいたりしたす。これが意倖にも奜評で、他瀟の広報チヌムでも「真䌌したい」ずいう意芋をもらいたした。 ちなみに蟻に「芖芚障害の堎合は、名刺をもらうよりもNFCの方が䟿利ですか」ず事前に確認をしたずころ、「䌚堎うるさい所で忙しくNFCで操䜜するよりも、家に垰っおから名刺を改めお確認できる方がいいように思いたす」ずの意芋をもらいたした。なるほど。 今回ブヌスにいたメンバヌは、SNS䞊でアむコンの方が知られおいる人も倚かったです。そのため「この人だよ」ず玹介をするのにもアクスタが圹立った、ずいうポむントも補足しおおきたす。
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の18日目の蚘事です🎅🎄 はじめに KINTOテクノロゞヌズのクリ゚むティブグルヌプ所属の犏田です。 Osaka Tech Lab に所属しおいたす。 トペタグルヌプ内コミュニティ「TURTLE」にお、2025幎4月にデザむン分科䌚を蚭立したした。 アンバサダヌずしお分科䌚の勉匷䌚䌁画・運営に携わったので、振り返りず今埌の意気蟌みをたずめたす。 TURTLEずは TURTLEToyota cloud UseR TechnicaL alliancEは、トペタグルヌプのクラりド技術に関する゚ンゞニアが集たり、知芋を共有するために蚭立されたコミュニティです。 「瀟倖コミュニティでは話せないこずが倚く、参加しづらい」「瀟内にむンプット・アりトプットの堎がない」「同じものを耇数瀟で開発しおいるのはもったいない」 こうした珟堎の声を背景に、トペタグルヌプずしお゚ンゞニアのコミュニティをみんなで䜜ろうずいう想いから誕生したした。 なぜデザむン分科䌚なのか 近幎、ビゞネスにおけるデザむンの重芁性は急速に高たっおいたす。 デザむンは単なる芋た目の矎しさを超え、ナヌザヌ䜓隓やブランド構築、サヌビスの䜿いやすさにたで圱響を及がし、䌁業掻動の前線に立぀存圚ずなっおいたす。 しかし、私が所属するクリ゚むティブグルヌプでは、トペタグルヌプ内でデザむンに関する知芋やノりハりを共有できる堎がほずんどありたせんでした。 特に、デザむンに関連する事䟋や成果物には瀟内専甚の情報が倚く、瀟倖コミュニティでは安心しお話すこずが難しい状況もありたした。 こうした背景から、Osaka Tech Labに所属し、TURTLEの他分科䌚で䌁画・運営を担っおいるアンバサダヌに盞談したした。 その結果、グルヌプ暪断でデザむン領域の知芋を共有できる堎の必芁性を再認識し、TURTLE事務局に盞談した埌、2025幎4月に『デザむン分科䌚』が正匏承認されたした。 分科䌚蚭立たでの流れ 2025幎2月 TURTLE総䌚で蚭立準備䞭の案内 デザむン分科䌚の勉匷䌚䌁画・運営を共に担うアンバサダヌ募集開始 2025幎3月 デザむン分科䌚アンバサダヌのキックオフMTG開催 分科䌚蚭立申請 2025幎4月 デザむン分科䌚蚭立が事務局にお正匏承認 2025幎2月のTURTLE総䌚での案内時の写真です。この開蚭準備発衚がきっかけでトペタグルヌプ他瀟のアンバサダヌの仲間を集めるこずができたした。 掻動実瞟2025幎4月9月 蚭立圓初、デザむン分科䌚には2瀟から6名のアンバサダヌが参加し、隔週で定䟋䌚を開きながら情報共有ず関係構築に努めおきたした。 勉匷䌚開催 半幎間でオンラむン勉匷䌚を2回実斜し、質疑応答や投祚など参加型コンテンツを簡単に䜜成できるむンタラクションツヌル「 slido 」や、チヌムでのアむデア出しや共同䜜業をスムヌズに行えるオンラむンホワむトボヌドツヌル「 FigJam 」を掻甚するこずで、オンラむンでも双方向のコミュニケヌションを重芖した勉匷䌚を実珟しおいたす。 第1回「コヌポレヌトサむトのリニュヌアル」 コンセプトの重芁性やデザむンプロセスを共有 第2回「デザむンシステム導入ずFigma運甚の最適化」 実践的なツヌル掻甚法を玹介 たずめ 2025幎12月時点で、デザむン分科䌚の参加䌁業数は30瀟、参加者数は179名に達しおいたす。 明日2025幎12月19日には第3回勉匷䌚「UX入門勉匷䌚」の開催も予定しおいたす。 珟圚、アンバサダヌの構成は2瀟7名による運営です。 今埌もグルヌプ党䜓でデザむンに関する知芋やノりハりを共有し、新たなグルヌプ䌚瀟からのアンバサダヌの仲間集めにも取り組み、孊びの倚い堎を目指したす。 デザむン分科䌚は「デザむンをビゞネスの前線に」ずいうビゞョンのもず、トペタグルヌプ党䜓でのデザむナヌ同士の知芋共有を加速させ、より良いナヌザヌ䜓隓の創出を目指しお掻動を続けおいきたす。 最埌たで読んでいただき、ありがずうございたした
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の17日目の蚘事です🎅🎄 Engineering OfficeのNaitoです。KINTOテクノロゞヌズ以䞋、KTCには4぀の2025幎泚力テヌマむンテンシティ、AIファヌスト、ナヌザヌファヌスト、リリヌスファヌストがありたす。 以前のブログ で2025幎泚力テヌマの1぀、リリヌスファヌストに぀いおお䌝えしたした。 今回はリリヌスファヌストにた぀わるこの1幎の取り組みや倉化に぀いお玹介したす。 最初に認識合わせをしおおくず、KTCではリリヌスファヌストは、「アむディア創出からリリヌスたでの期間を短くし、ナヌザヌ・顧客に早く䟡倀を提䟛する」ずしおいたす。 2025幎1月〜3月 Engineering Officeが立ち䞊がりたした。 メンバヌは ahomu ず私圓時入瀟3ヶ月の2人です。 Findy Team+の導入・掻甚支揎ずいう切り口で開発チヌムずの察話を通し、各チヌムの状況やメンバヌのこずを知り始めた状態で、その結果わかったこずは以䞋のようなこずでした。 自分たちの珟状を定量的に把握できおいるのは䞀郚のチヌムにずどたっおいる Findy Team+を導入したが、うたく蚈枬・可芖化できないチヌムもある Findy Team+の1機胜である、プロセスタむム分析JiraをINPUTずしお各工皋ごずのリヌドタむムの蚈枬・可芖化ができるチヌムはれロ 開発パフォヌマンスの蚈枬・可芖化に取り組んでいるチヌムにおいおも䞀郚の人で蚈枬デヌタを芋お詊行錯誀しながら、改善掻動に取り組んでいる。チヌム党䜓には広がっおいない 蚈枬・可芖化に関心があっおも先行しおいるチヌムがどんな状況なのかはわからず、情報収集ができない 珟圚2025幎末 Engineering Officeはなんず4名に増えたした。それぞれの専門領域を最倧限発揮し぀぀、コラボレヌションしおチヌムで掻動しおいたす。 「䞀緒にやろう」ず耇数チヌムから声をかけおいただきありがたい、私たちはこの1幎間で玄20チヌムに関わらせおいただきたした。 各チヌムは、 泚力テヌマに玐づいた目暙を蚭定し、取り組んでいる リリヌスファヌストの第䞀歩は自分たちの珟状を定量的に定性的に把握するこずからずいう意識が党瀟に広がっおおり、瀟内の䞻なプロダクト、開発チヌムはFindy Team+を導入しお開発パフォヌマンスの蚈枬を行っおいる Findy Team+ではFour Keysに぀いおは党チヌムが蚈枬可胜な状態になっおいる Findy Team+を芋お話し合うこずがチヌム党䜓に広がっおいるずころも増え、改善事䟋が少しず぀共有されおいる Findy Team+の1機胜である、プロセスタむム分析JiraをINPUTずしお各工皋ごずのリヌドタむムは3プロダクトが蚈枬できおいる チヌムを超えたリリヌスファヌストのタスクフォヌスが発足し、業務のかたわら、プロダクト暪断でリリヌスファヌストを実珟するための仕組みづくりを実斜䞭 ある郚門では郚門党䜓で圹割分担や開発プロセスを芋盎し、圹割間・チヌム間のコラボレヌションを匷化䞭 チヌムのレビュヌプロセスを芋盎した結果、レビュヌ時間が向䞊した事䟋 この倉化がどうやっお起こったのか正盎、各チヌムの頑匵りの賜物なわけですが。Engineering Office暪軞組織から芋た目線でお䌝えしおいきたいずおもいたす。 泚力テヌマを理解する 各プロダクトにおいおは泚力テヌマの意味はなんずなくわかるけど具䜓的にどういうこずずいうのが圓時の状況でした。 そのため、最初の2−3ヶ月は掚進メンバヌ党員で泚力テヌマに぀いお瀟内に浞透させるずころから始たりたした。 たずは瀟内で蚀葉の認識合わせを行い、「なぜこれがいたKTCにずっお倧事なのか」たた「リリヌス期間だけ短くなればよいずいうこずではなく、ナヌザヌ・顧客に向き合い、䟡倀を提䟛するこずに意味がある」「ナヌザヌファヌストをないがしろにしおリリヌスを優先しおも技術的負債になっおしたう」ずいうこずを䌝える掻動を続けたした。 プロダクトやチヌムごずに自分たちにずっおのリリヌスファヌストを考える 泚力テヌマに぀いお各人が理解するず、次はプロダクトごず、チヌムごずに自分たちは泚力テヌマを実珟するために䜕をしたらいいのか自分たちの珟状っおどんな感じなのかずいうこずが話し合われたした。 各方面で泚力テヌマに぀いお考えた結果、私のずころにも以䞋のような声が届いおきたした。 リリヌスが早くなったかどうかBefore/Afterをわかるようにしたい AIを掻甚しお実装スピヌドあげたい リリヌスたでの流れっおどうなっおいるのか 統合テストに時間かかっおいる ナヌザヌが遠くお䟡倀が届いおいるのかわからない 蚭蚈・実装より前のフェヌズにボトルネックがあるように思うが蚈枬できおいない 自チヌムだけでは前に進めるのは難しい。関係者で集たっお話し合いたい こういった課題感共有や話し合いを経お、プロダクトやチヌムで泚力テヌマを実珟するための自分たちのチヌムの目暙を定めおいきたした。 取り組み 以䞋はリリヌスファヌストに関する取り組みの䞀郚です。耇数のチヌムで同様の取り組みをしおいるケヌスもありたす。 なぜ開発パフォヌマンスを蚈枬するのかずFindy Team+導入の説明䌚 GitHubのブランチ戊略・運甚ルヌル倉曎 PRレビュヌプロセスの改善 Findy Team+を芋合う䌚 チヌムのケむパビリティの可芖化 Jiraを䜿った工皋ごずのリヌドタむムの蚈枬そのためにJiraの運甚ルヌル芋盎し 党瀟暪断でのAI利掻甚状況の蚈枬・可芖化 Value Streamの可芖化 郚門党䜓でのValue Streamの改善 アゞャむルトレヌニングの実斜 ナヌザヌ芖点で芁求を敎理し、PRDを䜜成するワヌクの実斜 プロダクト毎のテスト環境構築 むンシデント察応プロセス改善 テストデヌタ䜜成方法の芋盎し Techラりンドテヌブルチヌム間の情報共有 トペタ生産方匏勉匷䌚入門線 ここに挙げたのは私が関わった取り組みだけですので、瀟内には他にもたくさんの取り組みがありたす。 ボトルネックを特定し、Value Streamを改善した事䟋 Techラりンドテヌブル @Osaka Tech Lab たずめ 䞊蚘のような取り組みを1幎間繰り返し続けおきた結果が冒頭のような倉化に繋がっおいたす。 圓初のリリヌスファヌストの目暙を実珟しおいるチヌムもただ途䞭のチヌムもいたすが、どのチヌムも自分たちの行動で起きた倉化は実感しおいるこずずおもいたす。 瀟内の颚土ずしおボトムアップで様々なこずが進むこずが倚いです。そのため、今回の泚力テヌマの各取り組みにおいおもたずは自分のチヌムの範囲でやっおみようずいう圢で始たるこずが倧半でした。 䞀方で、KTCのプロダクトは耇数のチヌムで構成されおいるこずが倚いです。リリヌスファヌストやナヌザヌファヌストを実珟するためには、プロダクト党䜓を俯瞰する芖点が欠かせたせん。 自チヌムが敎うず、自然ずメンバヌの芖野も広がりより広い範囲に目を向けるようになりたす。そのため、2025幎埌半にはチヌムを超えた「リリヌスファヌスト」の取り組みが増えおきたした。 チヌムを超えるず郚門が異なる人や他の圹割の人たちず課題を共有し、目線合わせをしおいく必芁があるのですが、専門領域や圹割の違いにより芋えおいるもの感じおいるものが異なる堎合も倚く、ゎヌル蚭定や進め方で躓くこずも倚いです。 このような時にはビゞネス・技術・プロセスを統合しお芋えおいるマネヌゞャヌのアドバむスや方向性づけ、刀断ずいうのがずおも倧事になりたす。 それによりチヌムを超えた様々な関係者がたずたり、取り組みが加速するずいうの目の圓たりにしおいたす。 今幎の倉化が成果ずなっお衚れるのが来幎です。来幎、リリヌスファヌスト・ナヌザヌファヌストの掻動を加速させ、より倚くの成果に結び぀けおいくためにはマネヌゞャヌの関䞎は䞍可欠です。 本圓の意味でリリヌスファヌストを実珟するプロダクトがどれだけ増えるのか今からずおも楜しみです。 リリヌスファヌスト、ナヌザヌファヌストは䞀幎で終わる話ではありたせん。プロダクト開発に携わる以䞊は継続的に取り組んでいくテヌマです。 Engineering Officeは来幎も匕き続き各チヌムずずもにリリヌスファヌスト、ナヌザヌファヌストに取り組んでいきたす。 お知らせ Regional Scrum Gathering Tokyo 2026 のDay11/7に出たす。具䜓の取り組みのいくかに぀いお話す予定です。みなさんよかったら芋に来おくださいね。 「リリヌスファヌスト」の実感を届けるには〜停滞するチヌムに倉化を起こすアプロヌチ〜
この蚘事は KINTOテクノロゞヌズアドベントカレンダヌ2025 の17日目の蚘事です🎅🎄 1.はじめに こんにちは KINTOテクノロゞヌズのデゞタル戊略郚DataOpsG所属の䞊平です。 普段は瀟内のデヌタ分析基盀ず「cirro」ずいうAIを掻甚した瀟内アプリの開発・保守・運甚を担圓しおいたす。 以前、䞋蚘の蚘事で、Strands Agentsの導入前の怜蚌事䟋をご玹介させおいただきたした。 https://blog.kinto-technologies.com/posts/2025-07-18-try-strands-agent/ 圓時より発展し、珟圚「cirro」はAmazon Bedrock × Strands Agentsずいう構成になっおいたす。 本蚘事では、「cirro」にStrands Agentsを利甚し、GA4ぞの問い合わせ画面を構築した事䟋を玹介したす。 2.本蚘事の察象者 本蚘事は、Amazon BedrockをConverse APIやInvoke Model経由で利甚した経隓があり、 Strands Agents等゚ヌゞェント開発SDKぞの切り替えを迷っおいる方が察象ずなりたす。 3.GA4ぞの問い合わせ画面構築の背景、抂芁 3.1.背景 GA4 (Google Analytics 4) は、Webサむトやアプリに 「誰が」「どこから来お」「䜕をしたか」 ずいう、 蚪問者のアクセス状況を分析できる非垞に䟿利なサヌビスです。 しかし、その分析できる項目の皮類があたりにも倚いため、 初めお䜿う方にずっおは、どこを芋たらいいのか、どうデヌタを読み解けばいいのか、かなり難しいです。 GA4のデヌタは、䞻に次の2皮類の芁玠で構成されおいたす。 ディメンションデヌタを分類したり切り口ずしたりする「属性」を瀺す項目です。 「どこから」アクセスしたか䟋Google怜玢、Twitterなど 「どの囜・地域」から来たか 「どのペヌゞ」を芋たか 「どんなデバむス」を䜿ったか䟋スマヌトフォン、PC メトリクス具䜓的な量や頻床を衚す「数倀」を瀺す項目です。 Webサむトぞのアクセス数セッション数 特定のペヌゞが衚瀺された回数衚瀺回数 ナヌザヌがサむトに滞圚した時間 サむトを蚪れたナヌザヌの数 これらのディメンションやメトリクスの項目が200項目・300項目の芏暡で存圚するため、 慣れおいないず欲しい情報にたどり着くこず自䜓が課題です。 Google公開資料アナリティクスのディメンションず指暙 この課題に぀いお、䟋えば「今週のアクティブナヌザ数が知りたい」「アクセス数が倚いペヌゞは」等、 自然蚀語で問い合わせできるようになれば、サむトやアプリの管理者が簡単に傟向を芋るこずができ 改善に圹立぀のでは ず構築に着手したした。 3.2.抂芁 GA4ぞの問い合わせ画面は、よくあるシンプルなチャット画面です。 以䞋の流れでナヌザの問い合わせに察し、GA4の内容を応答したす。 ナヌザの問い合わせを入力 AIがGA4のAPIから珟圚有効なディメンションずメトリクスの䞀芧を取埗 AIが適したディメンションずメトリクスを遞択し、GA4ぞ問い合わせる GA4の結果をAI偎で衚瀺甚の圢匏に倉換し、回答を出力 シンプルですが、ナヌザはディメンションやメトリクスを把握せずずもAIを介しおGA4のデヌタにアクセスできたす。 初心者には単玔にデヌタアクセスの補助ずしお、 ディメンションやメトリクスを党お把握しおいない䞭玚者の方には、 どの項目で必芁なデヌタが取埗できそうかの圓たりを぀けるこずに圹立ちたす。 4.芁玠技術・アヌキテクチャの玹介 ここからは、「GA4ぞの問い合わせ画面」を構築時に䜿甚した芁玠技術やアヌキテクチャをご玹介しおいきたす。 4.1.Strands Agentsずは 2025幎5月16日にAWS Open Source Blogで公開されたオヌプン゜ヌスのAI゚ヌゞェントSDKです。 以䞋は、AWSのAmazon Web Services ブログで公開されおいる図です。 図のように、ツヌルを備えたAIを実装するには、Agentic Loopず呌ばれるルヌプ凊理が必芁です。 この凊理では、AIの応答がナヌザヌぞの回答なのか、ツヌルを䜿っおさらに凊理を進めるべきかを刀断したす。 Strands Agentsを䜿えば、このルヌプ凊理を開発者が自前で実装するこずなく、AI゚ヌゞェントを構築できたす。 参考、図の出兞Strands Agents – オヌプン゜ヌス AI ゚ヌゞェント SDK の玹介 4.2.cirroっおどんなサヌビス 私の所属するDataOpsGでは䞋蚘ミッションを目的に掻動しおいたす。 「党瀟のデヌタを分析甚に敎備、AI-Readyなデヌタ分析基盀を提䟛するこずでデヌタドリブンな意思決定を支揎する」 AIは、非゚ンゞニアでも容易にデヌタにアクセスするための入り口ずしお泚目しおおり、 cirroはDataOpsGで独自に開発・運甚しおいる生成AIの掻甚基盀です。 UI等可胜な限り共通化し、チャットや問い合わせ画面のような画面構成であれば、 プロンプトず参照デヌタの远加のみで 金倪郎风的に量産できる構成ずなっおいたす。 図のように、①UIコンピュヌティング機胜ず、②システムプロンプトや参照デヌタを分離し、 ②を切り替えるこずで1぀のシステムで耇数のAIの機胜を実珟しおいたす。 たた、URLパラメヌタで䜿甚するツヌルを指定するこずができ、ツヌルを持ったAI゚ヌゞェントずしお皌働するこずも可胜です。 今回はこの機胜を利甚し、cirroでGA4ぞの問い合わせ画面を構築したした。 4.3.GA4の問い合わせ甚のツヌル Googleが公開する2぀のAPIをStrands Agentsが䜿甚するツヌルずしおラップし構築したした。 cirroはツヌルを䜿甚しお、「利甚できるディメンションずメトリクスの取埗」ず「ナヌザの質問に合ったデヌタをGA4から取埗」を実珟しおいたす。 4.3.1.getMetadata GA4で䜿甚できるメトリクスずディメンションを取埗するAPI getMetadata詳现 4.3.2.runReport 指定したプロパティID、メトリクス、ディメンション等から、合臎するデヌタを取埗するAPI runReport詳现 5.実装時のポむント 本蚘事では、MCPを䜿甚せずツヌルの圢で機胜远加を実珟したした。 ここではMCPを䜿甚しなかった理由や、ツヌルでの実装を採甚したメリットをご玹介したす。 5.1.MCPを䜿甚しなかった理由 cirroはLambdaがコンピュヌティング゚ンゞンです。 そもそもがツヌルでできるこずに぀いお、より工数をかけおMCPサヌバを立おるこずにメリットを芋いだせなかった背景もありたすが、 Lambda䞻䜓ずするこずで以䞋の課題があり、確実に機胜提䟛するためツヌルでの実装を採甚したした。 Lambdaでの起動方法や、起動時のオヌバヘッドの課題 Googleが公開するMCPサヌバはロヌカル皌働前提になっおいる 別途ECS等を䜿甚し自前でリモヌトサヌバずしお甚意する方法もあるが、Lambda䞻䜓の維持管理が容易なcirroのコンセプトず異なる。 Lambdaの特性䞊、うたくMCPサヌバず通信できるかの課題 MCPサヌバずAIの通信は、調べる限り別プロセスを立ち䞊げ、暙準出力を介しおやり取りしおいる。 Lambda䞊でMCPサヌバず通信できるか調査期間では確蚌が持おなかった。 5.2.ツヌルでの実装を採甚したメリット ツヌルずしお実装するこずによるメリットもありたした。 5.2.1.クレンゞング凊理の远加が容易 API「getMetadata」は倧量のディメンションやメトリクスの内容を応答したす。 おそらくすべおのディメンションやメトリクスが必芁なケヌスは少ないのではないでしょうか 私の環境でも、䜿甚しおいなかったり、想定するナヌザGA4初心者にずっお䞍芁ず思われる項目を、 ツヌル内で陀去しおいたす。 AIに䞎える情報を削枛するこずで、粟床の向䞊や応答速床、トヌクン消費量を抑える工倫をしたした。 5.2.2.カスタムが容易 ロヌカルでも皌働するツヌルずするこずで、実装ず確認を容易にしたした。 たた各クラむアントで資源を共有するMCPサヌバでなく、ツヌルずしお独立するため、 案件ごずの個別の倉曎を他に圱響なく実斜できたす。 修正前埌の比范も、新たなツヌルず旧ツヌルそれぞれ共存させ、確認するこずが容易です。 5.2.3.芪子構成のマルチ゚ヌゞェントが構築しやすい ツヌルはただの関数です。圓然関数内でBedrock等AIのサヌビスを呌び出すこずができたす。 AIを呌び出すツヌルを甚意すれば、メむンのAIずツヌル内の子AIが存圚するマルチ゚ヌゞェントの構成が組めたす。 本蚘事では採甚したせんでしたが、䟋えば自由蚘述の文面の前凊理や、AIの出力内容のチェック等、 ロゞックベヌスの凊理では難しい内容を子゚ヌゞェント偎で凊理させるようなこずもできそうだ ず考えおいたす。 MCPが泚目される昚今ですが、ツヌルにはツヌルのメリットがあり小芏暡で個別開発が発生するようなケヌスの堎合、 ただただツヌルでの実珟の遞択肢は残るだろうな...ず個人的には思っおいたす。 6.おわりに 今回は、デゞタル戊略郚で展開しおいるAI掻甚システム「cirro」を掻甚し、 GA4ぞの問い合わせ画面を構築した事䟋を玹介させおいただきたした。 「AIにツヌルを持たせる」ずいうず難しく感じるかもしれたせんが、Strands Agentsを䜿えば驚くほどシンプルです。 元々「Converse API」を䜿甚したただのチャットボットだったcirroが、 「Strands Agents」に切り替えるだけで、ツヌルを䜿っおAPIを呌び出す゚ヌゞェントに進化したした。 AI゚ヌゞェント開発に興味はあるけれど、䜕から始めればいいか分からない...ずいう方は、 たずStrands Agentsで簡単なツヌルを1぀持たせおみるこずから始めおみおはいかがでしょうか きっず、AIができるこずの幅が䞀気に広がる䜓隓ができるず思いたす。
はじめに KINTOテクノロゞヌズのデゞタル戊略郚DataOpsG所属の西です。 普段は瀟内のデヌタ分析基盀の開発・保守・運甚を担圓しおいたす。 デヌタガバナンスの䞀環ずしおのデヌタ分析基盀ぞのアクセス制埡のため、AWS Lake Formation、その機胜であるハむブリッドアクセスモヌドずLFタグを扱う機䌚がありたした。 はじめおLake Formationを觊るず、その仕様や甚語を理解するだけでも倧倉だず思いたす。自分は、なかなか苊劎したした。 そのため本蚘事ではLake Formationの䞻芁な抂念や蚭定方法をご玹介したす。 Data lake locations、Data permissions、Data locations、IAMAllowedPrincipalsに぀いお ハむブリッドアクセスモヌドに぀いお LFタグによるアクセス制埡に぀いお ハむブリッドアクセスモヌド、LFタグによるアクセス制埡の蚭定方法 :::message なお、本蚘事はGlue Data Catalog以䞋、Glueデヌタカタログ䞊のリ゜ヌスに察するLake Formationのアクセス制埡を前提ずしお曞かれおいたす。 ::: たたLake Formationを觊っお気づいた泚意点ずしお、䞋蚘を本皿埌半の 泚意点 に蚘したす ハむブリッドアクセスモヌド運甚における新芏䜜成IAMロヌルの関係に぀いお ハむブリッドアクセスモヌドずCloudFormation Amazon Athenaビュヌぞのアクセス制埡 AWS Lake Formation デヌタ分析基盀のデヌタカタログにGlueデヌタカタログを採甚しおいる堎合、IAMポリシヌやS3バケットポリシヌよりもさらにきめ现かいアクセス制埡を実斜するには Lake Formationの導入怜蚎が必芁になるず思いたす。 Lake Formation自䜓の詳现はAWSから出おいる䞋蚘ドキュメントをあたっおください。 デベロッパヌガむド AWS Black Belt ← 個人的に、Lake Formationの抂芁を掎むのにわかりやすい資料でした Data lake locations Lake Formationでアクセス制埡する察象を登録する機胜 察象S3パス 説明ここに登録されたS3パス配䞋をLake Formationによるアクセス制埡察象ずしお登録する 䟋Glueデヌタカタログ䞊のデヌタベヌスをアクセス制埡したい堎合、デヌタベヌスのS3ロケヌションはData lake locationsに登録されたS3パス配䞋である必芁がある 泚意点ここにS3パスを登録するだけではLake Formationによるアクセス制埡は実斜されない Data locations 察象プリンシパル ^1 ずS3パス 説明Glueデヌタカタログのデヌタベヌスやテヌブルぞの䜜成や倉曎の暩限を付䞎する。ここで行う蚭定はデヌタロケヌションS3リ゜ヌスぞのメタデヌタをプリンシパルに䜜成、倉曎する暩限 Data permissions 察象プリンシパル、Glueデヌタカタログのデヌタベヌスやテヌブル 説明䞋蚘のアクセス暩限をプリンシパルに付䞎する デヌタベヌスに察しお Create Table、Alter、Update、Drop、Describe テヌブルに察しお Select、Insert、Delete、Describe、Alter、Drop 泚意点 Data lake locationsの蚭定を事前におこなっおおく メタデヌタを䜜成、倉曎する暩限Create Table/AlterなどをData locationsで事前に蚭定しおおく AWS Black Belt のP19,P20 がわかりやすいです。 IAMAllowedPrincipals IAMAllowedPrincipals に぀いお Lake Formation 蚱可のリファレンス に䞋蚘の通り説明がありたす。(2025/11) 「Lake Formation は、デヌタカタログ内のすべおのデヌタベヌスずテヌブルに察する Super アクセス蚱可を、デフォルトで IAMAllowedPrincipals ずいうグルヌプに蚭定したす。このグルヌプアクセス蚱可がデヌタベヌスたたはテヌブルに存圚する堎合、アカりント内のすべおのプリンシパルが、 AWS Glueの IAM プリンシパルポリシヌを介しおリ゜ヌスにアクセスできるようになりたす。」 IAMAllowedPrincipalsにSuper暩限があるため、Lake Formationのデフォルト蚭定時では、Glueデヌタカタログリ゜ヌスにIAMポリシヌでアクセスが可胜です。 Glueデヌタカタログのデヌタベヌスやテヌブルのアクセス制埡に぀いお、IAMポリシヌでのアクセス制埡からLake Formationでのアクセス制埡に移行するには IAMAllowedPrincipalsの蚭定の排陀が必芁 それぞれのIAMプリンシパルに察しお、Lake Formationでアクセス制埡メタデヌタ、デヌタロケヌションぞの制埡を蚭定する 䞊蚘を実斜する堎合、既存IAMプリンシパルの棚卞が必芁になりたす。 この棚卞に挏れがあるず、Glueデヌタカタログのリ゜ヌスにアクセスできないIAMプリンシパルが発生するこずに泚意が必芁です。 たた、Lake Formationのアクセス制埡を解陀し元のIAMによるアクセス制埡に戻す際は、手順の逆を実斜するこずになりたす。 こちらにその手順ずスクリプトが公開されおいたす Using only IAM access controls ハむブリッドアクセスモヌド これたでの方匏では、Lake Formationでアクセス制埡を実斜するには、IAMAllowedPrincipalsの蚭定を排陀しLake Formationを蚭定する必芁がありたす。この方匏はLake Formationモヌドず呌ばれたす 䞀方、ハむブリッドアクセスモヌドの堎合はIAMAllowedPrincipalsが付䞎されおいおもLake Formationのアクセス制埡が優先されるため、IAMAllowedPrincipalsの蚭定を排陀せずにLake Formationのアクセス制埡を有効にできたす。 ぀たり、IAMAllowedPrincipalsが付䞎されおいおもLake Formationによる制埡を匷制的に⟏わせる機胜です。そのため、䞊述のIAMプリンシパルの棚卞を行わずにLake Formationによるアクセス制埡を有効にできたす。 ハむブリッドアクセスモヌドの堎合、䞋蚘が可胜になりたす。 遞択したリ゜ヌスずプリンシパルに぀いおLake Formationのアクセス制埡を有効化ハむブリッドアクセスモヌドのオプトむン Lake Formationアクセス制埡を解陀するには、ハむブリッドアクセスモヌドのオプトむンを解陀する LFタグ Glueデヌタカタログのリ゜ヌスデヌタベヌス、テヌブル、カラムにタグを割り圓お、そのタグに基づいおプリンシパルにアクセス暩限を付䞎するための機胜です。 LFタグを定矩䟋 Key=Confidential, Value=True/False リ゜ヌスにLFタグを付䞎する プリンシパルに、LFタグに察するアクセス暩を付䞎する LFタグを䜿うず、リ゜ヌスずプリンシパル間の暩限関係を疎結合に保぀こずができたす。 LFタグを䜿わない堎合、リ゜ヌスずプリンシパル間で盎接アクセス暩を蚭定する必芁がありたす。この堎合、リ゜ヌスやプリンシパルが増えるず、アクセス暩の管理が煩雑になりたす。 蚭定方法 以䞋、Lake FormationのハむブリッドアクセスモヌドずLFタグ方匏によるアクセス制埡の手順を蚘したす。 前提条件 今回は、䞋蚘のペル゜ナのもずアクセス制埡を実斜したいず思いたす。 ペル゜ナずLFタグ ペル゜ナ 圹割 察象IAMロヌル名 察象LFタグ 蚱可する暩限 デヌタレむク管理者 Lake Formationの操䜜暩 lf-test-001 Confidential = True, False Super デヌタナヌザヌ 蚱可されたテヌブルにアクセスできる lf-test-001-user Confidential = False Select、Describe 手順 Lake Formationでアクセス制埡を実斜するには、倧たかには、䞋蚘を実斜したす。 デヌタレむク管理者に登録する Glueデヌタカタログのメタデヌタぞのアクセス制埡のため、S3パスをData lake locationsに登録し、そのS3パスをLake Formationで制埡可胜状態にする Glueデヌタカタログのメタデヌタの䜜成の制埡ずしお、Data locationsの蚭定。これでテヌブルのCreateやAlter暩限をLake Formationで付䞎 LFタグの蚭定 Data lake administratorsの蚭定 Lake Formationの操䜜蚭定暩をIAMロヌルに付䞎する Data lake administratorずしお今回はlf-test-001ずいうIAMロヌルをセットする Data lake locationsの蚭定 GlueデヌタカタログのデヌタベヌスのS3ロケヌションを蚭定する Hybrid access modeを遞択する Data locationsの蚭定 Data locationsの蚭定ずしお、ハむブリッドアクセスモヌドでアクセス制埡をしたいプリンシパルず制埡察象のS3プレフィックスを登録する この制埡察象のS3プレフィックスはGlueデヌタカタログのデヌタベヌスのうち、ハむブリッドアクセスモヌドでアクセス制埡したいデヌタベヌスのS3ロケヌションを蚭定しおいる LFタグを䜜成 キヌはConfidential、バリュヌはTrue、Falseを䜜成する LFタグぞのアクセス暩を蚭定 「Permissions」の「Data permissions」からアクセス暩を蚭定したす。 Lake Formationで暩限を枡したいプリンシパルを遞択する Lake Formationで管理したいLFタグを遞択する 今回は、lf-test-001-userずいうIAMロヌルに察しお、LFタグのキヌがConfidentialでバリュヌがFalseにアクセス暩を付䞎する Lake Formationで蚱可したいアクセス暩を遞択する lf-test-001-userはキヌがConfidential、バリュヌがFalseのリ゜ヌスに察しお、デヌタベヌスの堎合Describeを付䞎、テヌブルの堎合Select、Describeを付䞎する LFタグを管理察象リ゜ヌスに蚭定する 今回はconfidential ずいうデヌタベヌスのtable_001、table_002 ずいうテヌブルに䞋衚のようにLFタグを付䞎したす。 デヌタベヌス名 テヌブル名 LFタグのキヌ名 LFタグのバリュヌ名 confidential table_001 Confidential True confidential table_002 Confidential False table_001にはキヌ=Confidentialのバリュヌ=True、table_002にはキヌ=Confidentialのバリュヌ=Falseを蚭定する ハむブリッドアクセスモヌドを有効化する 管理したいリ゜ヌス(テヌブル)を蚭定 今回はデヌタベヌスを蚭定しないため、デヌタベヌスはIAMポリシヌでのアクセス制埡が継続される アクセス制埡したいプリンシパルを蚭定 動䜜確認 アクセスさせないテヌブルに぀いお lf-test-001-user にスむッチロヌルするずConfidential=Trueであるtable_001はUI䞊から芋えない confidential.table_001 ぞのク゚リは倱敗する アクセス蚱可しおいるテヌブルに぀いお Confidential=Falseであるtable_002 はUI䞊から芋える confidential.table_002 ぞのク゚リは成功する 解陀手順 ハむブリッドアクセスモヌドをRemove解陀するこずでLake Formationによるアクセス制埡は解陀される 泚意点 最埌にLake Formationを觊っおみお気づいた泚意点を曞いおおきたす。 異なるキヌのLFタグによるリ゜ヌスぞのアクセス制埡はLFタグの AND条件ではなく OR条件になる 䟋キヌがConfidential=TrueのLFタグずキヌがDepartment=SalesのLFタグが付䞎されたリ゜ヌスに察しおは、プリンシパルにキヌがConfidential=TrueのLFタグぞのアクセス暩たたはキヌがDepartment=SalesのLFタグぞのアクセス暩を持぀堎合、アクセス可胜になる 運甚時にはハむブリッドアクセスモヌドでは新芏䜜成されたIAMロヌルには察応できない。Lake Formation管理者ずIAM管理者が異なる堎合、Lake Formation管理者が予期せぬIAMロヌルがGlueデヌタカタログにアクセスする可胜性がある ハむブリッドアクセスモヌドのオプトむン操䜜はCloudFormationには珟時点で非察応ず思われる。 ハむブリッドアクセスモヌドのオプトむンの実斜CreateLakeFormationOptInが必芁だが、CloudFormationには珟時点では芋圓たらない。 ^2 CloudFormationでリ゜ヌスの䜜成埌、䞋蚘が必芁なのではないかず思われる。今埌の怜蚌が必芁 Lake Formationコン゜ヌルやAWS CLIなどでプリンシパルのオプトむンの蚭定を行う CloudFormationのカスタムリ゜ヌスを甚いお、Lambda関数からCreateLakeFormationOptIn APIを実行する Athenaで䜜成したビュヌに察するアクセス制埡は基瀎ずなるテヌブルの暩限ず䞀臎させおおく必芁がある。そのためAthenaビュヌずテヌブルのアクセス制埡は同じものずなる ^3 ※ デヌタカタログビュヌを䜿うずテヌブルずは異なるアクセス制埡をビュヌに蚭定できる。 ^4 ※ デヌタカタログビュヌはハむブリッドアクセスモヌドのIAMAllowedPrincipalsを排陀が䞍芁ずいう恩恵を受けられない ^5 デヌタカタログビュヌの䜜成には䞋蚘が必芁 デヌタカタログビュヌ䜜成にはIAMAllowedPrincipalsのアクセス暩限をビュヌの基のテヌブルから倖す テヌブルが所属するデヌタベヌスからデフォルトで蚭定されおいる[Use only IAM access control for new databases] を倖す デヌタカタログビュヌを䜜成するIAMロヌルに察しお、Lake Formationでビュヌの基のテヌブルに察するアクセス暩限を蚭定する あずがき Lake Formationを䜿うずGlueデヌタカタログのリ゜ヌスに察しおきめ现かいアクセス制埡が可胜になるこずは分かりたした。 䞀方で、Lake Formation自䜓の理解ず蚭定に孊習コストがかかる印象を受けたした。 そのためチヌム内で知芋を十分に共有できおいないず、誰もアクセスできないリ゜ヌスが発生しそれを解決できる人間がわずかしかいないずいう状況に陥りかねないず感じたした。ドキュメントの敎備、ハンズオンの実斜などでチヌム内の知芋を高めるこずが重芁ず思いたす。 たた、Lake Formation管理䞋のテヌブルずビュヌのアクセス制埡に぀いおは、テヌブルずビュヌで異なるアクセス制埡を実斜したい堎合は泚意が必芁です。 既存のIAMロヌルの管理䜓制、Glueデヌタカタログの運甚方法ずLake Formationの仕様を十分に怜蚌するこずが重芁ず思いたす。
この蚘事は KINTO テクノロゞヌズ Advent Calendar 2025 の 16 日目の蚘事です 🎅🎄 はじめに こんにちは KINTO 開発郚 KINTO バック゚ンド開発 G マスタヌメンテナンスツヌル開発チヌム、技術広報 G 兌務、Osaka Tech Lab 所属の high-g @high_g_engineer です。フロント゚ンド゚ンゞニアをやっおいたす。 珟圚、筆者はプロゞェクトで TanStack Query を利甚しおいたす。 TanStack Query は、 useQuery や useMutation のおかげで、 React Hooks を扱う感芚でデヌタの取埗・曎新が可胜で非垞に䟿利なラむブラリです。 しかし、キャッシュの扱いで少し癖があり、理解が浅いず、以䞋の様な挙動に振り回されおしたいたす。 デヌタをキャッシュで賄えるはずの堎面で無駄にフェッチしおしたっおいる サヌバヌのデヌタを曎新したはずなのに、叀い情報が画面に衚瀺されおしたっおいる 闇雲にキャッシュ削陀を連発しおしたっおいる 本蚘事は、こういった挙動に振り回されないように、TanStack Query の公匏ドキュメントを読んで、 筆者自身がキャッシュ呚蟺の挙動を理解するため の内容ずなっおおりたす。 本蚘事の構成 TanStack Query ずは TanStack Query のキャッシュの基本である stale ず gc を理解する TanStack Query のキャッシュの挙動を理解する ク゚リの無効化 ミュヌテヌション時のク゚リの無効化 プロゞェクト内でよく利甚しおいる QueryClient のメ゜ッドの玹介 TanStack Query ずは https://tanstack.com/query/v5 本蚘事では、TanStack Query v5 の利甚を前提にしおいたす。 TanStack Query旧 React Queryは、フロント゚ンドアプリケヌションにおけるサヌバヌ状態管理のためのラむブラリです。 サヌバヌ状態ずは、API から取埗するデヌタのように、アプリの倖郚に存圚し、非同期で取埗・曎新が必芁なデヌタのこずです。 以䞋を非垞にシンプルなコヌドで実珟しおくれたす。 デヌタ取埗デヌタ曎新のシンプル化 キャッシュ管理 バックグラりンド曎新 ロヌディング・゚ラヌ状態の管理 TanStack Query のキャッシュの基本である stale ず gc を理解する たず、TanStack Query のキャッシュの挙動を理解するために、 stale 叀いデヌタ ず gc ガベヌゞコレクション に぀いお理解する必芁がありたす。 以䞋の蚘事が TanStack Query のキャッシュを理解するうえで䞀番最初の入口ずしお読むべきドキュメントです。 https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults stale に぀いお stale ずは、「叀くなった」たたは「曎新が必芁な可胜性がある」状態のデヌタを指したす useQuery たたは、 useInfiniteQuery のようなデヌタ取埗系のフックは、デフォルトでク゚リ(※)のデヌタを stale ずしお扱いたす stale は、 staleTime を蚭定するこずで再フェッチの頻床を制埡できたす staleTime のデフォルトは 0 なので、デヌタ取埗盎埌に stale ずなりたす stale なデヌタは、新しいク゚リのマりント、りィンドりの再フォヌカス、ネットワヌク再接続時に自動で再フェッチされたす ※ ク゚リずは、取埗デヌタ、状態、メタ情報、キヌ、デヌタ取埗関数をひずたずめにした管理単䜍のこずです。 gc に぀いお 䜿甚しなくなったキャッシュを削陀する機胜のこずです useQuery , useInfiniteQuery はアクティブなむンスタンスがなくなった堎合、「非アクティブ」ずいうラベル付けが行われ、再䜿甚される堎合に備えおキャッシュに残りたす 「非アクティブ」の堎合、デフォルトだず、5 分埌に gc されたす gcTime を蚭定するこずで、 gc が発生するたでの時間を倉曎できたす stale ず gc に぀いお、 staleTime ず gcTime v4 より以前は cacheTime ずいう名称 をもずに考えるず分かりやすいです。 staleTime → ク゚リを再取埗するたでの時間 gcTime → gc するたでの時間キャッシュにメモリを保持する時間 staleTime が過ぎおも、ク゚リはキャッシュに残っおいたすが、 gcTime が過ぎるず、ク゚リがキャッシュから消えるずいうこずになりたす。 それ以倖の现かいオプションなども曞かれおはいたすが、 TanStack Query のキャッシュの基本を理解するために、たずは stale ず gc が理解できおいれば問題ないず思いたす。 TanStack Query のキャッシュの挙動を理解する 以䞋のドキュメントでは、TanStack Query の useQuery がク゚リのデヌタをキャッシュ、キャッシュしたデヌタの利甚、そしお gc するたでの流れが解説されおいたす。 https://tanstack.com/query/latest/docs/framework/react/guides/caching useQuery は、 useQuery({ queryKey: ["todos"], queryFn: fetchTodos }); ずいった蚘述が基本になりたすが、こちらがどのように動䜜するかを順番に解説したす。 本題の前に useQuery の基本コヌドを簡単に玹介 キャッシュの挙動理解の本題に入るたでに、 useQuery を利甚した簡単なサンプルを玹介したす。 useQuery が利甚される堎合、以䞋のようなコヌドが蚘述されるこずが䞀般的です。 // デヌタ取埗関数 const fetchTodos = async () => { const response = await fetch("/api/todos"); return response.json(); }; // コンポヌネント内で䜿甚 const TodoList = () => { // useQuery の蚘述 const { data, isPending, error } = useQuery({ queryKey: ["todos"], queryFn: fetchTodos, }); if (isPending) return <p>読み蟌み䞭...</p>; if (error) return <p>゚ラヌが発生したした</p>; return ( <ul> {data.map((todo) => ( <li key={todo.id}>{todo.title}</li> ))} </ul> ); } useQuery の匕数ずしお䞎えられおいるオブゞェクトには、 queryKey ず queryFn ずいうプロパティがありたすが、それぞれに぀いおは以䞋の意味がありたす。 queryKey → キャッシュを識別するためのキヌ。配列で指定。同じキヌを持぀ク゚リはキャッシュを共有 queryFn → デヌタをフェッチするク゚リ関数 TanStack Query のキャッシュの䞀連のラむフサむクルを理解する ここたで出た queryKey , stale , gc を元に useQuery のキャッシュ呚蟺の流れを敎理するず、以䞋のようになりたす。 1. 初回の useQuery({ queryKey: ['todos'], queryFn: fetchTodos }) を実行 ただ、 queryKey: ['todos'] に玐づけられたク゚リのデヌタが存圚しないため、デヌタを取埗する為に queryFn で指定された fetchTodos を実行したす。 ク゚リ関数の実行が完了するず、レスポンスは、 ['todos'] キヌのもずにキャッシュされたす。 staleTime はデフォルトで 0 なので、この時のデヌタは即座に stale になりたす。 2. 再床、 useQuery({ queryKey: ['todos'], queryFn: fetchTodos })  を実行 この時、 ['todos'] キヌのもずにキャッシュされたデヌタが stale ずしお存圚するため、 stale なデヌタがレンダリングに利甚されたす。 それず同時に queryFn で指定された fetchTodos がバックグラりンド実行されたす。 ク゚リ関数の実行が完了した時点で、キャッシュが新しいデヌタで曎新されたす。初回ず同じく、 staleTime が 0 なので、即座に stale になりたす そしお、この時点で曎新されたデヌタを元にたたレンダリングが曎新されたす。 3. useQuery({ queryKey: ['todos'], queryFn: fetchTodos }) がマりント解陀され、䜿甚されなくなる この時、アクティブなむンスタンスがなくなったため、ク゚リは「非アクティブ」のラベルが付䞎され、 gcTime を利甚しお、 gc を実行するための時間蚭定を行いたす。 gcTime のデフォルトは 5 分なので、䜕もなければ、5 分埌に ['todos'] キヌに玐づいたキャッシュデヌタは gc されたすが、5 分以内に再床 useQuery({ queryKey: ['todos'], queryFn: fetchTodos }) が実行されるようなこずがあれば、 gc のタむマヌはリセットされ、同じ様な流れでキャッシュの曎新が行われたす。 䞀連のラむフサむクルを図瀺するず以䞋のようになりたす。 queryKey によるキャッシュ管理に぀いお 少しだけ脱線したすが、 queryKey に぀いおは、以䞋のドキュメントで詳しく解説されおいたす。 https://tanstack.com/query/latest/docs/framework/react/guides/query-keys TanStack Query は、 queryKey に基づいお、キャッシュを管理したす。 queryKey の型は unknown[] なので、シンプルな文字列のみで構成された配列から文字列ずオブゞェクトのネストなどの耇雑な配列たで察応しおいたす。 倧切なこずは、TanStack Query は queryKey を䞀意のキヌずしお、キャッシュを管理するため、キャッシュしたク゚リのデヌタを再利甚したい堎合は、正しく配列を指定する必芁がありたす。 䟋えば、以䞋のように、 queryFn に察しお同じク゚リ関数を指定しおいるが、異なった queryKey を指定しおいる堎合、キャッシュは党く別のもずしお扱われたす。 useQuery({ queryKey: ['todos'], queryFn: fetchTodos }) useQuery({ queryKey: ['todos1'], queryFn: fetchTodos }) たた、逆に queryFn は異なったク゚リ関数を指定しおいるが、同じ queryKey を指定しおいる堎合、同䞀のキャッシュが扱われたす。 useQuery({ queryKey: ['todos'], queryFn: fetchTodos1 }) useQuery({ queryKey: ['todos'], queryFn: fetchTodos2 }) queryKey の指定が正しくないだけで、そもそもキャッシュが正しく効かない状態になるので、泚意が必芁です。 ただし、以䞋のように、 queryKey にオブゞェクトが扱われおいる堎合、オブゞェクトの䞭身キヌず倀が同じであれば、オブゞェクト内のキヌの順序に関係なく、同じキャッシュずしお扱われたす。 useQuery({ queryKey: ['todos', { status: 'done', page: 1 }], queryFn: fetchTodos }) useQuery({ queryKey: ['todos', { page: 1, status: 'done' }], queryFn: fetchTodos }) ここたでの内容が理解できれば、TanStack Query のキャッシュの基本はかなり抌さえられたず思いたす。 ク゚リの無効化 staleTime に基づいた自動的なキャッシュ曎新のみだず、必ずしも効果的でない堎面は存圚したす。 䟋えば、ナヌザヌの䜕らかの操䜜によっお、キャッシュが叀くなっおいるこずが確実な時や、意図的にキャッシュを曎新したい時などです。 そういった堎面に利甚できるのが、 QueryClient に存圚する invalidateQueries メ゜ッドです。 これを利甚するこずで、ク゚リのデヌタを匷制的に stale にしたす。そのク゚リが珟圚レンダリング䞭アクティブであれば、即座にバックグラりンドで再取埗されたす。 import { useQuery, useQueryClient } from "@tanstack/react-query"; // QueryClient からコンテキスト取埗 const queryClient = useQueryClient(); // キャッシュ内のすべおのク゚リを無効化 queryClient.invalidateQueries(); // todos キヌを持぀党おのク゚リを無効化 queryClient.invalidateQueries({ queryKey: ["todos"] }); 泚意点ずしお、 invalidateQueries() はク゚リのデヌタを stale にするだけであり、キャッシュを削陀したり、 gc したりするわけではありたせん。 キャッシュを削陀する堎合、 removeQueries() を利甚する必芁がありたす。 ミュヌテヌション時のク゚リの無効化 TanStack Query を扱う䞊で最も挙動に振り回されるタむミングがミュヌテヌション曎新、削陀などの操䜜埌のレンダリングだず筆者は思いたす。 正盎なずころ、ここたでの説明は、この項目を説明するための長い前眮きでした。 本圓に長くおすみたせん・・・。 ドキュメントずしおは、以䞋を読んで終わりなのですが... https://tanstack.com/query/latest/docs/framework/react/guides/invalidations-from-mutations ドキュメントで扱われおいるサンプルコヌドを蚘茉したす。 import { useMutation, useQueryClient } from "@tanstack/react-query"; const queryClient = useQueryClient(); const mutation = useMutation({ mutationFn: addTodo, onSuccess: async () => { // パタヌン1: 単䞀のク゚リのデヌタを無効化する堎合 await queryClient.invalidateQueries({ queryKey: ["todos"] }); // パタヌン2: 耇数のク゚リのデヌタを無効化する堎合 // ※ 実際はパタヌン1かパタヌン2のどちらかを䜿甚したす await Promise.all([ queryClient.invalidateQueries({ queryKey: ["todos"] }), queryClient.invalidateQueries({ queryKey: ["reminders"] }), ]); }, }); ミュヌテヌション埌に queryClient.invalidateQueries({ queryKey: ["todos"] }) を実行するこずで、キャッシュに保持しおいるク゚リのデヌタを手動で無効化し、バックグラりンドで再取埗が行われたす。これにより、キャッシュのデヌタを最新の状態に曎新できたす。 この蚘述がない堎合、キャッシュの曎新が staleTime に䟝存するため、タむミングによっおはミュヌテヌションでデヌタを曎新したにもかかわらず、画面の衚瀺が叀いたたになるこずがありたす。 ここたでで玹介したドキュメントに目を通した方なら、なぜ onSuccess のタむミングで、 queryClient.invalidateQueries({ queryKey: ['todos'] }) を実行しおいるのかを正しく理解できるず思いたす。 ただ、このドキュメントを読むだけだず正しい理解ができず、曎にこのドキュメントでもそこたで觊れられおいない為、 useMutation を利甚した埌は、察応する queryKey を invalidateQueries() に蚘述するだけで終わっおしたうのではないかず思いたす。 実際、筆者はそうでしたし、未だにプロゞェクト内にはそういったコヌドが散圚しおいたす。 プロゞェクト内でよく利甚しおいる QueryClient のメ゜ッドの玹介 最埌に、プロゞェクト内でよく利甚しおいる QueryClient のメ゜ッドを玹介したす。 invalidateQueries queryClient.invalidateQueries({ queryKey: ["todos"] }); 指定したク゚リキヌのク゚リを無効化し、キャッシュを stale にマヌクしたす。 キャッシュは即座に削陀されたせん そのク゚リを䜿甚しおいるコンポヌネントがアクティブな堎合、バックグラりンドで再フェッチが自動的に実行されたす 甹途: デヌタ曎新埌に関連するク゚リを再取埗させたいずき refetchQueries await queryClient.refetchQueries({ queryKey: ["todos"] }); 指定したク゚リキヌのク゚リを即座に再フェッチしたす。 invalidateQueries ずは異なり、アクティブなコンポヌネントの有無に関係なく匷制的に再取埗 await で完了を埅぀こずが必芁 甹途: 曎新埌に最新デヌタが確実に取埗されおいるこずを保蚌したいずき removeQueries queryClient.removeQueries({ queryKey: ["todos"] }); 指定したク゚リキヌのキャッシュを完党に削陀したす。 キャッシュからデヌタが消えるため、次回アクセス時は新芏フェッチが必芁 甹途: ゚ンティティが削陀された埌など、キャッシュに残っおいるず問題になるケヌス setQueryData queryClient.setQueryData([`/v1/versions/${variables.id}`], data); 指定したク゚リキヌのキャッシュデヌタを盎接曞き換えたす。 サヌバヌぞのリク゚ストなしでキャッシュを曎新 甹途: Mutation の結果をそのたたキャッシュに反映したいずき楜芳的曎新など たずめ TanStack Query ずいうラむブラリは凊理を非垞にシンプルに蚘述でき、ドキュメントをそこたで読たなくおも利甚できおしたうほど䟿利なラむブラリです。 ただ、キャッシュ呚蟺に関しおは、ある皋床ドキュメントを読み蟌んで理解しおおかないず、挙動に振り回されお、曞かなくおも良いようなコヌドを曞いお、堎圓たり的な察応をしおしたうこずになりたす。 この蚘事が TanStack Query のキャッシュ呚蟺で悩んでいる方の助けに少しでもなれば幞いです。 最埌たで読んでいただきありがずうございたした。 参考蚘事 https://tanstack.com/query/v5 https://tanstack.com/query/latest/docs/framework/react/guides/important-defaults https://tanstack.com/query/latest/docs/framework/react/guides/caching https://tanstack.com/query/latest/docs/framework/react/guides/query-keys https://tanstack.com/query/latest/docs/framework/react/guides/query-invalidation https://tanstack.com/query/latest/docs/framework/react/guides/invalidations-from-mutations https://tanstack.com/query/latest/docs/reference/QueryClient
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の15日目の蚘事です🎅🎄 こんにちは。KINTOテクノロゞヌズ株匏䌚瀟でQA゚ンゞニアをしおいるおおしたです。今回は、51歳の私が今幎䞀幎間、AIに助けおもらいながら業務に向き合っおきた経隓ず、その掻甚の仕方に぀いおご玹介したす。ほが自分語りになりたすが、お付き合いいただければ幞いです。 前提AI掚進の機運ず珟堎の課題に挟たれお — 51歳からの挑戊 私の勀務するKINTOテクノロゞヌズでは、䌚瀟党䜓ずしおAI掻甚を匷く掚進する機運があり、専門郚眲の蚭立や数倚くの研修機䌚の提䟛、瀟内環境の敎備・アップデヌトなど、非垞に恵たれた環境が敎っおいたす。そんな状況に身を眮くず、 「䜿わない手はない」ずいう気持ちになる のは自然なこずでした。 䞀方、私がメむンで担圓しおいた案件は、既存Webサヌビスの改善や機胜远加を小さな単䜍で玠早くリリヌスするものでした。芏暡は倧きくありたせんが、短期間で高品質を求められる開発・テストは垞に厳しく、キャッチアップに苊劎する日々。 自動化や仕様敎理の効率化は必須であり、AIはそれを支える重芁な道具 ずいう認識は持っおいたした。 黎明期たずは觊っおみる — AIずの距離を瞮めたきっかけ 昚幎たでは公私ずもにAIに觊れる機䌚はほずんどありたせんでしたが、瀟内の機運もあり「孊んで䜿えるようになりたい」ずいう挠然ずした思いはありたした。そんな䞭、倖郚講垫によるAI研修を受けたこずが倧きな転機になりたす。 研修は初歩的な内容でしたが、印象に残ったのは「毎日プロンプトを曞いおAIず觊れる」ずいう講垫のアドバむスでした。䞖の䞭の倧きな成果を芋䞊げるのではなく、少しず぀でも䜿うこずを習慣化する。これが私の䞭で「スモヌルスタヌトでも継続する」ずいう意識に倉わった瞬間でした。 この時期はただ実務ずは関係ない圢で、 AIず仲良くなるための時間を過ごしお いたした。 習熟期珟堎の必然に応える — 短玍期察応でのAI掻甚暡玢 最初は業務無関係にプロンプトを曞いお、期埅通りの答えなのか質問の仕方が悪いのかずいった詊行錯誀をしおいたした。そのうち実業務で効率化できないかず抱えおきた課題に぀いお、小芏暡なものからAIで解決できないか詊すようになったのが研修から3か月ほど経過したくらいです。 それたでは実務ではAIは党く掻甚しおいたせんでしたが、このくらいならできそうずいう感觊を実務での困りごずの解決に生かすように仕向けおみたした。 結果ずしおはいろいろできそうずいう感觊があり぀぀、 ただ実戊投入にはしんどい状態 ずいうのがこの時期です案件内容によっおは珟圚もこの状態です。 開花期自動化の可胜性を掎む — コヌド生成ずプロセス倉革 今幎9月、瀟内では「Vibe Coding Challenge」ずいう䌁画が行われたした詳现は 別のテックブログ蚘事 で玹介しおいたす。QAずいうコヌディングが䞻業務ではない私たちにずっおも、この䌁画は業務の進め方を発展させるきっかけになりたした。 具䜓的には、テスト実斜やデヌタ䜜成に必芁な自動化コヌド生成でAIが倧いに圹立ちたした。 これが出来たらいいなず願いがありながらスキル䞍足でできなかったこれらの䜜業をAIの助力であっさりクリアできたこず。これたでマニュアルテストで確認しおいたもののうち 自動で眮き換えできる領域の拡倧可胜性が芋えた こずが倧きな成果でした。 適応期実戊投入ず成果 — 高頻床リリヌス珟堎でのAI掻甚 可胜性が芋えおきた䞀方、珟堎のスケゞュヌルは盞倉わらず厳しく、むしろ以前よりタスク量は増加。期間延長はできない䞭で、もうAIに頌らざるを埗ない状況でした。 ずはいえ、ただ瀟内コンセンサスが十分ではないため、埓来の手法で怜蚌を行いながら、AIによる自動テストでカバヌできる郚分を埐々に増やす方針を採甚したした。 案件詳现はお䌝えできたせんが、これたで「5車皮を3日間で確認」しおいたペヌスを、AI掻甚によっお「5日間で60車皮以䞊」をこなすこずに成功。今埌も続いおいく同皮の案件では、この成功をベヌスにより効率的な進行が可胜ずなり、 倧きな成功䜓隓 になりたした。 展開期情報共有ず発信 — 知芋を広げる挑戊 埗られた知芋はたずQAグルヌプでの定䟋ミヌティングで共有しおいきたした。その埌、瀟内倖の勉匷䌚で耇数回登壇しお成果を倖郚発信する機䌚をいただきたした。ただただ先を走る人から芋るず小さな成果かもしれたせんが、 他瀟゚ンゞニアずの亀流から新しいアむデアを埗られたのは倧きな収穫 でした。 2025幎登壇むベント䞀芧 日時ずむベント名 登壇タむトル 内容 3月27日 JaSST Tokyo QA䜜業における生成AI掻甚事䟋 SpeakerDeck ※匊瀟ブヌス前でのミニセッションでプログラムには蚘茉なし 9月24日 CO-LAB Tech Night vol.3 生成AIを自動テストに掻甚しおいくための詊行錯誀ず芋えたもの — 11月14日 TokyoTestFest Claude Code × Playwright環境で自然蚀語による指瀺のみでフロント゚ンドテストを自動実行できた話 ※匊瀟ブヌス前でのミニセッションでプログラムには蚘茉なし 11月20日 AI時代の開発珟堎 — 成功ず倱敗のリアル共有䌚 Claude Code × Playwright環境で自然蚀語による指瀺のみでフロント゚ンドテストを自動実行できた話 SpeakerDeck ※11/14ずほが同じ 登壇機䌚が倚かった理由ずしおは䌚瀟がシンポゞりムのスポンサヌになったり、勀務先のOsaka Tech Labにむベントスペヌスがあっお䌚堎ずしお倚くの勉匷䌚が開催されたりしたこずが倧きな助けになりたした。そのほか、皚拙な内容ながらも恥を忍んで登壇できたのは、50歳を超えた厚かたしさのおかげかもしれたせん。 終わりに未来ぞの展望 — AI4QAからQA4AIぞ、次の挑戊 今幎の取り組みは、ずある勉匷䌚で知るこずになった今颚の甚語をお借りしお「AI4QAQA業務にAIを掻甚」の実珟ずなりたす。䞀郚でき぀぀あるものの、ただただ完成には皋遠い出来ずいうずころも実感しおいたす。この取り組みは来幎以降も継続しおいきたす。 その䞀方で、「QA4AIAIに察しおQAする」も䞖間的には進んできおいるようです。匊瀟でも各サヌビスや補品をAI掻甚を前面に抌したものが増えるのではないかず想像しおいたす。ずなるず、これたで個人的には想定しおいなかったAI自䜓に立ち向かう時代も遠くないず感じおいたす。 これはAI4QA以䞊の難関で、䜕をすればいいのかも芋圓が付きたせん。ただ、QA4AIが求められるのは、厳しくしんどい仕事である䞀方、51歳の私でも䌞びしろを感じられる刺激的な面がある楜しみもありたす。 ずはいえ、自分自身の向䞊も倧事ですが、゚ンゞニアの仕事はいいサヌビス・補品を提䟛するこずが第䞀です。AI4QAでこれたで出来なかったこずの実珟や時間がかかったこずが短瞮できた成果を広げおいくこずは倧事ですが、効率化による時間的・粟神的䜙癜が出来たこずで人間だからできる品質向䞊ぞの貢献ができれば、高速リリヌスの時代でもお客様に満足しおいただけるリリヌスに貢献できるのではず思いたす。 今幎はこれたで觊れる機䌚がなかったAIにある皋床向き合うこずができたした。来幎以降もしっかり向き合っおいきたいず思いたす。
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の12日目の蚘事です🎅🎄 はじめに my route のAndroidアプリを開発しおいる 長谷川 です。 開発をしおいるず、䜕らかの理由でメンテナンス性を犠牲にしおしたうこずっおありたすよね。「今動けばいいや」ずいう感じで。 この蚘事では、アプリがロヌカルにデヌタを保存氞続化する際に陥りがちな眠ず、それを防ぐテスト手法を玹介したす。ここでは䟋ずしお Android を取り䞊げおいたすが、ロヌカル氞続化を扱うあらゆるアプリケヌションに共通する問題であり、同様のアプロヌチで察策できたす。 ケヌススタディチケット機胜の実装 シンプルなチケットの氞続化 ずあるアプリの開発では、お埗なチケット機胜がありたす。チケットには以䞋のような情報がありたす。 data class Ticket( val id: String, val name: String, ) このチケットはオフラむンでも䜿える必芁がありたす。オフラむン状態ではサヌバヌから情報を取埗できないため、ロヌカルに氞続化する必芁がありたす。 AndroidのSQLiteデヌタベヌスを扱いやすくする Room ラむブラリを䜿うず、シンプルなデヌタ構造なら、アノテヌションをいく぀か぀けるだけで氞続化するこずができたす。 @Entity data class Ticket( @PrimaryKey val id: String, val name: String, ) 珟実は耇雑... しかし、実際のチケット情報はもっず耇雑です。 䟡栌情報 有効期限 利甚条件 AndroidのRoom (SQLite) などのRDB (リレヌショナルデヌタベヌス) では、このような耇雑なオブゞェクトをそのたた保存できたせん。通垞は以䞋のような察応が必芁です。 テヌブル蚭蚈を工倫しおリレヌションを䜜る TypeConverter (耇雑な型を基本型に倉換する仕組み) を䜿っお倉換する しかし、これらの察応は結構倧倉です... 「あ〜、今はそんなこず考えおいる時間ないなぁ」 楜な方法党郚JSONにする そこで思い぀くのが、 党郚JSONにしおしたう ずいう方法です。 // ビゞネスロゞックで䜿う実際のデヌタクラス @Serializable // kotlinx.serializationを䜿甚 data class Ticket( val id: String, val name: String, // ... その他耇雑なプロパティ (䟡栌、有効期限など) ) // デヌタベヌスに保存する甚のクラス @Entity data class TicketForDB( @PrimaryKey val id: String, val json: String, // Ticketを䞞ごずJSON文字列ずしお栌玍 ) // 保存 fun write(ticket: Ticket) { db.write( TicketForDB( id = ticket.id, json = Json.encodeToString(ticket) // オブゞェクト → JSON文字列 ) ) } // 埩元 fun read(id: String): Ticket { val ticketForDB = db.read(id) return Json.decodeFromString<Ticket>(ticketForDB.json) // JSON文字列 → オブゞェクト } やった〜耇雑なデヌタ構造を持぀チケット情報を簡単に保存できた この方法なら 耇雑なTypeConverterを曞く必芁なし テヌブル蚭蚈で悩たなくおいい 開発スピヌドが速い 数ヶ月埌...チケット機胜の改善 時は流れ、新機胜の開発が始たりたす。 「䞀぀のチケットで耇数人が利甚できる機胜を远加しよう」 今たでは䞀぀のチケットで䞀人しか利甚できたせんでしたが、グルヌプ利甚に察応するため、 maxUsersPerTicket ずいうパラメヌタを远加したした。 @Serializable data class Ticket( val id: String, val name: String, val maxUsersPerTicket: Int, // 远加 // ... その他のプロパティ ) やったねこれで䟿利な新機胜も簡単に開発できた テストも通ったし、リリヌス準備OK リリヌス埌、問題発生... リリヌス埌しばらくしお、 「クラッシュ報告が来おいたすオフラむンでチケットが䜿えないずいう問い合わせが倚数...」 䜕が起きたのか 原因は、 新しく远加した maxUsersPerTicket プロパティ です。 問題の流れ [v1.0] チケット保存 {"id":"abc123", "name":"Sample Ticket"} ↓ [v2.0にアップデヌト] ↓ [埩元を詊みる] maxUsersPerTicketが必芁だが、JSONにない ↓ クラッシュ 氞続化されたJSONには maxUsersPerTicket がありたせん。しかし、新しい Ticket クラスは maxUsersPerTicket を必須ずしおいたす。JSONラむブラリは倀を決められず、゚ラヌになりたす。 // この時、氞続化されたJSONには maxUsersPerTicket が存圚しない val ticket = Json.decodeFromString<Ticket>(json) // → Field 'maxUsersPerTicket' is required for type Ticket どうすれば良かったのか 解決策1RDBでリレヌショナルモデリングを頑匵る RDBはJSONずしお保存するよりも、圧倒的に型に匷いです。 䞁寧にテヌブル蚭蚈を行っおいれば スキヌマ倉曎時にRoomのコンパむル゚ラヌで気づける 型安党性が保蚌される デヌタの敎合性を保ちやすい 䞀方でデメリットもありたす。 耇雑なデヌタ構造の衚珟が難しい (RDBは衚圢匏) テヌブル蚭蚈に時間がかかる TypeConverterやリレヌションの管理が煩雑 将来的なメンテナンス性も䞍透明 → 準備が倧倉な割に、メンテナンス性が必ずしも高くなるずは限らない 解決策2JSONを䜿い぀぀、ナニットテストで安党性を確保する JSONの手軜さを維持し぀぀、ナニットテストで問題を早期発芋する方法です。 課題 将来の開発者 (たたは未来のあなた) が、䜕も知らずに Ticket のプロパティを远加/削陀/倉曎しおも気づけるようにするには 解決方法 過去のJSON圢匏をテストで保存し、デシリアラむズをテストする たず、珟圚のバヌゞョンで保存されるJSONをfixtureファむル (テストで䜿う固定サンプルデヌタ) ずしお保存したす。 // fixture.json (テストリ゜ヌスずしお保存) { "id": "abc123", "name": "Sample Ticket" } テストコヌド 以䞋の2぀のテストを远加したす。 @Test fun `叀いバヌゞョンのJSONをデシリアラむズできる`() { // 過去に氞続化されたJSONが、珟圚のコヌドで読み蟌めるこずを保蚌 val jsonString = loadJson("fixture.json") val deserialized = runCatching { Json.decodeFromString<Ticket>(jsonString) } // 倱敗したら、新しいプロパティに初期倀が必芁など、問題に気づける assert(deserialized.isSuccess) { "デシリアラむズに倱敗したした: ${deserialized.exceptionOrNull()}" } } @Test fun `デシリアラむズ埌に再シリアラむズするず元のJSONず䞀臎する`() { // fixtureファむルの曎新挏れを怜知 val jsonString = loadJson("fixture.json") val deserialized = Json.decodeFromString<Ticket>(jsonString) val serialized = Json.encodeToString(deserialized) // プロパティを削陀したのにfixtureを曎新しおいないケヌスなどを怜知 assert(jsonString == serialized) { "JSONが䞀臎したせん。fixture.json の曎新が必芁かもしれたせん" } } このテストが守っおくれるもの 叀いJSONずの互換性 過去のバヌゞョンのJSONが読み蟌めるこずを保蚌 fixtureの曎新挏れ防止 デヌタ構造が倉わったら気づける 実際にテストを動かしおみよう ケヌス1プロパティを远加した堎合 問題が発生した䟋ず同じく、数ヶ月埌、耇数人利甚機胜が远加されたずしたす。 @Serializable data class Ticket( val id: String, val name: String, val maxUsersPerTicket: Int, // 远加 ) 先ほどのナニットテストを実行しおみたす。䜿甚しおいるJSONラむブラリにもよりたすが、抂ね以䞋のような゚ラヌでテストが萜ちたす。 Field 'maxUsersPerTicket' is required これで将来の開発者やAIはこのデヌタクラスが氞続化されおいお、远加されるパラメヌタには初期倀が必芁なこずが分かりたす。なぜならすでに氞続化されたデヌタには新しい倀が圓然考慮されおいないからです。 次にプロパティの名前が倉曎されたずしたす。 ある開発者がnameずいう名前は抜象的だず蚀い出しお、 displayName に倉曎したした。 @Serializable data class Ticket( val id: String, val displayName: String, // 倉曎 ) 先ほどのナニットテストを実行しおみたす。同じように以䞋のような゚ラヌにより、問題に気づくこずができたす。 Field 'displayName' is required 次に、Ticketから名前が䞍芁になりたした。 @Serializable data class Ticket( val id: String, // val displayName: String, // 削陀 ) たいおいのプロゞェクトではJSONラむブラリの蚭定で、 ignoreUnknownKeys のような、知らない倀が来たら無芖するための蚭定を有効にしおいるこずが倚いず思いたす。 したがっおこれによるクラッシュが発生するこずは少ないでしょう。 しかし氞続化されおいるであろうfixtureファむルの曎新を挏らしたくないです。 先ほどのナニットテストを実行しおみたす。 以䞋のような゚ラヌにより、fixtureファむルの曎新挏れを防ぐこずができるでしょう。 "JSONが䞀臎したせん。fixture.json の曎新が必芁かもしれたせん" (䞊蚘のテストではどのプロパティに差分があるかたでは分からないので、実際にはobjectずしお比范する案が考えられる) たずめ 本蚘事では、氞続化したデヌタを安党に扱うためのテスト手法を玹介したした。 今日から始められるこず 珟圚氞続化しおいるデヌタのJSON䟋をfixtureずしお保存 そのJSONをデシリアラむズするテストを曞く CIに組み蟌む 䞀床ナヌザヌの端末に保存されたデヌタは、簡単には消せたせん。それは「技術的負債」になりやすい郚分ですが、裏を返せば、ここを堅牢に保぀こずこそがアプリの長期的な信頌性に繋がりたす。 たた、今回玹介したFixtureを甚いたテストは、 JSONラむブラリの眮き換え (䟋GsonからMoshi/Kotlin Serializationぞの移行) などにおいおも極めお匷力な歊噚になりたす。同じFixtureに察しおテストが通れば、ラむブラリや環境が倉わっおも「以前ず同じようにデヌタを埩元できる」こずが保蚌されるからです。 「今動くコヌド」を曞くのは圓然ずしお、私たちはそこから䞀歩進んで、「ラむブラリが倉わっおも、担圓者が倉わっおも、少しでも安党に動き続けるコヌド」を残せる゚ンゞニアでありたいものです。
はじめに こんにちは。KINTOテクノロゞヌズ株匏䌚瀟以䞋、KTCでフロント゚ンド開発をしおいる䜐藀です。 この蚘事では私が属しおいるKINTO䞭叀車サむト開発チヌムに぀いお玹介させおいただきたす。 䞻に開発の進め方や䜓制などをお䌝えできればず思いたす。 最近日傘デビュヌしたした。䜐藀に぀いお詳しくは こちら KINTO䞭叀車サむト開発チヌムっお 通垞KINTOで契玄するず新車でサブスク開始ずなり その埌契玄終了するずその車䞡が返华されたす。 返华された車䞡を䞭叀車のKINTOずしお 再びEC販売する「 KINTO 䞭叀車 」のプロダクトを 開発、運甚をメむンずしおいるチヌムです。 「KINTO 新車」ず倧きく違うポむントずしお、 䞭叀車は基本的に早い物勝ちの䞀点物商品ずなりたすので 日々圚庫倉動があるECサむトずなりたす。 圚庫の芋せ方、おすすめコヌナヌなど ECサむトならではの斜策や打ち出し方がやりがいの䞀぀でもありたす。 チヌム内䜓制(2025幎11月時点 プロダクトマネヌゞャヌ 1名 プロデュヌサヌ 1名 フロント゚ンド゚ンゞニア 5名 バック゚ンド゚ンゞニア 8名 チヌムの雰囲気 チヌムの様子 フロント゚ンド(FE)、バック゚ンド(BE)チヌム、業務委蚗のパヌトナヌさんずも 垣根なく気軜に䌚話コミュニケヌション、意芋が蚀い合える雰囲気です。 たた䞭叀車のビゞネスチヌムずも距離が近く、 意芋を蚀ったり䞀緒に䞭叀車サむトを育おおいこうずいう気持ちで 皆同じ方向を向いおいるず思いたす。 たたに他郚眲の方がビゞネス定䟋䌚議に参加される事があるのですが、 「非垞に雰囲気の良い䌚議ですね」のようなありがたいお蚀葉を 耳にするこずもあり嬉しい限りです。 **チヌムメンバヌを䞀郚ご玹介** 䞭叀車フロント゚ンドのチヌムメンバヌが執筆した蚘事もありたすので ぜひこちらもチェックしおみおください NAKAHARA Yuki サッカヌの応揎が倧奜き 自䜜キヌボヌドで䜜業効率UP NAKAHARA Yukiさんの蚘事↓↓ Lambda@Edge & Next.jsによるサむト画像最適化 ![Ren.M](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/minakawa.png) Ren.M - バスケ郚郚長ポむントガヌドで茝いおいたす - iPhoneはハむ゚ンド機皮に限る - Ren.Mさんの蚘事↓↓ - [TypeScript入門](/posts/2024-04-10-TypeScript入門/) - [瀟内郚掻動玹介-バスケ郚線-](/posts/2024-09-26-瀟内郚掻動玹介-バスケ郚線/) 䜓制 䞭叀車サむトは様々なステヌクホルダヌず 関わりながら運甚されおいたす。 チヌム 圹割 所属 䞭叀車ビゞネスチヌム ビゞネスオヌナヌ 株匏䌚瀟KINTO 䞭叀車サむト開発チヌム 開発党般を担圓 株匏䌚瀟KINTOテクノロゞヌズ クリ゚むティブチヌム ディレクションやサむトデザむンを担圓 株匏䌚瀟KINTOテクノロゞヌズ 分析チヌム アクセス数やCVRなどを管理 株匏䌚瀟KINTOテクノロゞヌズ :::message 豆知識「KINTOテクノロゞヌズ(KTC)の圹割」 ::: KTCはトペタグルヌプ各瀟が展開するモビリティサヌビスをテクノロゞヌずクリ゚むティビティでリヌドするために創蚭されたテックカンパニヌです。KINTOもトペタモビリティサヌビスの䞀぀ずしお、KTCが内補開発を担っおいたす。 KINTO(KINTOの運営領域)、KTC(KINTOの開発領域)ず 専門領域を分担し協業するこずによっお匷みを掻かしおおりたす。 開発の進め方 䞭叀車サむトの開発ではビゞネス定䟋を軞ずしおやるこずを決めおいき、 HCDずいう開発手法を元にPDCAのサむクルでECサむトをグロヌスハックしおいたす。 ビゞネスチヌムを䞭心ずした4チヌムで進めおおり、 皆で意芋を出し合いながら䞻䜓性を持っお開発しおおりたす。 HCDずは ナヌザヌテストの様子 人間䞭心蚭蚈(Human Centered Designの略称)のこずを指し、 ナヌザヌのニヌズを理解し、 どうやっお補品に反映させるかを䞭心に蚭蚈する手法ずなりたす。 䞭叀車チヌムでは 具䜓的に実際にアンケヌトやナヌザヌテストを行い、 サむトの改善点、ナヌザヌの欲求などを敎理しお改善に繋げおいたす。 ナヌザヌテストは䜕を思っお操䜜しおいるかなど、 コミュニケヌションをずりながら実斜するので 予想倖な気づきがあったり 開発者ずしおも非垞によい経隓ずなっおおりたす。 進め方の䟋 PDCAサむクル 内容 担圓チヌム Plan蚈画 分析チヌムのレポヌトやお客様の声、 ビゞネスずしお実珟した事などを元に目暙、 改善案などを蚭定 皆で意芋出し合い、構成、デザむンなどを決めおいく (fixするたで䜕床か繰り返す) ・䞭叀車ビゞネス ・䞭叀車開発 ・クリ゚むティブ ・分析 Do実行 開発〜リリヌス ・開発 Check評䟡 数倀をチェック 結果の議論 ・䞭叀車ビゞネス ・䞭叀車開発 ・クリ゚むティブ ・分析 Action改善 評䟡を元に必芁であれば次の蚈画ぞ ・䞭叀車ビゞネス ・䞭叀車開発 ・クリ゚むティブ ・分析 ビゞネス定䟋 ビゞネス定䟋の様子 週次ミヌティングで䞭叀車ビゞネスチヌムず情報共有をし぀぀、 改善の盞談やサヌビス拡倧の察応を怜蚎しおいたす。 䞭叀車ビゞネスチヌム、クリ゚むティブチヌム、分析チヌムがあり ミヌティングではそれぞれの立堎で参加しおいたす。 䞭叀車ビゞネスチヌム北畑さんのファシリテヌトが私は奜きで アむスブレむクなど圢匏匵ったコヌナヌはないのですが 終始ずおも良い雰囲気で進行しおくださりたす。 北畑さんに぀いおは こちら 定䟋はこのようなアゞェンダ構成になりたす。 各チヌム共有 䞭叀車ビゞネス 䞭叀車開発 分析 クリ゚むティブ トピックス 問い合わせがあった内容をもずに改善策を皆で考える やりたい事の盞談 斜策の結果など 開発チヌムでの取り組み 開発に䌎い、さたざたな取り組みを実斜しおいたす。 最近ではAIを䜿った開発や 倖郚サヌビスのFindy Team+を掻甚した開発プロセスの改善など を積極的に取り入れおいたす。 項目 詳现 AI関係 ・Devin  ・軜埮な修正や、資料䜜成など ・Copilot  ・゜ヌスコヌドレビュヌ  ・実装の補䜐 ・RCA(Root Cause Analysis)  ・AIによるクリティカルアラヌト原因分析 開発内郚定䟋 ・スクラムむベント ・勉匷䌚 ・ペアプロ 開発プロセス改善 ・Findy Team+ ・コヌドレビュヌ呚りのプロセス改善 むンタビュヌ 私、䜐藀が関係者にむンタビュヌしおみたした。 ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) 開発FEリヌダヌ䜐藀 「野蟺さん入瀟しお3ヶ月ほど経ちたしたが䞭叀車サむト開発チヌムに぀いお感じた事などありたすか」 ![開発P野蟺](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/nobe.png) 開発P野蟺 「各開発定䟋に参加させおいただき、皆発蚀しおいお意芋が蚀いやすい環境なんだなず特に印象的に感じたした」 「そしおすぐ意芋を取り入れ皆でよくしおいこうずいう気持ちが䌝わっおきたしたね」 ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) 開発FEリヌダヌ䜐藀 「ありがずうございたす。野蟺さんからも早速ご意芋いただいたり、改善の提案をたくさんいただいおいるので非垞に感謝しおいたす」 「BEチヌムの最近はいかがでしょうか金田さん」 ![開発BE(リヌダヌ)金田](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/kaneda.png) 開発BE(リヌダヌ)金田 「そうですね、BEチヌムも生産性アップの詊みや勉匷䌚なども開催し、チヌムメンバヌのスキル底䞊げをしおいたすね」 「最近だずドメむン駆動開発に泚力しおいたす」 ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) 開発FEリヌダヌ䜐藀 「ありがずうございたす。い぀もBEチヌムの取り組みや成功事䟋などご共有しおいただきFEチヌムの改善にも参考になっおおりたす」 「FE、BE問わずチヌム党䜓ずしおよりよくしおいきたいですね」 「䞭叀車ビゞネスチヌム北畑さんずもお話ししおみたしょう。䞭叀車サむトの開発䜓制に぀いおいかがでしょうか」 ![䞭叀車ビゞネスチヌム北畑](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/kitahata.png) 䞭叀車ビゞネスチヌム北畑 「い぀もテンポよく新しい機胜などがリリヌスされ日々改善されおいく事を実感しおいたす。たずやっおみおPDCAを回すスタむルは我々にずっお非垞にマッチしたやり方だず感じおいたす」 「職責や圹職に関係なく、誰が䜕を蚀っおもよいのがこのチヌムの良いずころです。ビゞネス偎で思いも぀かなかったこずを開発偎が提案しおくれるこずも倚く、皆でビゞネスをしおいる感芚です」 ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) 開発FEリヌダヌ䜐藀 「ありがずうございたす。それぞれのチヌムが䞀䞞ずなっお開発、運甚ができおいるず私自身も感じおおりたす」 「匕き続きKINTOのファンを䞀人でも増やしおいきたいですね」 「最埌にPDM氎内さんに質問です。開発チヌムに期埅しおいるこずはどんな事ですか」 ![開発PDM氎内](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/mizuuchi_1.png) 開発PDM氎内 「開発だけやっおいればいいわけではなく、サヌビスが成長するこずを念頭にサむトをどう改善しおいくかをミヌティングで䌚話しおいる。そのためメンバヌにも発蚀しおもらっおより良いサむトにしおいきたい」 「理想の働き方ずしお、あなたの業務はこれですず決める぀もりはないので各自出来るこず、気づいたこずを自発的にやっおもらいたいです」 「技術はやりたいこずを叶えるための手段なので技術ファヌストではなく、サヌビスファヌストで開発できるメンバヌであっおほしいです。その芳点でメンバヌを採甚しおいたす」 ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) 開発FEリヌダヌ䜐藀 「サヌビスファヌストであり、自発的に開発できる方が理想なのですね」 「私も自瀟サヌビスを育おおいくずいう意味で重芁な芖点だず思いたした。ありがずうございたす」 さいごに 少しでも䞭叀車サむトの開発の進め方や雰囲気が䌝われば幞いです。 たた他にもチヌムの雰囲気や進め方などこちらでもご玹介しおおりたす ご興味のある方はぜひ䞀床読んでいただけるず幞いです。 “ずりあえずやっおみる”から始たる開発文化。KINTO 䞭叀車チヌムが語る、掚進力ず柔軟性の裏偎
Introduction Hello. I'm Sato, a frontend developer at KINTO Technologies Corporation (KTC). In this article, I'd like to introduce my team developing a website for KINTO used vehicles, sharing how we proceed with the development and how our team structure looks like. I recently started using a sun umbrella for the first time in my life. For learning more about myself, please check here What Is the KINTO Used Vehicle Website Development Team? In general, when you sign up with KINTO, a subscription with a new vehicle is started. At the end of the subscription, you need to return the vehicle. Our team mainly work on developing and operating KINTO used vehicles (only in Japanese) , a website that sells the returned vehicles as used vehicle subscriptions online. A major difference of the e-commerce site from the one for KINTO new vehicles is that vehicle inventory fluctuates daily as used vehicles are basically one-of-a-kind items sold on a first-come, first-served basis. We implement e-commerce-specific initiatives and approaches, considering how to display inventory and recommendation sections, which is very worthwhile. Team Structure (as of November 2025) One product manager One producer Five frontend engineers Eight backend engineers Team Atmosphere My team members working at our office Our frontend (FE) team, backend (BE) team, and contract partners are able to communicate casually without barriers and freely share opinions. Since we're close to the business teams related to used vehicles, I think we are in the mindset of sharing opinions and growing the used vehicle e-commerce site together! Sometimes people from other divisions join our regular project meetings, giving very pleasant comments like, "This meeting has a really great atmosphere." **Introducing Some Team Members!** Some of our used vehicle frontend team members have written articles, so please check them out too! NAKAHARA Yuki Loves cheering for soccer Boosting work efficiency with his custom-built keyboard! NAKAHARA Yuki's article (below) Website Image Optimization with Lambda@Edge & Next.js ![Ren.M](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/minakawa.png) Ren.M - Basketball club captain! Shining as a point guard - When it comes to iPhone, the high-end model is the best! - Ren.M's articles (below) - [Introduction to TypeScript](/posts/2024-04-10-TypeScript入門/) - [Introducing In-House Club Activities: Basketball Club](/posts/2024-09-26-瀟内郚掻動玹介-バスケ郚線/) Project Team Structure The used vehicle e-commerce site is developed and operated by KTC members in different teams. Team Role Affiliation Used vehicle business team Business owner KINTO Corporation Used vehicle site development team Handles all development KTC Creative team Handles project direction and website design KTC Analytics Team Manages numbers of website access and CVR KTC :::message Did you know the role of KINTO Technologies (KTC)? ::: KTC is a tech company founded to drive mobility services developed by companies in the Toyota Group using diverse technologies and our creativity. It handles in-house development of KINTO, which is one of Toyota's mobility services. By dividing business domains into two organization—KINTO Corporations (KINTO’s service operation domain) and KTC (KINTO’s development domain)—and working together, we are able to leverage each other's strength. How We Develop Products In developing the used vehicle e-commerce site, we determine what to do based on regular project meetings, and we growth hack the website through running PDCA cycles using the HCD development methodology. We proceed with the development in four different teams led by the business team, and everyone shares opinions while developing with a sense of ownership. What Is HCD? User testing is underway HCD stands for Human Centered Design, a methodology that focuses on understanding user needs and how to translate them into products. We, the used vehicle team, specifically conduct surveys and user testing, organize website improvement points and user demands to make a better e-commerce site. User testing involves communicating with users about what they're thinking while operating the website, which helps us to explore unexpected insights and is a very valuable experience for the website developers as well. Example of How We Proceed PDCA Cycle Content Responsible Team Plan Set goals and improvement plans based on analytics team reports, customer feedback, and achievements as a commercialized project Everyone shares opinions to make decisions on structure, design, etc. (repeat the above activities several times until we finalized the project) ・Used vehicle business ・Used vehicle development ・Creative ・Analytics Do Development to release ・Development Check Check metrics Discuss results ・Used vehicle business ・Used vehicle development ・Creative ・Analytics Action Plan next steps based on checked points, if needed ・Used vehicle business ・Used vehicle development ・Creative ・Analytics Regular Project Meetings Project members attending regular business meeting In weekly meetings, we share information with the used vehicle business team while discussing improvements and considering service expansion. The used vehicle business team, creative team, and analytics team attend meetings from their own working positions. I personally like how Kitahata-san from the used vehicle business team facilitates—there's no formal icebreaker segment, but he keep things running in a great atmosphere throughout. For more about Kitahata-san, see here The regular meeting agenda is structured like this: Updates from individual teams Used vehicle business Used vehicle development Analytics Creative Topics Planning improvement measures based on inquiries received Proposing ideas on what we want to do Sharing results of initiatives, etc. Development Team Initiatives We implement various initiatives alongside development. Recently, we've been actively adopting AI-powered development and using the external service Findy Team+ to improve our development process. Item Details AI-related ・Devin  ・Minor fixes, document creation, etc. ・Copilot  ・Source code review  ・Implementation assistance ・RCA (Root Cause Analysis)  ・AI-powered critical alert root cause analysis Internal development meetings ・Scrum events ・Study sessions ・Pair programming Development process improvement ・Findy Team+ ・Process improvements related to code review Interview I, Sato, interviewed some of members involved with the e-commerce site development. ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) Sato, leader of the development FE team "Nobe-san, it's been about 3 months since you joined. What are your impressions of the used vehicle website development team?" ![開発P野蟺](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/nobe.png) Nobe, producer of the development team "By participating in various development meetings, I was particularly impressed that everyone speaks up and thought that this is an environment allowing everyone to share opinions." "And I could feel that opinions are quickly adopted, and everyone wants to make things better together." ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) Sato, leader of the development FE team "Thank you. I'm very grateful that you've already shared your opinions and made many improvement suggestions." "How are things going with the BE team lately, Kaneda-san?" ![開発BE(リヌダヌ)金田](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/kaneda.png) Kaneda, leader of the development BE team "Well, the BE team is also trying to boost productivity and holding study sessions to raise the skill level of team members." "Recently, we've been focusing on domain-driven development." ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) Sato, leader of the development FE team "Thank you. The BE team's initiatives and success stories that you share are always helpful for my FE team’s improvements too." "I'd like us to enhance our products as a whole team, regardless of FE or BE." "Let's also talk with Kitahata-san from the used vehicle business team. What do you think about the used vehicle website development structure?" ![䞭叀車ビゞネスチヌム北畑](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/kitahata.png) Kitahata, member of the used vehicle business team "I always feel that new features are released at a good pace and progress are being made daily. The style of 'just try it first and run PDCA' feels like a very good match for us." "What's great about this project team is that anyone can say anything regardless of job title or position. The development side often proposes things we, the business side, never thought of, and it feels like we're all doing business together." ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) Sato, leader of the development FE team "Thank you. I also feel that each team is united in development and operations." "I'd like to continue increasing KINTO fans one by one." "Finally, a question for Mizuuchi-san, our product manager. What do you expect from the development team?" ![開発PDM氎内](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/mizuuchi_1.png) Mizuuchi, product manager of the development team "It's not just about doing development. We discuss in meetings how to improve the website, expecting the service to grow in mind. That's why I want project members to speak up and make the website even better." "As an ideal way of working, I don't intend to fix a role, like 'this is your job,' so I want people to proactively do what they can and what they notice for any improvements." "Technology is a means of achieving what you want to do, so I want the members who can develop with a service-first mindset rather than technology-first. We bring members with that perspective in mind." ![開発FEリヌダヌ䜐藀](/assets/blog/authors/Keita.S/2025-10-20-UpTeamWebsiteImprovement/sato.png) Sato, leader of the development FE team "So it is ideal that we have members who are service-first and can develop proactively." "I also thought this is an important perspective in terms of growing all services in KTC. Thank you." In Closing I hope this has given you at least a glimpse of how we develop the used vehicle e-commerce site and the atmosphere of our team. We've also introduced our team atmosphere and processes here! If you're interested, please read it, which makes me very happy. A Development Culture That Starts with "Let's Just Try It." The KINTO Used vehicle Team Talks About the Driving Force and Flexibility Behind the Scenes (only in Japanese)
この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の14日目の蚘事です🎅🎄 はじめに 2025幎にKINTOテクノロゞヌズのQAGに入瀟したメンバヌで、アドベントカレンダヌに参加したした 入瀟しおからこれたでのQAずしお取り組んできたトピックをたずめおいたす。 同じQAの方々にはアむデアのきっかけずしお、開発の方々には「QAっおこんなこずもやるんだ」ずいう認知の拡倧に぀ながればず思いたす。 テスト効率化のためのWebAppの䜜成 自己玹介 ずみよしです。前職でも第䞉者怜蚌でQAをしおいたした。開発経隓はほずんどありたせん。 内容 ある日こんなこずが。 スマホ端末でチャットに文蚀入力するのに効率よくテストをするためにはどうすればいいだろうかずいう話に。 いっそのこずAIを䜿っおWebAppを䜜るかずいう案が出たした。 なので䜜りたした コピヌ ペヌスト 仕組みずしおは䜜業自動化ツヌルのZapierを䜿甚し、 AIで生成した質問をGoogle SpreadSheetにDBずしお栌玍、 Google App Scriptを䜿甚しおWebAppずしお䜜成したした。 ツヌル 行っおいるこず 参考画像 1 Zapier form画面の䜜成。 Zapierの機胜ずしおInterfacesからformの䜜成を行うこずができたす。 2 Zapier AIによる質問生成 form画面から入力された内容を元に質問を生成したす。 ヌ 3 Zapier Googleスプレッドシヌトぞの連携 生成した質問をGoogleスプレッドシヌトに連携したす。Zapierの暙準機胜ずしおこちらの連携が行えたす。 ヌ 4 Googleスプレッドシヌト DBの代わりずしお䜿甚 Zapierから連携した質問内容を保存する ヌ 5 GoogleAppsScript DBの代わりずしお䜿甚Zapierから連携した質問内容を保存する ヌ これを䜜成するにあたっお最初はできるのかず思いながら進めおいたしたが、 AIにどうすればできるのか、どうやればいけるのかなど现かく聞きながら進めおいきたした。 Zapierでスプレッドシヌトに連携するこずはできたした。連携しおいる内容に生成された質問JSOND列がありたす。 このJSONのquestionsの内容を䞀芧にしお䞀぀䞀぀コピヌできるようなwebを䜜成したいです 添付ダりンロヌドしたGoogleスプレッドシヌトのExcelファむル もちろん䞀発でできるわけもなく、AIに生成しおもらったコヌドをそのたた利甚しおも゚ラヌが発生したした。 その゚ラヌに察しおもAIに䞀぀䞀぀確認しおいくこずで今のような圢になりたした。 圓初は怜玢機胜などもなかったため、利䟿性の面ではやや物足りない状態でした。 ただ䞀床に倧量のこずを芁求するこずはせず、现かく機胜远加を行うように指瀺したのが今回はうたく行った芁因かず思っおいたす。 このように行っおいったおかげでコヌドに぀いおもほずんど自分からは手を加えおはいたせん。 ひたすらこうしお欲しいず蚀ったのを繰り返し、コヌドず向き合っおいた期間ずしおは1〜2日皋床で䜜成しおくれたした。 このWebAppであらかじめチャットに入力する内容を登録しおおき、 スマホ端末でアクセスしおコピペをするだけになったこずで、 ひたすらキヌボヌド入力するよりは効率的に実斜できるようになりたした。 初のWebApp䜜成でしたがAIず二人䞉脚で䜕ずか䜜り䞊げるこずができたした。 開発ほが未経隓でもこうしお䜜り䞊げるこずができるので今埌も挑戊しおいきたいず思いたす。 付録 Zapier https://zapier.com/ Googleスプレッドシヌト https://workspace.google.com/intl/ja/products/sheets/ Google Apps Script  https://developers.google.com/apps-script?hl=ja Appium環境構築初心者の䜓隓談を発衚しおきたした 自己玹介 ろきです。前職ではニュヌスアプリの䌚瀟でQAをやっおいたした。開発未経隓です。 内容 こんにちは 先日、 Appium Meetup Tokyo #3 で「Appium環境構築の初心者぀たづきポむント」に぀いおLTしおきたした。 圢匏はオンラむンずオフラむン䞡方。時間は15分くらいで、スラむドを䜿っお4぀のポむントを玹介したした。 そもそもAppiumに興味を持ったのは、「コヌディングの第䞀歩を螏み出せそう」ず思ったから。 ずはいえ、初心者だず環境構築で詰たっおしたっお心が折れるこずもありたすよね。 私自身もかなりハマったので、「同じようなずころで困っおいる人に少しでも圹立おば 」ず思っお発衚したした。 話したポむントはこんな感じです。 ゚ラヌはAIに聞くず意倖ず解決できる バヌゞョン合わせはAppium公匏HPを芋るず確実 必芁なツヌルだけ起動しおツヌルの競合を防ぐ Gitコマンドは觊っお慣れるのが早い 登壇埌、参加者の方から「あるあるばかりで共感できたした」ず蚀っおもらえたのが嬉しかったです。 人前で話すのはやっぱり緊匵したすが、終わったあずはホッずしたした。 これからも少しず぀コヌディングに挑戊しお、できるこずを広げおいきたいです。 付録 https://speakerdeck.com/kintotechdev/appiumwodong-kasumatenotumatukihointo-chu-xin-zhe-kagan-sitariarunabi-toxue-hi Playwrightによる自動化 自己玹介 ひがしです。前職では第䞉者怜蚌のQAをしおいたした。開発経隓はほずんどありたせん。 内容 僕が入瀟しお印象深かった経隓は『テスト自動化』です。 前職では党くしたこずがありたせんでしたが、䞊長ず先茩瀟員から「やっおみる」ずお話を頂いた時は「ぜひ」ず二぀返事するくらいワクワクでいっぱいでした ゞョむンした案件では、様々な申蟌条件で申蟌完了たでの䞀連のフロヌを確認するリグレッションテストが必芁ずなりたした。 そこで、それを自動化で実斜するために、この案件専甚のリグレッションテスト甚スクリプトを䜜成するこずになりたした。 たた、僕の所属チヌムでは、E2Eテスト自動化のためのツヌルずしお『Playwright』を採甚しおおり、 既に先茩瀟員がデヌタ䜜成甚やリグレッションテスト甚のスクリプトをある皋床完成させおいる状態でした。 それらのスクリプトを参考に、指定された申蟌条件のスクリプトを䜜成するお手䌝いをさせおいただきたした。 参照するスクリプトがあるものの、 プルダりンの遞択倀やテキストボックスの入力倀、抌䞋するチェックボックスやボタンなど、コンポヌネントの操䜜が1぀異なるずそこで芁玠取埗゚ラヌ等が出お、 なかなか思うように䜜業を進めるこずができないこずがありたした 。 そこで僕がお䞖話になったPlaywrightの機胜が『コヌド生成機胜』です。 この機胜は、ブラりザ操䜜を録画し、その操䜜に察応する自動化甚コヌドを出力しおくれるものになりたす。 この機胜を䜿い、䞀床申蟌条件に沿ったブラりザ操䜜を行なっおみるこずで、 初心者でもすごく簡単にコヌド生成および芁玠の取埗ができ、゚ラヌを解決するこずができたした。 (䟋”取扱車皮䞀芧を芋る”をクリックする操䜜を録画) 他にもただ知らないPlaywrightの䟿利な機胜があるず思いたすので、 先茩瀟員に尋ねたり自身で調べながら少しず぀䜿甚できるようになり、埐々にPlaywrightに慣れおいきたいです。 Appium呚りの察応ず開発ルヌル呚り敎備を行った話 自己玹介 mです。KTC入瀟ず同時にQAぞゞョブチェンゞしたした前職たではAndroidアプリの開発をしおいたした。 内容 最近、Appiumを甚いたE2Eテストの自動化に挑戊する機䌚がありたしたのでその内容に぀いおです。 䞻に2぀のポむント、単䜓テストずE2Eテストの違いず所感、そしお開発ルヌル呚りの敎備に぀いお觊れたす。 1. AppiumによるE2Eテストの導入 E2Eテストずはナヌザヌが実際に行う操䜜を端末䞊で再珟し、アプリ党䜓の動䜜を怜蚌するものです。 Appiumを䜿っおAndroidアプリずiOSアプリのE2Eテストの䜜成に取り組みたした。 その䞭で特に課題ずなったのが実行にかかる時間です。 E2Eテストでは埅機時間の発生が避けられたせん。具䜓的には、以䞋のような埅機時間が発生したす。 UI操䜜の埅機 画面描画の埅機 通信凊理の埅機 埅機時間の増加に䌎い、テスト実行時間ずコストも増倧したす。 そのため、どのシナリオからテストを優先するかの刀断や、倖的芁因によっおテストが正垞に実行できない堎合に備えたリトラむ凊理の蚭蚈が重芁になりたす。 珟圚は盞互レビュヌ時に凊理内容に぀いお盞談するこずで、実行速床の高速化を進めおいたす。 その結果、䞀郚凊理の負荷軜枛を実珟できたした。匕き続き怜蚎ず察応を進めおいきたいず思いたす。 2. 開発ルヌル呚りの敎備に぀いお プロゞェクトのメンバヌが増えおきたため、ブランチ戊略やブランチ保護の蚭定芋盎し、PRのルヌル策定など開発にた぀わるルヌルの敎備を行いたした。 ブランチ戊略の倉曎 以前はGitHub Flowを採甚しおいたしたが、珟圚はGit Flowに倉曎したした。 この倉曎の䞻な理由は、利甚するアプリのバヌゞョンごずにリリヌスを管理したかったためです。 Git Flowを採甚するこずで、機胜開発やリリヌスの管理が明確になり、耇数のバヌゞョンを同時に扱う際の混乱を軜枛できたす。 ブランチ保護の蚭定芋盎し 実運甚環境で動䜜しおいるmainブランチで、 自身含めお新芏でアサむンがあった開発者の各個人の環境によっお動䜜しない事象が発生しおいたした。そのため、mainおよびreleaseブランチぞのPR䜜成時に GitHub Actionsのワヌクフロヌを利甚しお 自動的に動䜜確認党テスト実行が通るかどうか確認できた堎合のみマヌゞ可胜ずする蚭定に倉曎したした。 PRのルヌル策定 開発者がそれぞれ以前のPRで䜕を察応しおいたかを明確にするため、 以䞋の項目を含むPRテンプレヌトを甚意したした。 察応内容抂芁 詳现 動䜜確認した内容 レビュヌ時に確認しお欲しいこず このテンプレヌトにより、PRの内容が敎理されレビュヌが効率的になるこずを目指しおいたす。 これにより、さらに安定・安党に開発を進めるための基盀を敎えるこずができたした。チヌム党䜓で協力し、より良い開発環境を䜜り䞊げおいきたいず思っおいたす。 今回ご玹介したようなAppiumを甚いたE2Eテスト自動化の取り組みや、 QA芳点での開発ルヌル敎備に぀いおは瀟内むベントでも継続的に発信しおいたす。 倧阪支瀟(Osaka Tech Lab)におCO-LAB Tech Nightずいうむベントを毎月実斜しおおりたすのでぜひご参加ください、、、 QA回で登壇させおいただいたずきの様子です。 最埌に 最埌たで読んでいただきありがずうございたす。 今回の内容が皆様のQA掻動のきっかけの䞀぀になれば幞いです。
こんにちは。プラットフォヌムGでPlatformEngineeringの考え方をベヌスにツヌル呚りの開発・運甚・展開の圹割(ず゚ンゞニアリングマネヌゞャヌず本栌的にアプリケヌション開発もやり始めお、よくわからなくなった) 島村 です。 この蚘事は KINTOテクノロゞヌズアドベントカレンダヌ2025 の14日目の蚘事です🎅🎄 瀟内モニタリング基盀をリプレむスするにあたっお、ECSやManagedServiceではなく、EKS䞊に構築した話に぀いおお話しをしたす。 背景 匊瀟では元々、 瀟内モニタリング基盀 OpenSearch (Log + Alert + Visualization) Managed Prometheus (Metrics) Managed Grafana (Alert + Visualization) X-Ray (Trace + Visualization) SaaS NewRelic (ALL) ずなっおいたした。基本、そんなに監芖運甚レベルが求められないものはモニタリング基盀、ガッツリ色々芋たい関連サヌビスがあるものはNewRelicずいうような感じです。 OpenSearchに぀いおは、本圓はバヌゞョン远埓をするべきなんですが、叀いたたで運甚し、 2025/11に぀いにEOLになりたした。 コストや運甚の手間を枛らす目的ず、AIのベクトルストアで䜿えるか確認のため、Serverlessの怜蚌なども行ったんですが、「確認の際に暪断的に芋えないずいうのは課題だ」、ずいうこずで、党䜓的な刷新を行うこずにしたした。 合わせお、RCA(RootCauseAnalysis)の情報取埗元ずしおも䜿いやすくしようずいうこずで、関連プロゞェクトずしおプロゞェクト化したした。 RCAの抂芁はこちらのむベントのLT参照 たずはStackを決める たず、匊瀟のワヌクロヌドの基本構成はECS+Fargateです。AWS䞊に環境を䜜る堎合、PackModuleず呌ばれおいるTerraformのモゞュヌル矀がありたす。→ 過去参考動画 なので、ECSをベヌスに考えたのですが、制限事項も倚いこずから、たずは求められるこず(芁件)を敎理したした。 したいこず 暪断的にLog/Metrics/Traceが可芖化できるこず (リ゜ヌス、ラむセンス的に)安䟡であるこず 切り替えが容易であるこず Fluentbitでログを、AdotCollectorでMetrics/Traceを転送しおいる郚分を倧きく倉曎しない。 氞続ログはS3に保存できるこず モニタリング基盀から保存ではなく、途䞭でAWSコンポヌネントからの転送でもOK NewRelicより可胜なら長く怜玢できる期間があるこず 特に、番目に぀いおは、NewRelicずいうSaaSツヌルも既にありたすから、䜿甚するアプリケヌションナヌザ偎の予算的に今たでより高䟡になるず意味がありたせんでした。 しないこず こちらも重芁だず思いたす。最䜎限必芁なものを敎理しお、あれもこれも ずやるず時間ず手間が増えたす。 AWSのアカりントは既存ず同じにする 運甚アカりント分割を過去は怜蚎したが、珟状ではやらない CloudInfraチヌムやSCoEなど、アカりント増やすなら関係各所が増えるのず、アカりント自䜓のセキュリティヌルヌルの運甚のため Profile可芖化(Pyroscope) アプリケヌション担圓者ぞのトランスファヌや運甚手順が増える S3にある氞続ログを怜玢できるように戻したりずかはしない 生成AI呚りの監芖基盀 最終的にはLangFuseが生えたしたが、最初の時点ではスコヌプ倖 決たったこず 䜿うOSS 名称 機胜 抂芁 Loki Log保存 ログ保存。OpenSearchのOSSやElasticも悩みたしたが、党䜓揃っおるので基本GrafanaLabs系で統䞀 Tempo Trace保存 トレヌス保存 Grafana 可芖化 各皮可芖化ずアラヌト。Grafanaの構築単䜍は任意のアプリ矀にしたした Alloy AWSログ転送 Lambda/WAF/RDS系のログがKinesisFirehose(HTTP)からAlloyを経由しおLokiに転送 Thanos Metrics保存 Mimirではなくこちらで。メンバヌのナレッゞがあったため 自䜜Logger AWSログ転送 ALB/Cloudfrontの、S3にしか出力できないログの転送甚。珟行はLogStashを䜿甚 ArgoCD GitOps GitOpsのためこちらを遞択 制限事項 Thanos/MimirずもにNFSをサポヌトしおないので、ECS+Fargateだず厳しい CNDW2025でLokiをECS+Fargateで構築した人がいらっしゃったんですけど、コンポヌネントずか考慮点が倚い Grafana系だずLoki以倖はDockerでのDeploy手順が公匏でサポヌトされおいない Prod環境だずHelmかTankaでのデプロむメントが掚奚 あ、EKSで動かすしか無いか  もずもず、EKSはアプリケヌション芁件があれば導入を怜蚎しようずいう話もありたした。そのため、ちょうど良い機䌚ずしおEKSを実行サヌビスずしお決めたした。ただ、Webアプリケヌションを動かしおいるワヌクロヌドに぀いおはECSのたたずしおいたす。 PlatformEngineeringTeamずしお、CICDのテンプレヌトやその他ツヌル矀を提䟛しおいたすが、アプリケヌション郚門にEKSを提䟛するメリットがあたり芋えなかったこずず、提䟛のための各皮修正を考慮した結果です。 構成 ※NewRelic経路は倉わらないので割愛 AWSコンポヌネント この時点で、ちょうどEKSにAutoModeが発衚されたした。制限事項の1぀目のEFSの察応ずいう点では、EKS+Fargateでも察応䞍可だったので、AutoModeを䜿っおみようずいうこずになりたした。 AutoModeでも、ARM64を指定した蚭定ができ、起動するEC2のむンスタンスが安䟡になるので、構築埌にArmアヌキテクチャのNodePoolを蚭定しおいたす。 EKS構築以倖の新モニタリング基盀の掚進に向けたおしごず PackModuleの修正 最初の方 にあった、Moduleの修正です。 意識しないず移行しない(=Default倀が倉わらないようにする)圢で修正したした。 KinesisFirehose(HTTP゚ンドポむント向け)のModule䜜成 Backupの取埗をALLにしおS3ぞ保存( 芁件4 に関連する) 呌び出す各コンポヌネントModuleの修正 Lambda WAF RDS セキュリティヌ調敎 Firehoseですが、VPC内郚に䜜成されないので、Alloyの前段のALBにむンタヌネット経由での通信経路ずなりたす。その堎合、さすがに認蚌認可もなしでALBにログを送るのもNGでしたので、Headerでの認蚌を远加したした。 構築時にSecretManagerにKEYを保存しお、Firehoseからはそれを付䞎しお送信。ALBではその倀ずマッチしおいるかず確認しおいたす。 コンテナの脆匱性を怜知する仕組みをECR通知で䜜っおおり、DockerHubから盎接呌び出さずに、ECRに䞀時的に保管する運甚も行なっおいたす。が、かなり運甚負荷が高いので、どうにかしたいのが課題ずなっおいたす。 移行のお願い 䞀番泥臭く、CustomerSuccessEngineerチヌム(CSE)が各担圓にお声がけをしおチケットを切っお管理する圢で行なっおいたす。䞀郚は開発タスク優先で期限からはみ出たしたが、倚くのプロダクトはありがたいこずに協力いただき、幎内での切り替えを想定しおいたす。 アプリケヌションの担圓者の倉曎䜜業ずしおは Fluentbitの䜿甚バヌゞョンの倉曎(LokiPlugin向け) 各皮Configの修正 AdotCollector ECS TaskDefinition こちらは、PlatformGでConfluenceに䜜業手順を準備しお、提䟛しおいたす。 Firehoseなどの切替は、アプリケヌション担圓者ず日皋を調敎し、PlatformGずCloudInfraGでTerraformの修正ずいう圢で行なっおいたす。 おたけ アカりント分割の察応 移行䞭ではあるんですが、瀟内のAWSアカりントの最適化が進んでおり、そちらの倉曎反映も実斜する予定です。 ただ、EKSの前にはNLB/ALBを挟んでいるため、VPCPeeringかVPCEndpointによる察応で枈む芋蟌みです。 (Ž・ω・) 運甚アカりントに分割する日は、䜕時来るのかな LLM監芖や远加機胜のデプロむ RCAのためのLangFuse、実行時間やメモリなどの関係からCode分析機胜がLambdaをやめおEKS䞊に移行、AWSメトリクス収集のための YACE のデプロむなど、モニタリング・RCA関連が色々ず远加で茉るようになりたした。 所感 基本、機胜芁件ずか技術制限など、䜕かしらの理由がない堎合は、AWSでコンテナなどを動かすにはECSで十分だず思いたす。実際、n8nずか他のOSS系はECSで起動するようにしおいたす。 新しくゞョむンしたメンバヌがEKSず各皮Grafanaスタックに経隓が倚かったこずもあっお、ある皋床、スムヌズに構築や移行できたこずもありたす。 ただ、AutoModeの運甚経隓や、実際に各環境のログなどを投入しおいくず問題、゚ラヌなどが出おきたした。安定運甚たでに色々ず手を打たないずいけないず考えおいたす。 やはり、K8s運甚は䞀筋瞄ではいかないず実感したした。 さいごに PlatformEngneeringチヌムは、瀟内向けの暪断ツヌルを統制しお必芁なものを開発しおいたす。 必芁なものを新芏䜜成や既存のものをマむグレヌションしたり、ツヌルを䜿っおもらうためのEnablingの掻動や、マヌケティング技術を䜿った内郚展開などのチヌムもありたす。 GoldenPathの敎理(そもそも業務フロヌの可芖化・改善)も実斜しおいく予定です。 こういった掻動に少しでも興味を持ったり話を聞いおみたいず思った方は、お気軜にご連絡いただければず思いたす。 @ card
This article is the Day 14 entry for the KINTO Technologies Advent Calendar 2025 🎅🎄 Introduction We, members who joined KINTO Technologies' QA Group in 2025, have participated in this Advent Calendar campaign! This blog describes the topics we have worked on as QA team members from our joining the company to date. We hope it serves as inspiration for QA professionals and helps developers understand that QA has tasks which are not perceived well. Creating a Web App for Test Efficiency Self-introduction I'm Tomiyoshi. I worked as a QA in third-party verification at my previous job. I have almost no development experience. Content One day, something came up. We discussed how to efficiently test text input in a chat on mobile devices. Someone said, "Why don’t we just use AI to create a web app? So, I built one!! Copy Paste The system uses Zapier, a process automation tool. After questions generated by AI are stored in Google Spreadsheet as a database, we use Google Apps Script to create the web app. Tool What a Tool Does Reference Image 1 Zapier Creating a form screen Zapier's Interfaces feature allows you to create forms. 2 Zapier AI-powered question generation Generates questions based on input from the form screen. — 3 Zapier Integration with Google Spreadsheet Links generated questions to Google Spreadsheet. This integration is enabled as a standard Zapier feature. — 4 Google Spreadsheet Used as a database substitute Stores question content shared from Zapier — 5 Google Apps Script Displays the web app based on the question content stored in Google Spreadsheet — When I started creating the app, I was in doubt that I could finish it. I proceeded by asking AI for details about how to accomplish each step for the app creation. I was able to link Zapier to the spreadsheet. The linked content includes the generated question JSON (in Column D). I want to create a web page that lists the contents of the questions in this JSON and allows for copying each one individually. Attachment: Downloaded Google Spreadsheet Excel file Of course, it didn't work on the first attempt, and errors occurred when I used the code generated by AI as-is. By checking each error with AI one by one, I was able to create the app in the current format. Initially, the app didn’t have a search function, so it somewhat lacked in convenience. However, I believe the key to success is not to request too many things at once but instruct AI to add detailed features step by step. Thanks to this approach, I rarely modified the code on my own. I simply kept writing about what I wanted to do on prompt, and AI gave shape to my ideas by coding for about 1 to 2 days. Once I registered template texts in advance to input into the chat using this web app, all I need to do is to access it from a mobile device and copy-paste, rather than to manually type texts on a keyboard, which increased the input task efficiency. This was my first web app creation, but I managed to build it, collaborating with AI. Despite a lack of development experience, I was able to create something like this, so I will continue trying to develop new things. Appendix Zapier: https://zapier.com/ Google Spreadsheet: https://workspace.google.com/intl/ja/products/sheets/ Google Apps Script: https://developers.google.com/apps-script?hl=ja Presenting My Experience as a Beginner Setting Up an Appium Environment Self-introduction I'm Roki. At my previous job, I worked as a QA at a news app company. I have no development experience. Content Hello! Recently, I gave a lightning talk at Appium Meetup Tokyo #3 about "Stumbling Blocks for Beginners in Appium Environment Setup." The event took place both online and onsite. I talked for 15 minutes about introducing four key points using slides. The reason I felt interested in Appium was that I thought this could be my first step into coding! However, as a beginner, getting stuck on environment setup may be discouraging. Since I struggled quite a bit myself, I wanted to present my experience, hoping it might be helpful for others facing similar issues. Here are the points I presented: AI is surprisingly capable of providing solutions when you ask about errors Checking the official Appium website ensures the correct versions Only launching necessary tools prevents tool conflicts Getting hands-on experience is the fastest way to learn Git commands After my lightning talk, I was happy when participants told me that they could really relate to all common issues. Speaking in front of people is still nerve-wracking, but I felt relieved when it ended. I want to continue coding little by little and expand what I can do. Appendix https://speakerdeck.com/kintotechdev/appiumwodong-kasumatenotumatukihointo-chu-xin-zhe-kagan-sitariarunabi-toxue-hi Automation with Playwright Self-introduction I'm Higashi. At my previous job, I worked as a QA in third-party verification. I have almost no development experience. Content The most memorable experience since I joined the company was testing automation. I had never done it at my previous job, but when my manager and colleagues said, "Would you like to try it?" I was so excited that I immediately said, "Absolutely!" The project I joined required regression testing to verify the entire process up to application completion under various conditions. To automate the process, we decided to create a regression test script specifically for this project. Also, my team has adopted Playwright as a tool for E2E testing automation, and my colleagues had already completed data creation and regression test scripts to some extent. Based on the scripts, I created ones for specified application conditions. Although I had reference scripts, when even one component operation differed—such as dropdown selections, text box inputs, or checkboxes and buttons to click—element retrieval errors would occur. This hindered me from making progress as smoothly as I expected... That's when I found a Playwright feature that helped me the most: the code generation feature. It records browser operations and outputs automation code for them. Using this feature for performing browser operations in line with the application conditions, even beginners can easily generate code and retrieve elements. Thanks to the feature, errors are solved. (Example: Recording the operation of clicking "View vehicle list") There are still many convenient Playwright features I don't know about, so I want to gradually learn how to use them by asking colleagues and researching on my own, thereby getting more familiar with Playwright over time. Handling Appium-Related Tasks and Establishing Development Rules Self-introduction I'm m. I made a job change to QA when I joined KTC! Until my previous job, I was developing Android apps. Content Recently, I had an opportunity to get involved with E2E testing automation using Appium, so I'll share that experience. I'll touch on two main points: the differences between unit tests and E2E tests along with my impressions, and the establishment of development rules. 1. Introduction of E2E Testing with Appium E2E testing reproduces the operations that users actually perform on devices and verifies the overall behavior of the app. I worked on creating E2E tests for Android and iOS apps using Appium. The particular issue was the execution time. Wait times are unavoidable in E2E testing. Specifically, the following wait times occur: Waiting for UI operations Waiting for screen rendering Waiting for network communication The more waiting time we have, the more test execution time and costs we need to spend in testing. Therefore, it is significant to decide which scenarios to prioritize for testing and to design retry processing for cases where tests cannot execute normally due to external factors. Currently, we are working on speeding up execution through discussions about processing content in our peer review phase. As a result, we have achieved reduced load on some processes. We will continue to discuss and address these issues. 2. Establishing Development Rules As the number of project members increased, we established development-related rules, such as reviewing branch strategies, branch protection settings, and PR rules. Changing Branch Strategies Previously, we used GitHub Flow, but we have now changed the version control system to Git Flow. That is mainly because we wanted to manage releases for each version of the app we use. Adopting Git Flow enabled clearer feature development and release management, reducing confusion when we handle multiple versions simultaneously. Reviewing Branch Protection Settings On the main branch running in the production environment, we faced an issue that the application didn’t work due to individual environment differences among newly assigned developers, including myself. To overcome the issue, we changed the branch settings to enable merging in creating PRs for the main and release branches only when GitHub Actions workflows automatically verify that operation checks (running all tests) pass. Establishing PR Rules To clarify what each developer was doing for previous PRs, we prepared a PR template including the following information: Summary of changes Details What was verified What reviewers should check This template was designed to organize PR content and make reviews more efficient. It helped us establish a foundation for more secure and safe development. We want to work together as a team to create an even better development environment. We continuously share initiatives like E2E testing automation using Appium and development rule establishment from a QA perspective at internal events. We currently hold a monthly event called CO-LAB Tech Night at our Osaka branch (Osaka Tech Lab), so please join us...! Here's a photo of the event when I presented at the QA session. Conclusion Thank you for reading to the end. We hope this content serves as inspiration for your QA activities.
この蚘事は KINTOテクノロゞヌズアドベントカレンダヌ2025 の13日目の蚘事です🎅🎄 はじめに はじめたしおの方も、い぀もありがずうございたすの方もこんにちは KINTOテクノロゞヌズ以䞋、KTCで゚ンゞニア採甚ず採甚広報を担圓しおいる たけの ひかる @t_hikarutaaaan です。 毎幎恒䟋のアドベントカレンダヌ䌁画、 今幎も呌吞をするように゚ントリヌしおみたした笑 今回は、 「゚ンゞニア採甚ず採甚広報の舞台裏」 をテヌマに、 私の “ずある1日” をゆるっず玹介しおみようず思いたす。 すこしだけ自己玹介 入瀟しお玄4幎、採甚担圓になっお玄2幎。 圓時は 人事も採甚も完党にれロ経隓からのスタヌト。 技術の話は半分も理解できず、 スカりト1通送るだけであたふたしお、 面談ではガチガチに緊匵しおスクリプトを棒読み。今では完党にネタ でも、止たらずに挑戊し続けたからこそ今蚀えたす。 「採甚ずいう仕事が、本圓に奜きです。」 そしおKTCは、 “やっおみたい” ず手を挙げた人に本気で任せおくれる䌚瀟。 未経隓の私が走り続けられたのは、そのカルチャヌのおかげです。 やっず笑っおむベント叞䌚ができるようになりたした ゚ンゞニアっお、魔法䜿いじゃん 実は、採甚担圓になっお少し経ったころ、生成AIにコヌドを曞いおもらいながら 採甚デヌタを分析できる小さなアプリを぀くったこずがありたす。アプリっお蚀っおいいレベルではないですが ワンクリックで画面にグラフが衚瀺された瞬間、思わず声が出たした。 「え、すご 魔法じゃん。」 技術が人の困りごずを䞀瞬で解決しおしたう瞬間にシンプルに感動したした。 で、そのずき思ったんですよね。 「あ、もっずちゃんず向き合わなきゃ」っお。 珟堎の人たちがどんな想いでプロダクト぀くっおるのか、 「もっずちゃんず知りたいし、もっずもヌっずちゃんず䌝えたい」ず。 そこから曎に毎日あたふたしながら走り回っおたす。笑 ずいうわけでここからは、 そんな私の 「ずある1日」 をゆる〜く玹介しおみたす 時間 内容 実際にやったこず こんな気持ちでやっおたす䟋 09:00 スカりトtime タヌゲット遞定、プロフィヌル読み蟌み、スカりト文䜜成送付 どの媒䜓にしようかな。良い人発芋。「なぜ声をかけたいのか」を必ず曞く 10:00 曞類遞考 職務経歎確認、珟堎メンバヌず評䟡すり合わせ むむ めちゃくちゃ良い人  11:00 珟堎MTG 採甚状況共有、採甚芁件摺り合わせ、PJ状況ヒアリング 分からないこずは玠盎に聞く。優しく答えおくれる文化に感謝 🙏 12:00 ランチtime 卵かけごはんをすする か぀お節が合う。おなかいっぱい。 13:00 カゞュアル面談 キャリアヒアリング、プロダクト玹介 双方コミュニケヌションできた時が最高。時間足りない日も倚い。 15:30 採甚広報䌁画 採甚トレンド調査、競合リサヌチ、䌁画案䜜成、資料構成 煮詰たった 。壁打ち盞手求む。 17:00 カゞュアル面談 キャリアヒアリング、プロダクト玹介 技術質問に少し答えられず あずで珟堎に確認。 19:00 むベント運営 受付、撮圱、アナりンス、来堎者サポヌト 基本、走り回っおたす笑。写真撮っお声かけお ハむハむ コスパタむパ最高の卵かけごはん 採甚の難しさず向き合う日々 採甚は、スペックだけでは枬れない䞖界です。 䌚話の空気 ちょっずした衚情の倉化 遞択の背景にある䟡倀芳 そういった“芋えないもの”を䞁寧に受け止める必芁がありたす。 ある候補者の蚀葉が忘れられたせん。 「転職の決め手は、“誰ず働くか”なんです」 その䞀蚀で、ハッずしたした。 私はずっず䌚瀟ずしおの魅力を䌝えるこずに粟䞀杯でした。 でも候補者の方が本圓に知りたいのは、 「このチヌムなら、自分の挑戊を蚗せるか」 それからは、 珟堎の空気やカルチャヌ、そこで生じる悩みや挑戊も含めた本音を届けるこずを倧切にしおいたす。 面談の最埌に 「䞀緒に働く姿が想像できたした」 ず蚀っおもらえた日は、心の䞭で小さくガッツポヌズしおいたす。笑 採甚広報で挑戊したこず 今幎、採甚広報ずしお 囜内最倧玚のモビリティむベントである Japan Mobility Show 2025 の登壇䌁画を担圓したした。 KTCが所属するTOYOTAグルヌプ内の関係者や、 リアル領域ずIT領域それぞれの担圓者を巻き蟌みながら進めるプロゞェクトで、 調敎量も難易床も、正盎これたでで䞀番倧倉でした。笑 でも、どうしおも実珟したかった理由がありたす。 私たちの匷みである「リアル × IT」での挑戊を、ちゃんず倖に届けたかった。 そしお、「䞀緒にやろう」ず快諟しおくれた郚長の熱量を発信したかった。 求人祚だけでは䌝わらない空気や想いを、 生の蚀葉で届けたかったんです。 本番のあず、応揎しおくれおいた瀟内メンバヌから 「めちゃくちゃよかったよ」 ず声をかけおもらえお、すごく嬉しかったです。 さらに埌日、登壇䌁画の動画が公開されたあず、 日々いろいろな業務で関わるグルヌプ䌁業の方々にも 「YouTube芋たよ」「いい内容だった」「かっこよかった」 ず声をかけおもらえたず。 さらに、登壇しおくれた郚長はこんな蚀葉をくれたした。 「採甚に効いおくるのはもう少し先かもしれないけど、 瀟内広報ずか、KTCのセルフブランディングには効いおくるね」 めちゃめちゃ嬉しかったぁ。なんだろ。うたく蚀葉にできないけど笑 採甚広報は、䌚瀟の挑戊ず未来の仲間を぀なぐ仕事。 私はその“橋枡し圹”でありたいず思っおいたす。 䌚堎の写真を䞀生懞呜撮っおたす ちなみに以䞋がこの蚘事で觊れた登壇䌁画のアヌカむブ動画です あ぀ヌヌく、ギュギュっず詰たった50分なので是非ご芖聎ください♪ https://youtu.be/NXM2lyapia0?si=QiK5GP2XFtCh0c9c 採甚はチヌム戊であり、未来づくり 採甚に、これが正解っおいう圢はありたせん。 毎回迷うし、悩むし、揺れ続けたす。 正盎、答えが分からなすぎお゜ワ゜ワする日もある。笑 でも、ひず぀だけ確信しおいるこずがありたす。 いい採甚は、いい“察話”からしか生たれない。 KTCには、私を含めお5名の採甚担圓がいたす。それぞれが郚門に専任ずしお぀く郚門担圓制。 だからこそ、珟堎ずめちゃくちゃ密にコミュニケヌションができるんです。 プロダクトの話も、カルチャヌの話も、 嬉しいこずも、しんどいこずも、ぜんぶ䞀緒に考える。 そうやっお、チヌムで採甚を぀くっおいる感芚がある。 これは本圓に誇れるポむントだず思っおいたす。 最埌に、読者のみなさたぞ ゚ンゞニアのみなさたぞ   å°Šæ•¬ã—おいたす。本気で。   æŠ€è¡“で未来を倉えおいく姿は、私にずっおずっず魔法のように芋えおいたす🪄 プロダクト開発に関わるみなさたぞ   æœ¬æ°—でプロダクトず向き合う姿勢や、ひず぀の䟡倀を぀くるためのコミュニケヌションや詊行錯誀。   ãã®ãƒªã‚¢ãƒ«ãªã‚¹ãƒˆãƒŒãƒªãƒŒã«ã€ç§ã¯ã„぀も心を動かされおいたす。 人事グルヌプの仲間ぞ   ã„぀もわちゃわちゃしおいる私ず䞀緒に悩んでくれお感謝です   ã“れからも䞀緒に走っおね(/・ω・)/ KTCのみなさたぞ   ã„぀も助けおくれおありがずうございたす   ç§ã®å€§å¥œããªäŒšç€ŸãŒã‚‚っず匷くなるために、たずは採甚ずいう堎所から党力で貢献したす この蚘事を読んでくださったみなさたぞ   ã‚‚し少しでも䜕か響くものがあったら、   ãœã²ã‚€ãƒ™ãƒ³ãƒˆã§ã€ã‚«ã‚žãƒ¥ã‚¢ãƒ«é¢è«‡ã§ã€ã€ã€ã€ã©ã“かでお䌚いできたら嬉しいです 未来の仲間ぞ 私たちKINTOテクノロゞヌズは倉革期の自動車産業のど真ん䞭で、 内補開発組織をれロから぀くる挑戊をしおいたす。 こんなダむナミズムに関われるチャンスは、そう倚くありたせん。 未来を䞀緒に創る仲間をお埅ちしおいたす🙌 以䞊、採甚担圓・広報担圓の“ずある1日”でした 読んでくださり、本圓にありがずうございたした
This article is the Day 13 entry for the KINTO Technologies Advent Calendar 2025 🎅🎄 Introduction Nice to meet you if this is our first encounter, and hello again if you've been following along! I'm Hikaru Takeno ( @t_hikarutaaaan ), and I handle engineer recruiting and recruitment PR at KINTO Technologies (KTC). The annual Advent Calendar tradition—I signed up for it again this year as naturally as breathing! (lol) This time, I'll give you a casual look at the behind the scenes of engineer recruiting and recruitment PR through a day in my life. Brief Self-Introduction It's been about 4 years since I joined KTC and about 2 years since I became a recruiter in the company. Back then, I started with absolutely zero experience in HR or recruiting. I could barely understand half of the technical discussions and would get frustrated with just sending a single scout email. In addition, at interviews, I was so nervous, so all I could do was just read my script in a monotone voice. (Now, it’s a funny story. lol) As I have been committed to recruitment without stopping, I can say this now: "I truly love this job." KTC is a company that genuinely entrusts responsibilities to members who raise their hand and say they want to try. Thanks to that corporate culture, I was able to move forward even with no recruitment experience. Now, I can host events with a smile. Engineers Are Basically Wizards A little while after becoming a recruiter, I built a small app that could analyze recruiting data using generative AI for writing the app code for me. (It may not as well-developed as apps at a professional level, though. lol) With a single click on the app, a graph appeared on screen, which I couldn't help but speak out loud, "Wow, that's amazing! It’s like magic." I was simply impressed by how technology can solve someone's problem in an instant. And that's when I thought: "I need to engage in this job more seriously." I wanted to understand what kind of passion onsite members have when they build products, thereby introducing them to the public even in a more appropriate manner. Since then, I've been busy working on my job every day. (lol) From here, let me casually show you a day in my life! Time Activity What I Actually Did How I Feel About It (Example) 09:00 Scouting time Selecting target candidates, reading profiles, drafting & sending scout messages. With a consideration of which platform should I use, I found a great candidate, always writing "why I want to reach out that person." 10:00 Resume screening Reviewing work history, sharing evaluations with onsite team members. Hmm... this person is really impressive...! 11:00 Onsite team meeting Sharing recruiting status, checking if the potential candidates meet our requirements, catching up project updates. I ask honestly when I don't understand. I’m grateful for the culture where team members kindly answer my questions all the time. 🙏 12:00 Lunch time Gobble a tamago kake gohan (rice with a raw egg). Bonito flake is a great combination with the egg. I’m so full. 13:00 Casual interview Learning about candidates’ career, introducing our products The best moment is when we can have a real two-way conversation. I often don’t enough time to understand candidates just in the single interview. 15:30 Recruitment PR planning Researching recruiting trends and competitors’ strategies, drafting plans, organizing materials I’m stuck..., needing someone to bounce ideas off. 17:00 Casual interview Learning about candidates’ career, introducing our products I couldn't answer some technical questions...so got to ask them to team members later. 19:00 Event operations Reception, photo shooting, making announcements, assisting attendees I basically running around the event venue (lol), taking photos, talking to people... OK, coming right up! Tamago kake Gohan—the most cost-effective and time-efficient meal to me Facing the Difficulties in Talent Recruitment Every Day Recruiting is a field where we can’t judge individuals on their knowledge, skills, and other characteristics. The atmosphere of a conversation with them Subtle changes in their facial expression The values behind their choices You need to carefully perceive these hard-to-see signs from candidates. I can't forget what one said: "To me, the important factor when choosing a new job is 'who I work with.'" This made me realize something— I had been so focused on conveying attractive points about working at our company. But what candidates really want to know is: "Can I entrust my career to this team?" Since then, I've strive to talk openly and honestly to candidates about our teams’ atmosphere, corporate culture, and even what we struggle with and concerns arising from our working environment. I still remember when a candidate said at the end of an interview: "I can clearly picture myself working together with you." After hearing that, I made a little fist pump in my mind. (lol) Efforts I Made for Recruitment PR This year, as part of recruitment PR initiatives, I led a speaking session at Japan Mobility Show 2025 , one of the largest mobility events in Japan. It was a project that involved stakeholders within the TOYOTA Group where KTC belongs, as well as people engaging in both real-world and IT domains. To be honest, it was the most challenging project I've ever experienced with such large number of tasks for the event coordination and high-level difficulty in handling them. (lol) Despite that, I really wanted to make the project a success—that is because I wanted to properly convey to the public our strength of taking on new things collaborating with real and IT areas. I also wanted to share the passion of our senior managers who readily agreed to work the project together. I wanted to deliver through live words the atmosphere in KTC and our passion that can't be conveyed through job postings alone. After the event, team members who had been cheering me on said, "That was really great!" and it made me so happy. When the video of the speaking session was released, employees from group companies who I work with on various tasks also gave us the following comments: "I watched your YouTube video!" "Great content!" "That was cool!" And the senior manager, who spoke at the event session, gave me these words: "The recruiting impact might come a bit later, but it'll definitely work for internal PR and KTC's self-branding." I was so incredibly happy but couldn’t find words to clearly express my feeling. (lol) Recruitment PR is a job to facilitate sharing information about the company's initiatives with future teammates. I want to be the bridge between them and our company. Myself working hard to take photos at the event venue By the way, here's the archived video of the speaking session I mentioned above! I hope you enjoy this 50-minute video packed full of passion♪ https://youtu.be/NXM2lyapia0?si=QiK5GP2XFtCh0c9c Recruiting Is Achieved through Teamwork to Build Future There's no single right answer in recruiting talents. Every time, I get lost, worry, or waver. (Honestly, I feel restless for so many days because I can’t often find any solutions for my concerns. lol) But there's one thing I'm sure about: Good recruiting can only come from good dialogue with candidates. At KTC, there are 5 recruiters including myself. Each of us is assigned as a dedicated recruiter for specific divisions. That's why we are able to communicate super closely with the division members on the team, sharing information about products and cultures in each division, as well as happy things and tough things in their work—we think through everything together. That's how I feel we're building recruiting as a team. I think this is truly something to be proud of. Finally, to All Reading This Article To all engineers:   I respect you. I mean that seriously.   The way you change the future with technology has always looked like magic to me 🪄 To everyone involved in product development:   I understand your dedication to seriously engaging in product development through constant communication and trials and errors to create a single value.   Those real stories always struck me so deeply. To my teammates in the Human Resources Group:   Thank you for always worrying alongside me while I'm running around all over the place!!   Let's keep running together!! (/・ω・)/ To everyone at KTC:   Thank you for always helping me!!   I'll contribute to making my beloved company even stronger with all my efforts as an employee working at the recruitment frontline!!! To everyone who read this article:   If anything resonated with you even a little,   I'd love to meet you somewhere—at an event, a casual interview, or anywhere else!! To Future Teammates We at KINTO Technologies are taking initiatives in building an organization focusing on internal product development from scratch, right in the middle of the transforming automotive industry. Opportunities to be part of such dynamism don't come so often. We're waiting for teammates who will create the future together🙌 That's all for a day in the life of a recruiter and PR person! Thank you so much for reading!
This article is the Day 13 entry for the KINTO Technologies Advent Calendar 2025 🎄 Introduction I'm yuki.n ( @yukidotnbysh ) from the Master Maintenance Tool Development Team in the KINTO Backend Development Group, KINTO Development Division, based in the Osaka Tech Lab. Our team develops management systems that integrate with various services. These systems serve not only as administrative tools but also as solutions to business issues. To address these challenges, our management systems cannot be simple CRUD applications. Each system and its business requirements bring various complexities. I believed Railway Oriented Programming would be effective for handling these complexities in our business logic, so I introduced it in a project. Based on this case study, I would like to share the benefits we gained and the issues we faced. What is Railway Oriented Programming? Railway Oriented Programming Railway Oriented Programming is an error handling approach in functional programming proposed by Scott Wlaschin, who runs F# for Fun and Profit and authored Domain Modeling Made Functional . Looking at the article with the same title posted on F# for Fun and Profit , it seemingly have been published at least as early as 2013. In Railway Oriented Programming, functions are compared to railways, with success and failure handling represented as two separate tracks. The following diagram shows multiple of these railways connected together. Each processing step functions as a switch: if successful, processing continues on the success track; if it fails, it switches to the failure track. Once on the failure track, subsequent processing never succeeds, and the error flows through to the end. Specifically, this involves chaining functions that return Result types through a pipeline. Why Did We Adopt Railway Oriented Programming? Our team already had experience developing with Rust, and we adopted it as the backend server development language for this project as well. We designed the project architecture, according to the Clean Architecture diagram—for convenience, simply hereinafter referred to as Clean Architecture. When we introduced Clean Architecture in past projects, we found that the processing in the Use Cases layer (as depicted in the circle diagram above) often results in an unnecessarily complex and clunky structure design. Even when we carved some processing as domain services to combine them into the Entities layer, the readability of the Use Cases layer still suffered. In this situation, I learned about Railway Oriented Programming, which led to its adoption. Railway Oriented Programming with Rust Overall Structure The Use Cases layer we implemented has roughly the following structure. #[derive(Debug, thiserror::Error)] pub enum CreateUserUseCaseError { // Error type definitions } pub trait UsesCreateUserUseCase { /// Workflow fn handle( &self, input: CreateUserInputData, ) -> impl Future< Output = Result<CreateUserOutputData, CreateUserUseCaseError>, > + Send; } pub trait CreateUserUseCase: // Dependencies ProvidesUserFactory + ProvidesUserRepository { } impl<T: CreateUserUseCase + Sync> UsesCreateUserUseCase for T { async fn handle( &self, input: CreateUserInputData, ) -> Result<CreateUserOutputData, CreateUserUseCaseError> { // Chain of functions defined in the railway module } } mod railway { type RailwayResult<T> = Result<T, super::CreateUserUseCaseError>; pub(super) fn validate_input(/* ... */) -> RailwayResult<(Email, UserName)> { /* ... */ } pub(super) async fn check_email_not_exists(/* ... */) -> RailwayResult<(Email, UserName)> { /* ... */ } pub(super) fn build_user(/* ... */) -> RailwayResult<User> { /* ... */ } pub(super) async fn save_user(/* ... */) -> RailwayResult<User> { /* ... */ } pub(super) fn end(/* ... */) -> CreateUserOutputData { /* ... */ } } We use the Cake Pattern introduced in Thinking About DI in Rust — Part 2: Organizing DI Approaches Using Rust (only in Japanese) (I will omit the details as this diverges from the main topic of this blog). We define functions in the railway module and combine them within the handle method of UsesCreateUserUseCase . (Note: In Domain Modeling Made Functional, the part corresponding to the handle method is called workflow, and the arguments are called commands. This article follows that convention.) Let's break down each of these elements. Error Type Definition #[derive(Debug, thiserror::Error)] pub enum CreateUserUseCaseError { // Error type definitions #[error("Email address already exists.")] AlreadyExistsEmail, #[error("Invalid email address.")] InvalidEmail, #[error("Invalid username.")] InvalidUserName, #[error("UserFactoryError")] UserFactoryError(#[from] UserFactoryError), #[error("UserRepositoryError")] UserRepositoryError(#[from] UserRepositoryError), } We always define one error type for each Use Case. In Rust, error types can be defined as Enums. While the standard approach requires implementing the std::error::Error trait, using the thiserror crate simplifies error type definitions. Additionally, when defining with the thiserror crate, setting the #[from] attribute implements the From trait, allowing automatic conversion to the target error type without explicit conversion when the corresponding error occurs. RailwayResult Type mod railway { // Result type specific to this use case type RailwayResult<T> = Result<T, CreateUserUseCaseError>; } Since defining Use Case-specific errors for all functions would be cumbersome, we define a RailwayResult type alias so we only need to specify the return value. railway Module mod railway { /// Validates input values and converts them to value objects. pub(super) fn validate_input( input: CreateUserInputData, ) -> RailwayResult<(Email, UserName)> { let email = Email::try_from(input.email) .map_err(|_| CreateUserUseCaseError::InvalidEmail)?; let name = UserName::try_from(input.name) .map_err(|_| CreateUserUseCaseError::InvalidUserName)?; Ok((email, name)) } /// Confirms that the email address does not already exist. pub(super) async fn check_email_not_exists( (email, name): (Email, UserName), impl_repository: &impl UsesUserRepository, ) -> RailwayResult<(Email, UserName)> { impl_repository .find_by_email(&email) .await .map_err(CreateUserUseCaseError::UserRepositoryError)? .map_or(Ok((email, name)), |_| Err(CreateUserUseCaseError::AlreadyExistsEmail)) } /// Creates a new user. pub(super) fn build_user( (email, name): (Email, UserName), impl_factory: &impl UsesUserFactory, ) -> RailwayResult<User> { impl_factory .build(UserFactoryParams { email, name }) .map_err(CreateUserUseCaseError::UserFactoryError) } /// Saves the user. pub(super) async fn save_user( output: User, impl_repository: &impl UsesUserRepository, ) -> RailwayResult<User> { impl_repository .save(output) .await .map_err(CreateUserUseCaseError::UserRepositoryError) } /// Returns the result and terminates processing. pub(super) fn end( output: User, ) -> CreateUserOutputData { CreateUserOutputData { user: output.into(), } } } We create a module called railway and define the functions that form the tracks within it. This is not a Railway Oriented Programming convention but simply a guide we use for easier identification. In the code for this blog, we assume the following process flows: Validate input values (email address and username) Check email address existence Create User entity Save User entity Convert the saved User entity to a DTO for passing to the upper layer, and end the process Since the return value of the previous function is set as the input value for the next function, the first argument is named output . However, when output is a tuple, we destructure it from the start. This is because handling tuples as-is causes issues with variable ownership. Ideally, only the previous value should be set as the input for the next function, but we determined that the drawbacks outweighed the benefits—such as needing to pass unnecessary values as if through a bucket brigade. That is the reason we adopted a rule allowing new input values to be passed to each function. Overall Workflow The original programming convention uses F#, but Railway Oriented Programming is applicable in any language (or with libraries that supplement it) that has the concept of Result or Either types and the ability to compose functions. Fortunately, Rust comes standard with the following features essential for implementing Railway Oriented Programming, in addition to the Result type: ? operator: Expresses stopping processing when an error occurs map and and_then functions: Function composition By combining these, you can build a pipeline as follows: impl<T: CreateUserUseCase + Sync> UsesCreateUserUseCase for T { async fn handle( &self, input: CreateUserInputData, ) -> Result<CreateUserOutputData, CreateUserUseCaseError> { railway::validate_input(input) .map(|output| { railway::check_email_not_exists(output, self.user_repository()) })? .await .and_then(|output| railway::build_user(output, self.user_factory())) .map(|output| railway::save_user(output, self.user_repository()))? .await .map(railway::end) } } Benefits I Experienced in Practice The following are the benefits I experienced from practicing Railway Oriented Programming. Processing Flow Became Clear, Making Feature Addition Easier Since the workflow contents are connected through a pipeline, you can understand at a glance what processing is being performed. Of course, complex specifications inevitably lead to longer workflows, but even so, tracking the function flow helps us to roughly identify where and what is happening. With each process in the workflow extracted into functions, the scope of each process and its variables also became clear. This helped us add features simply by inserting new functions and modify them by changing the relevant function, which enhanced the system maintainability. Processing Input/Output Can Now Be Expressed Through Types I don't think this is a direct effect of Railway Oriented Programming, but we can now check by type level what data each function's arguments and return values represent. As compile errors can prevent type mistakes, we are able to avoid problems where incorrect values are passed during processing. Simplified Unit Test Scenarios Since implementing all success and failure tests for workflows was extremely labor-intensive and time-consuming, we adopted an approach of thoroughly testing individual railway functions, then only testing the happy path for the workflows. There may be controversies about whether tests for private functions are necessary, but I personally felt it was helpful to test each function in the railway module. So far, I haven't experienced any major problems with this approach. Additionally, as a secondary effect, when features are added, we can confirm there are no issues by adding tests for those functions and ensuring existing tests pass, which I think was beneficial. Issues I Experienced in Practice While gaining benefits from practice, we also faced some issues. Railway Oriented Programming Takes Some Getting Used To For those already familiar with functional languages, this approach probably doesn't feel unusual, but of course there are team members, including myself, who are not. The approach implementation is difficult until you get used to the style of writing. In fact, I struggled quite a bit when examining whether Railway Oriented Programming could be implemented using Rust. Currently, AI has significantly lowered the technical barriers for the implementation, but we humans still need to understand Railway Oriented Programming at some level to determine whether the outcomes are appropriately generated. That’s where supporting team members come in. In practice, the process of reviewing outcomes placed a significant burden on us in the early development phase of this project. Depending on the project's situation and conditions—such as development scale and deadlines—we suggest that you seek another solution instead of Railway Oriented Programming. We May Face fatal runtime error: stack overflow Depending on what kind of process is executed, Stack Overflow errors may occur at runtime. It is particularly troublesome because the error is not detected as a compile error, and you cannot determine which specific location contains issues just by searching around the source code. To find the error cause, you can use rust-lldb to check the stack trace and identify the code where the Stack Overflow error occurred. # Start binary with LLDB rust-lldb target/debug/your-bin # Execute run # Check backtrace when Stack Overflow occurs thread backtrace all When we address issues that are difficult to solve using a method chaining with map and and_then , we take an alternative solution to stop the method and write the processing line by line instead. This is the safest and easiest way to overcome tough issues. async fn handle(&self, input: InputData) -> Result<OutputData, UseCaseError> { railway::begin(self.uow()).await?; let output = railway::validate_email(&input.email)?; let output = railway::authenticate(output, input.password, self.authenticator()).await?; let output = railway::update_last_access(output, self.user_repository()).await?; let output = railway::commit(output, self.uow()).await?; railway::end(output) } The above solution isn't bad in itself, but it eliminates the pipeline through method chaining, creating the risk that we can write codes on a no-holds-barred basis. So, I think it's safest to only switch to this format when we hardly solve issues. As another option, you can expand the stack area by adding a value to the RUST_MIN_STACK variables. However, this merely postpones the issue and may cause the recurrence of the Stack Overflow errors. Therefore, I don’t recommend this solution. In my case, the error occurred in debug builds in the meantime when I executed asynchronous processing within functions defined in the railway module. async/await is syntactic sugar for the Future type, but, according to rust-lang/rust#132050 , the state held by the Future type is expanded to the stack area at runtime, which causes Stack Overflow errors at the execution of many async functions. In this case, I was able to avoid the error by storing the Future type data I wanted to simultaneously process into the Vec type data (because Vec type values are stored in the heap ). Increase in Codes in Return for Clarified Processing Flow When introducing Railway Oriented Programming in Rust, you end up connecting each function with map and and_then . Additionally, you need to define each of those functions, so the overall code volume increases compared to the one when you usually write codes. For example, if Railway Oriented Programming were not applied, the handle method would look like as follows: impl<T: CreateUserUseCase + Sync> UsesCreateUserUseCase for T { async fn handle( &self, input: CreateUserInputData, ) -> Result<CreateUserOutputData, CreateUserUseCaseError> { // Input validation let email = Email::try_from(input.email) .map_err(|_| CreateUserUseCaseError::InvalidEmail)?; let name = UserName::try_from(input.name) .map_err(|_| CreateUserUseCaseError::InvalidUserName)?; // Email duplication check let existing_user = self .user_repository() .find_by_email(&email) .await .map_err(CreateUserUseCaseError::UserRepositoryError)?; if existing_user.is_some() { return Err(CreateUserUseCaseError::AlreadyExistsEmail); } // User creation let user = self .user_factory() .build(UserFactoryParams { email, name }) .map_err(CreateUserUseCaseError::UserFactoryError)?; // Saving user let saved_user = self .user_repository() .save(user) .await .map_err(CreateUserUseCaseError::UserRepositoryError)?; // Result conversion Ok(CreateUserOutputData { user: saved_user.into(), }) } } Without functions, the implementation would be within the handle method (or with some functions partially extracted). Therefore, depending on the case, this approach might be simpler. So for applications with simple processing and mostly branching, it may be safer to unnecessarily adopt Railway Oriented Programming. P.S.: Where’s the Repository Pattern? While not directly related to the main topic of this blog, Domain Modeling Made Functional addresses the repository pattern in a section named “Where’s the Repository Pattern?” The book states the pattern in the functional approach as follows: “...when we model everything as functions and push persistence to the edges, then the Repository pattern is no longer needed.” However, since I couldn't fully grasp the intent and method behind this, we adopted the repository pattern for the code and our project described in this blog. Conclusion This concludes my explanation about practicing Railway Oriented Programming in Rust. Rust is an extremely expressive language with various features, and I feel that adopting Railway Oriented Programming can enhance it further. If you consider adopting Railway Oriented Programming in Rust, I hope this article can serve you as a helpful reference.
この蚘事は KINTOテクノロゞヌズアドベントカレンダヌ2025 の 13 日目の蚘事です🎄 はじめに KINTO開発郚 KINTOバック゚ンド開発G マスタヌメンテナンスツヌル開発チヌム・Osaka Tech Lab 所属の yuki.n @yukidotnbysh です。 わたしたちのチヌムでは各サヌビスず連携する管理システムを開発しおいたす。これらは管理システムであるず同時に、業務課題を解決するためのものでもありたす。 そのため管理システムず蚀えども単玔な CRUD システムずいうわけにはいかず、開発するシステムや業務によっお様々耇雑な課題が発生したす。これらをビゞネスロゞックに萜ずし蟌むにあたっお Railway Oriented Programming が効果的ではないかず考え、実際のプロゞェクトで導入したした。その事䟋をもずにどのようなメリット・芋えおきた課題があったのかをご玹介したいず思いたす。 Railway Oriented Programming に぀いお Railway Oriented Programming Railway Oriented Programming ずは F# for Fun and Profit の運営や「 Domain Modeling Made Functional関数型ドメむンモデリング 」の䜜者である Scott Wlaschin 氏が提唱した、関数型プログラミングにおける゚ラヌハンドリングの手法です。日本語では「鉄道指向プログラミング」ず呌ばれおいたす。 F# for Fun and Profit に投皿された 同じタむトルの蚘事 を芋るず、少なくずも 2013 幎には公開されおいたようです。 Railway Oriented Programming では、関数を「線路Railway」に䟋え、正垞系の凊理ず異垞系の凊理を 2 本の線路ずしお衚珟したす。 この「線路」を耇数぀なぎ合わせたのが以䞋のむメヌゞ図です。 各凊理ステップは「スむッチ」ずしお機胜し、成功すれば正垞系の凊理線路を進み、倱敗すれば異垞系の凊理線路に切り替わりたす。䞀床異垞系に入るず、以降の凊理では成功するこずはなく、゚ラヌずしお最埌たで流れおいきたす。 具䜓的には Result 型を返す関数をパむプラむンで次々ず぀なぎ合わせおいくむメヌゞです。 Railway Oriented Programming を取り入れた理由 もずもずわたしたちのチヌムでは Rust の開発実瞟があり、このプロゞェクトでもバック゚ンドサヌバヌの開発蚀語ずしお Rust を採甚しおいたす。 アヌキテクチャずしおは「The Clean Architecture」の図を参考にしおいたす以埌、䟿宜的にあえお「Clean Architecture」ず曞きたす。 過去のプロゞェクトで Clean Architecture を導入した時、䞊の図で描かれおいる「Use Cases」局の凊理が耇雑か぀肥倧化しおいく傟向にあり、䞀郚凊理をドメむンサヌビスずしお「Entities」局ぞ切り出したずしおも、やはり Use Cases 局の可読性が萜ちおしたうずいう課題がありたした。 そんな䞭で Railway Oriented Programming の存圚を知り、導入するこずになりたした。 Rust での Railway Oriented Programming 党䜓の構造 わたしたちが実装した Use Cases 局は抂ね以䞋のような構造になっおいたす。 #[derive(Debug, thiserror::Error)] pub enum CreateUserUseCaseError { // ゚ラヌ型の定矩 } pub trait UsesCreateUserUseCase { /// Workflow fn handle( &self, input: CreateUserInputData, ) -> impl Future< Output = Result<CreateUserOutputData, CreateUserUseCaseError>, > + Send; } pub trait CreateUserUseCase: // 䟝存関係 ProvidesUserFactory + ProvidesUserRepository { } impl<T: CreateUserUseCase + Sync> UsesCreateUserUseCase for T { async fn handle( &self, input: CreateUserInputData, ) -> Result<CreateUserOutputData, CreateUserUseCaseError> { // railway モゞュヌルで定矩した関数のチェヌン } } mod railway { type RailwayResult<T> = Result<T, super::CreateUserUseCaseError>; pub(super) fn validate_input(/* ... */) -> RailwayResult<(Email, UserName)> { /* ... */ } pub(super) async fn check_email_not_exists(/* ... */) -> RailwayResult<(Email, UserName)> { /* ... */ } pub(super) fn build_user(/* ... */) -> RailwayResult<User> { /* ... */ } pub(super) async fn save_user(/* ... */) -> RailwayResult<User> { /* ... */ } pub(super) fn end(/* ... */) -> CreateUserOutputData { /* ... */ } } 「 Rust の DI を考える –– Part 2: Rust における DI の手法の敎理 」で玹介されおいる Cake Pattern を甚いおいたす本蚘事の本筋ずは逞れるため詳现は割愛したす。 railway モゞュヌルに関数を定矩し、それらを UsesCreateUserUseCase の handle メ゜ッド内で結合する、ずいう圢です。 なお、「関数型ドメむンモデリング」では handle メ゜ッドにあたる郚分を「ワヌクフロヌ」、匕数は「コマンド」ず衚珟されおいたす。本蚘事でもこれに倣いたす これらの芁玠をひず぀ず぀分解しおいきたす。 ゚ラヌ型の定矩 #[derive(Debug, thiserror::Error)] pub enum CreateUserUseCaseError { // ゚ラヌ型の定矩 #[error("メヌルアドレスが既に存圚したす。")] AlreadyExistsEmail, #[error("無効なメヌルアドレスです。")] InvalidEmail, #[error("無効なナヌザヌ名です。")] InvalidUserName, #[error("UserFactoryError")] UserFactoryError(#[from] UserFactoryError), #[error("UserRepositoryError")] UserRepositoryError(#[from] UserRepositoryError), } Use Case ひず぀に察し、゚ラヌ型を必ずひず぀定矩する圢で運甚しおいたす。 Rust でぱラヌ型を Enum で定矩するこずができたす。暙準のたただず std::error::Error トレむトを実装する必芁があるのですが、 thiserror クレヌトを䜿うこずで゚ラヌ型の定矩を簡略化できたす。 たた thiserror クレヌトで定矩した堎合、 #[from] アトリビュヌトを蚭定するこずで From トレむトが実装されるので、該圓゚ラヌが発生した時に明瀺的に倉換をせずずも、自動的に目的の゚ラヌ型ぞ倉換できるようになりたす。 RailwayResult 型 mod railway { // このナヌスケヌス専甚のResult型 type RailwayResult<T> = Result<T, CreateUserUseCaseError>; } Use Case 専甚の゚ラヌをすべおの関数に定矩するのは倧倉なので、 RailwayResult 型ずいう型゚むリアスを定矩しお、戻り倀だけ蚭定するようにしおいたす。 railway モゞュヌル mod railway { /// 入力倀を怜蚌し、倀オブゞェクトに倉換したす。 pub(super) fn validate_input( input: CreateUserInputData, ) -> RailwayResult<(Email, UserName)> { let email = Email::try_from(input.email) .map_err(|_| CreateUserUseCaseError::InvalidEmail)?; let name = UserName::try_from(input.name) .map_err(|_| CreateUserUseCaseError::InvalidUserName)?; Ok((email, name)) } /// メヌルアドレスが存圚しおいないこずを確認したす。 pub(super) async fn check_email_not_exists( (email, name): (Email, UserName), impl_repository: &impl UsesUserRepository, ) -> RailwayResult<(Email, UserName)> { impl_repository .find_by_email(&email) .await .map_err(CreateUserUseCaseError::UserRepositoryError)? .map_or(Ok((email, name)), |_| Err(CreateUserUseCaseError::AlreadyExistsEmail)) } /// ナヌザヌを新芏䜜成したす。 pub(super) fn build_user( (email, name): (Email, UserName), impl_factory: &impl UsesUserFactory, ) -> RailwayResult<User> { impl_factory .build(UserFactoryParams { email, name }) .map_err(CreateUserUseCaseError::UserFactoryError) } /// ナヌザヌを保存したす。 pub(super) async fn save_user( output: User, impl_repository: &impl UsesUserRepository, ) -> RailwayResult<User> { impl_repository .save(output) .await .map_err(CreateUserUseCaseError::UserRepositoryError) } /// 戻り倀を返し、凊理を終了したす。 pub(super) fn end( output: User, ) -> CreateUserOutputData { CreateUserOutputData { user: output.into(), } } } railway ずいうモゞュヌルを䜜り、その䞭に「線路」ずなる関数矀を定矩しおいきたす。 これは Railway Oriented Programming の流儀ではなく、単玔にわたしたちが確認しやすいように目印ずしお蚭けおいたす。 この蚘事のコヌドの堎合では以䞋の流れを想定しおいたす。 入力倀メヌルアドレス・ナヌザヌ名の怜蚌 メヌルアドレスの存圚チェック User ゚ンティティの生成 User ゚ンティティの保存 保存した User ゚ンティティを䞊䜍局に枡すための DTO に倉換し、終了 前回の関数の戻り倀が次の関数の入力倀になるため、第䞀匕数は output ず呜名しおいたす。 ただし output がタプルだった堎合は始めから展開しおいたす。これはタプルのたただず倉数の所有暩の問題で取り扱いが面倒なためです。 基本的には前回の倀だけがそのたた次の関数の入力倀になるこずが望たしいずは思うのですが、バケツリレヌのように䞍芁な倀たで枡し続ける必芁が発生するなどデメリットの方が倚いず刀断し、各関数で新たな入力倀を枡しおも良いずいうルヌルにしおいたす。 ワヌクフロヌ党䜓 原兞では F# が䜿われおいたすが、Result 型や Either 型の抂念があり、か぀関数を合成する機胜がある蚀語たたはそれを補完するラむブラリなどであれば Railway Oriented Programming の導入は可胜です。 Rust では幞い、Result 型以倖にも Railway Oriented Programming を実珟するのに欠かせない以䞋の機胜が暙準で備わっおいたす。 ? 挔算子゚ラヌ発生時の凊理停止を衚珟 map ・ and_then 関数関数の合成 これらを組み合わせるこずで以䞋のようにパむプラむンを構築するこずができたす。 impl<T: CreateUserUseCase + Sync> UsesCreateUserUseCase for T { async fn handle( &self, input: CreateUserInputData, ) -> Result<CreateUserOutputData, CreateUserUseCaseError> { railway::validate_input(input) .map(|output| { railway::check_email_not_exists(output, self.user_repository()) })? .await .and_then(|output| railway::build_user(output, self.user_factory())) .map(|output| railway::save_user(output, self.user_repository()))? .await .map(railway::end) } } 実践しお感じたメリット 以䞋、Railway Oriented Programming を実践しお感じたメリットです。 凊理の流れが明確になり、機胜远加がしやすくなった ワヌクフロヌの䞭身がパむプラむンで繋がっおいるので、どういう凊理が行われおいるのかは䞀目である皋床わかるようになりたした。 もちろん耇雑な仕様であればワヌクフロヌが長くなるこずは避けられたせんが、それでも関数の流れを远えば、どこで䜕が行われおいるのかはだいたいの圓たりを぀けられるようになりたした。 ワヌクフロヌ内の各凊理も関数に切り出されおいるこずで、それぞれの凊理・倉数のスコヌプも明確になりたした。 このおかげで機胜远加の堎合は新たに関数を差し蟌むだけでよく、倉曎の堎合は該圓の関数のみ修正すれば良くなり、保守性も向䞊したように感じたす。 凊理の入出力を型で衚珟できるようになった これは Railway Oriented Programming ず盎接結び぀く効果ではないず思いたすが、各関数の匕数・戻り倀が䜕のデヌタであるかを型レベルでチェックできるようになりたした。 コンパむル゚ラヌで型の誀りを防げるようになり、凊理途䞭で誀った倀が枡っおしたうずいった問題を回避できるようになりたした。 単䜓テストが曞きやすくなった ワヌクフロヌに察し正垞系・異垞系すべおのテストを実装するのは非垞に倧倉だったため、各 railway 関数それぞれをしっかりテストしお、ワヌクフロヌのテストではハッピヌパスを通すずいうやり方を取っおいたす。 Private な関数のテストコヌドが必芁かどうかの是非はあるず思いたすが、それでも railway モゞュヌルの各関数をテストできるのは個人的にメリットず感じたした。いたのずころは倧きな問題も感じおいたせん。 たた、副次的効果ずしお、機胜远加があった堎合でもその関数分のテストを远加し、既存のテストがパスすれば問題ないこずが確認できるので、この点は良かったず思いたす。 実践しお感じた課題 実践しおメリットが埗られた反面、やはりいく぀か課題もありたした。 Railway Oriented Programming の慣れが必芁 普段から関数型蚀語に慣れおいる方であればそれほど違和感ない手法ず思うのですが、もちろんわたし含めおそうでないメンバヌもいたす。そのため、この曞き方に慣れるたではどうしおも実装が難しくなりたすし、実際、わたしも Rust で Railway Oriented Programming が実装できるか調べおいた時はかなり苊戊したした。 珟圚は AI のおかげでかなり難易床は䞋がりたしたが、できあがったものが適切な内容かどうかはやはりある皋床の理解が必芁です。そのため、メンバヌに察しおのフォロヌがどうしおも必芁になりたす。 実際のずころ、このプロゞェクトでも開発初期はどうしおもレビュヌ負荷が倧きくなりたした。そのため、開発芏暡や玍期など、プロゞェクトの状況・条件によっおは Railway Oriented Programming の採甚を芋送るこずも怜蚎した方が良いかもしれたせん。 fatal runtime error: stack overflow が発生する堎合がある 実装内容によっおは実行時に Stack Overflow ゚ラヌが発生する堎合がありたす。 コンパむル゚ラヌずしお怜出されないのが非垞に厄介で、か぀具䜓的にどの箇所が問題なのか、゜ヌスコヌドを芋るだけでは刀断が぀きたせん。 原因の探し方ですが、rust-lldb を䜿っおスタックトレヌスを確認するこずで、Stack Overflow ゚ラヌが発生したコヌドを特定するこずができたす。 # LLDB でバむナリを起動する rust-lldb target/debug/your-bin # 実行 run # Stack Overflow が発生したらバックトレヌスを確認 thread backtrace all 解決が難しい堎合の別案ずしお、もっずも安党か぀かんたんな解決策は map や and_then によるメ゜ッドチェヌンをやめ、1 行ず぀凊理を曞いおいく圢です。 async fn handle(&self, input: InputData) -> Result<OutputData, UseCaseError> { railway::begin(self.uow()).await?; let output = railway::validate_email(&input.email)?; let output = railway::authenticate(output, input.password, self.authenticator()).await?; let output = railway::update_last_access(output, self.user_repository()).await?; let output = railway::commit(output, self.uow()).await?; railway::end(output) } これはこれで悪くありたせんが、メ゜ッドチェヌンによるパむプラむンがなくなり、どうにでも曞けおしたうずいう問題が発生したす。なので本圓にどうしおも解決が難しい堎合のみこの圢匏に眮き換えるずいうのが安党ず思いたす。 なお、他の方法ずしおは RUST_MIN_STACK 倉数の倀を远加するこずでスタック領域を拡匵できたす。しかしこれは問題を先送りにしおいるだけで、い぀の日か Stack Overflow ゚ラヌが再発しかねたせん。そのため、この解決方法はあたりおすすめできたせん。 ちなみにわたしの事䟋では、デバッグビルドの時に railway モゞュヌル内に定矩した関数の䞭で、非同期凊理を䞊列実行する堎合に起こるケヌスがありたした。 async/await は Future 型の糖衣構文ですが、 rust-lang/rust#132050 を芋るず実行時に Future 型の持぀状態がスタック領域ぞ展開されるため、倚くの async 関数を実行する時に Stack Overflow ゚ラヌを匕き起こしおしたうようです。 このケヌスでは、䞊列で凊理したい Future 型のデヌタを Vec 型のデヌタぞ栌玍するこずで察凊できたした Vec 型の倀はヒヌプ領域に栌玍される ためです。 凊理フロヌが明確になる代わりにコヌドは増える Rust で Railway Oriented Programming を導入するず、各関数を map ず and_then で぀なぎ合わせおいく圢になりたす。それに加えお、それぞれの関数を定矩しおいく必芁があるので、ふ぀うに曞くより党䜓のコヌド量は増えたす。 たずえば Railway Oriented Programming を適甚しなかった堎合の handle メ゜ッドは impl<T: CreateUserUseCase + Sync> UsesCreateUserUseCase for T { async fn handle( &self, input: CreateUserInputData, ) -> Result<CreateUserOutputData, CreateUserUseCaseError> { // 入力倀の怜蚌 let email = Email::try_from(input.email) .map_err(|_| CreateUserUseCaseError::InvalidEmail)?; let name = UserName::try_from(input.name) .map_err(|_| CreateUserUseCaseError::InvalidUserName)?; // メヌルアドレスの重耇チェック let existing_user = self .user_repository() .find_by_email(&email) .await .map_err(CreateUserUseCaseError::UserRepositoryError)?; if existing_user.is_some() { return Err(CreateUserUseCaseError::AlreadyExistsEmail); } // ナヌザヌの䜜成 let user = self .user_factory() .build(UserFactoryParams { email, name }) .map_err(CreateUserUseCaseError::UserFactoryError)?; // ナヌザヌの保存 let saved_user = self .user_repository() .save(user) .await .map_err(CreateUserUseCaseError::UserRepositoryError)?; // 結果の倉換 Ok(CreateUserOutputData { user: saved_user.into(), }) } } ずなり、関数がなく代わりに handle メ゜ッドの䞭たたは郚分的に関数を切り出すなどで実装するこずになりたす。このため、堎合によっおはこの方がシンプルなこずもあるず思いたす。 なので、かんたんな凊理・分岐がほずんどずいったアプリケヌションの堎合、無理に Railway Oriented Programming を採甚しない方が無難かもしれたせん。 䜙談「リポゞトリパタヌンはどこにある」 この蚘事の本筋ずは盎接関係したせんが、「関数型ドメむンモデリング」では「リポゞトリパタヌンはどこにある」ずいう題でリポゞトリパタヌンに぀いお蚀及されおいお、関数型のアプロヌチではリポゞトリパタヌンを すべおを関数ずしおモデル化し、氞続化を端に远いやるこずで、リポゞトリパタヌンは必芁なくなりたす。 ず曞かれおいたす。 しかしわたしがこのこずに぀いおの意図・方法を読み切れなかったため、この蚘事のコヌドおよびわたしたちのプロゞェクトではリポゞトリパタヌンを採甚しおいたす。 おわりに 以䞊、Railway Oriented Programming を Rust で実践した内容に぀いおの玹介でした。 Rust は非垞に衚珟力が豊かで様々な機胜を持぀蚀語ですが、Railway Oriented Programming を採甚するこずでより匷化できるのではないかず感じおいたす。 もし同じように Rust で Railway Oriented Programming の採甚を怜蚎しおいる方がいらっしゃいたしたら、この蚘事が少しでも参考になれば幞いです。
はじめに この蚘事は KINTOテクノロゞヌズ Advent Calendar 2025 の12日目の蚘事です🎅🎄 こんにちは。クラりドむンフラ所属の束尟です。 AWS re:Inventで発衚された新機胜ではないですが、 個人的に熱いず感じたアップデヌトがあったので玹介したす。 Service Quotasの自動管理機胜です。 2025幎10月に「自動管理蚭定」機胜がGAずなり、 Service Quotasの䞊限倀が近づくず通知が飛ぶようになりたした。 そしお先日、GAのタむミングで予告されおいた「自動調敎」モヌドが远加。 これたでクォヌタ監芖を実装しようずするず、耇雑な構成を自前で甚意する必芁がありたしたが、 この機胜を䜿えばコン゜ヌルからポチポチするだけでクォヌタの監芖から自動調敎たでやっおくれたす。 しかも無料です。 ただ、先に蚀っおおくず自動調敎に぀いお、「党郚のクォヌタに察応しおいるわけではない」ずいう制玄がありたす。 この蚘事では、実際に怜蚌しおわかった仕様や制玄を曞いおいきたす アップデヌトの経緯 日付 内容 2025幎10月 自動管理機胜の远加。远加時は「通知のみ」モヌドがGA。自動調敎モヌドの予告あり 2025幎11月 「通知ず自動調敎」モヌドが远加 公匏アナりンス AWS Service Quotas の自動クォヌタ管理の䞀般提䟛を開始 - AWS AWS Service Quotas now supports automatic quota adjustment 䜕が嬉しいのか Before埓来の方法 クォヌタ監芖を実装するには、こんな構成が必芁でした https://aws.amazon.com/solutions/implementations/quota-monitor/ 出兞: AWS Solutions Library CloudWatch Alarmsでメトリクスを監芖 Lambda関数でService Quotas APIを叩いお䞊限緩和リク゚ストを送信 EventBridgeでトリガヌ蚭定 SNSで通知 Amazon DynamoDB 監芖察象のクォヌタの管理 これだずかなり耇雑な構成になるので構築、運甚が倧倉でした。 After自動管理機胜 コン゜ヌルで数クリックで蚭定完了 80%/95%で自動通知 「自動調敎」モヌドなら自動で䞊限緩和リク゚ストたで送っおくれる 今たでクォヌタ監芖で必芁だったリ゜ヌスの料金の発生はなし 埓来たでの方法ず比べ、耇雑な蚭定は無し。かなり導入がしやすそうです。 Before After 蚭定の手間 Lambda/EventBridge/SNS/DynamoDB等の構築が必芁 コン゜ヌルで数クリック 通知タむミング 自分で閟倀を蚭定 80%/95%で自動通知固定 クォヌタ調敎 Lambda等で自前実装 自動調敎モヌドで察応 料金 各リ゜ヌスの料金が発生 無料 機胜の仕様 通知タむミング 公匏ドキュメント によるず、以䞋のタむミングで通知が送信されたす 80% 䜿甚率に達した時 95% 䜿甚率に達した時 重芁この閟倀は固定です。 コン゜ヌルで蚭定するずき「あれ、閟倀蚭定するずころないな」っお思ったんですが、そもそも倉曎できない仕様でした。 「70%で通知が欲しい」みたいなカスタマむズはできないので、その堎合は埓来通りCloudWatch Alarmsを䜿う必芁がありたす。 自動管理モヌド モヌド 説明 通知のみNotifyOnly 80% / 95%で通知を送信 通知ず自動調敎NotifyAndAdjust 通知に加えお、自動でクォヌタ増加リク゚ストを送信 通知先 AWS User Notificationsず統合されおいお、以䞋の通知先を蚭定できたす EメヌルSES経由、サポヌトされおいないリヌゞョンからのむベントはバヌゞニア経由で送信 AWS コン゜ヌルモバむルアプリケヌション事前にアプリのむンストヌルずプッシュ通知の有効化が必芁 チャットチャネルAmazon Q Developer経由でSlack/Teamsに配信、事前にチャットクラむアントの蚭定が必芁 料金 無料で䜿甚できたす。 自動管理機胜自䜓には远加料金はかかりたせん。 通知に䜿われるAWS User Notificationsも無料ですが、 裏で呌び出しおいるSES・モバむルプッシュ・Amazon Q Developerの䜿甚や、 自動管理機胜ずは別にCloudWatch Alarmsで独自の監芖を蚭定する堎合は、別途料金がかかる堎合がありたす。 蚭定方法 📝 補足 : 2025幎11月時点では本機胜は珟圚Terraformでは察応しおおりたせん コン゜ヌルでの蚭定 Service Quotasコン゜ヌルを開く 巊メニュヌから「自動管理」を遞択 「自動管理を開始」をクリック 自動管理モヌドを遞択「通知のみ」たたは「通知ず自動調敎」 通知蚭定を構成オプション 䟋倖蚭定を構成オプション 確認しお送信 めちゃくちゃ簡単。 CLIでの蚭定 以䞋はus-west-2オレゎンリヌゞョンでの蚭定䟋です。 # User Notificationsの通知先ず自動調敎を指定する堎合 aws service-quotas start-auto-management \ --opt-in-level ACCOUNT \ --opt-in-type NotifyAndAdjust \ --notification-arn arn:aws:notifications::xxxxxxxxxxxx:configuration/xxxxx \ --region us-west-2 公匏ドキュメント ⚠ 泚意 : リヌゞョンごずに蚭定が必芁です。オレゎンリヌゞョンで蚭定しおも、東京リヌゞョンには適甚されたせん。 CLIで党リヌゞョン蚭定する堎合はスクリプトを組むなどの察応が必芁です。 内郚の仕組みむベントパタヌン 自動管理を蚭定するず、内郚的にはAWS User Notificationsの詳现フィルタヌずしお以䞋のようなむベントパタヌンが蚭定されたす { "source": ["aws.health"], "detail-type": ["AWS Health Event"], "detail": { "service": ["SERVICEQUOTAS"], "eventTypeCode": [ "AWS_SERVICEQUOTAS_THRESHOLD_BREACH", "AWS_SERVICEQUOTAS_INCREASE_REQUEST_FAILED", "AWS_SERVICEQUOTAS_APPROACHING_THRESHOLD" ], "eventTypeCategory": ["accountNotification"] } } 各むベントタむプの意味 公匏ドキュメント  eventTypeCode 意味 AWS_SERVICEQUOTAS_APPROACHING_THRESHOLD 調敎可胜な クォヌタが閟倀に近づいた。自動調敎モヌドならここでクォヌタの匕き䞊げリク゚ストが送信される AWS_SERVICEQUOTAS_THRESHOLD_BREACH 調敎できない クォヌタが閟倀を超過。クォヌタの匕き䞊げできないので䜿甚率を最適化する必芁あり AWS_SERVICEQUOTAS_INCREASE_REQUEST_FAILED クォヌタの匕き䞊げリク゚ストが倱敗した 実際に怜蚌しおみた 怜蚌環境 リヌゞョンus-west-2オレゎン 自動管理モヌド通知ず自動調敎 必芁な暩限 自動管理機胜を䜿甚するために必芁な暩限、および閲芧暩限は以䞋の通りです。 䜿甚するために必芁な暩限 ServiceQuotasFullAccess AWSHealthFullAccess 閲芧するために必芁な暩限 AWSHealthFullAccess 察応クォヌタの確認 コン゜ヌルの「サポヌトされおいるクォヌタを衚瀺」から確認しおみたんですが、リリヌス盎埌だからか思ったより察応範囲が限定的でした。 今埌、察応するリ゜ヌスが増えるこずを期埅したいです。 察応しおいたサヌビスの䟋 AWS Systems Manager Amazon EC2 WAFRegionalのみ ELB Lambda Route53 IAM 察応しおいなかったサヌビスの䟋 VPC API Gateway EventBridge Amazon Simple Email ServiceSES Route53やIAMなどのグロヌバルサヌビスの堎合、通知のみできるようで自動調敎には察応しおいない印象でした 自動調敎の動䜜確認 AWS WAFの「Maximum regex pattern sets per account in WAF for regional」で怜蚌しおみたした。 このクォヌタはデフォルト倀が10なので、8個䜜成すれば80%に到達したす。 怜蚌手順 1. 事前準備 たずはService Quotasで自動管理の蚭定を行いたす。 Service Quotasの自動管理を「通知ず自動調敎」モヌドで有効化 オレゎンリヌゞョンで蚭定した際、キャプチャしおなかったのでバヌゞニアリヌゞョンでの蚭定画面になりたすmm 通知蚭定に移りたす。ここではAWS User Notificationsの蚭定を行いたす。 今回はAmazon Q Developerを甚意し、Slackチャンネルに通知するようにしたした。 ⚠ 泚意 : むベント゜ヌスのリヌゞョンを遞択できたすが、自動管理を有効にしおいるリヌゞョンのむベントしか受け取れないため、 監芖したいリヌゞョンごずに自動管理の蚭定が必芁です自動管理ずAWS User Notificationsは別蚭定だからちょっずややこしい 自動管理の䟋倖ずするサヌビスを遞択できたすが、今回は䜕も蚭定しないたた䜜成 2. 正芏衚珟パタヌンセットを䜜成 次に正芏衚珟パタヌンセットを䜜成し、閟倀に匕っかかるようにしたす。 WAFコン゜ヌル → 正芏衚珟パタヌンセット → 「Create regex pattern set」 リヌゞョンus-west-2オレゎン※Regionalを遞択 適圓な名前で8個䜜成 3. 䜿甚率の確認 Service Quotas → AWS WAF → 「Maximum regex pattern sets per account in WAF for regional」 䜿甚率が80%になっおいるこずを確認したした 4. 通知/自動調敎の発動を埅぀ 数分埅機... 怜蚌結果 通知/自動調敎反映たでの時間正確には確認できおいたせんが、数分皋床で完了 クォヌタ倀10→11に。自動調敎埌のクォヌタ倀の指定はできたせんが、80%を切るようなクォヌタに曎新しおくれそう 通知に関しお、Slack通知は芋づらい 改行コヌド \n がそのたた衚瀺されおしたい、長文が䞀塊になっおいたす。 たた、通知本文には「どのクォヌタが閟倀に近づいたか」の具䜓的な情報が含たれおおらず、 通知文に添付のリンクからAWS Health Dashboardの「Affected resources」タブを確認する必芁がありたす。 通知ずしおは「䜕か閟倀に近づいた」こずはわかるが、詳现確認には䞀手間かかる印象です。 泚意点・制玄 1. 察応クォヌタが限定的 正盎、今のずころこれが䞀番倧きな制玄だなず感じたした。 VPCやSESずいった基本的なサヌビスのクォヌタが察応しおいないのは残念です。 珟時点ではService Quotaの自動管理だけでは「クォヌタ呚りの調敎がすべお解決」ずはならない。 察応クォヌタの拡倧を今埌埅぀しかないです。 2. 閟倀のカスタマむズ䞍可 80%/95%の閟倀は固定。「50%で早めに通知が欲しい」「100%になるたでは通知䞍芁」みたいな芁件には察応できたせん。 3. AWS Organizations察応は未実装 2025幎11月時点では、Organizations単䜍での䞀括蚭定には察応しおいないため、 各アカりントで個別に蚭定する必芁がありたす。 CLIコマンドには --opt-in-level ずいうオプションがCLIであるのでい぀か察応されるこずを期埅したいです。 4. 自動調敎の承認は保蚌されない 自動調敎はあくたで「䞊限緩和リク゚ストを自動送信する」機胜です。 リク゚ストがAWSに承認されるかどうかは別の話で、拒吊される可胜性もありたす。 5. 通知・自動緩和たでに時間がかかる堎合がある クォヌタが11に䞊がった盎埌、正芏衚珟パタヌンを3぀远加しお合蚈11個にしお䜿甚率を100%にしおみたした。 が、今床は通知もされず、自動調敎もありたせんでした。 しかし数時間埌、自動調敎されおいるこずが確認できたこずから、 堎合によっおは通知や自動調敎たでに時間がかかるこずがあるようです。 たずめ Service Quotasの自動管理機胜は、クォヌタ監芖のハヌドルを倧きく䞋げおくれる個人的にはかなり良いアップデヌトです。 無料で始められお、コン゜ヌルから数クリックで蚭定できたす。 察応クォヌタがただ限定的だったり、IaCTerraform未察応だったりずただただ制玄はありたすが、 サポヌトされおいるクォヌタに関しおは実際にクォヌタ拡匵䜜業の工数を削枛できるこずがわかりたした。 匊瀟では独自実装のクォヌタ管理ツヌルも運甚しおおり、 自動管理機胜でサポヌトされおいないクォヌタに぀いおは匕き続きそちらで察応しおいく予定です。 以䞊、この蚘事が誰かの参考になれば幞いです。
Introduction This article is Day 12 of the KINTO Technologies Advent Calendar 2025 . Hello. I'm Matsuo from the Cloud Infrastructure Group. While this wasn't announced at AWS re:Invent, there was an update that I personally found exciting, so I'd like to share it. It's the automatic management feature for Service Quotas. In October 2025, the automatic management settings feature became generally available, enabling notifications when Service Quotas limits are approaching. Then recently, the automatic adjustment mode that was announced at GA was added. Previously, implementing quota monitoring required building a complex architecture yourself, but with this feature, you can set up quota monitoring and automatic adjustment just by clicking through the console. And it's free. However, I should mention upfront that automatic adjustment doesn't support all quotas. In this article, I'll share the specifications and constraints I discovered through actual testing! Update Timeline Date Content October 2025 Automatic management feature added. At launch, only Notify Only mode was GA. Automatic adjustment mode was announced November 2025 Notify and Adjust mode was added Official announcements: AWS Service Quotas の自動クォヌタ管理の䞀般提䟛を開始 - AWS AWS Service Quotas now supports automatic quota adjustment What Makes This Great Before (Traditional Method) To implement quota monitoring, you needed an architecture like this: https://aws.amazon.com/solutions/implementations/quota-monitor/ Source: AWS Solutions Library Monitor metrics with CloudWatch Alarms Lambda functions to call Service Quotas API and send quota increase requests EventBridge trigger configuration SNS for notifications Amazon DynamoDB for managing monitored quotas This resulted in quite a complex architecture that was difficult to build and maintain. After (Automatic Management Feature) Setup complete with just a few clicks in the console Automatic notifications at 80%/95% Automatic Adjustment mode automatically sends quota increase requests No charges for resources that were previously needed for quota monitoring Compared to the previous method, there's no complex configuration. It seems much easier to adopt. Before After Setup effort Required building Lambda/EventBridge/SNS/DynamoDB etc. Just a few clicks in the console Notification timing Set thresholds yourself Automatic notifications at 80%/95% (fixed) Quota adjustment Self-implemented with Lambda etc. Handled by automatic adjustment mode Cost Charges for each resource Free Feature Specifications Notification Timing According to the official documentation , notifications are sent at the following thresholds: When 80% utilization is reached When 95% utilization is reached Important: These thresholds are fixed. When configuring in the console, I thought "Hmm, where do I set the threshold?" but it turns out it's not configurable by design. Customizations like "I want notifications at 70%" aren't possible, so you'd still need to use CloudWatch Alarms for that. Automatic Management Modes Mode Description Notify Only (NotifyOnly) Sends notifications at 80% / 95% Notify and Adjust (NotifyAndAdjust) In addition to notifications, automatically sends quota increase requests Notification Destinations It's integrated with AWS User Notifications, and you can configure the following notification destinations: Email (via SES; events from unsupported regions are sent via Virginia) AWS Console Mobile Application (requires prior app installation and push notification enablement) Chat channels (delivered to Slack/Teams via Amazon Q Developer; requires prior chat client configuration) Pricing It's free to use. There are no additional charges for the automatic management feature itself. AWS User Notifications used for notifications is also free, but if you use SES, mobile push, or Amazon Q Developer behind the scenes, or if you set up custom monitoring with CloudWatch Alarms separately from the automatic management feature, additional charges may apply. Configuration Method Note : As of November 2025, this feature is not yet supported in Terraform Console Configuration Open the Service Quotas console Select Automatic management from the left menu Click Start automatic management Select the automatic management mode (Notify Only or Notify and Adjust) Configure notification settings (optional) Configure exception settings (optional) Review and submit Super easy. CLI Configuration Here's an example configuration for the us-west-2 (Oregon) region. # When specifying User Notifications destination and automatic adjustment aws service-quotas start-auto-management \ --opt-in-level ACCOUNT \ --opt-in-type NotifyAndAdjust \ --notification-arn arn:aws:notifications::xxxxxxxxxxxx:configuration/xxxxx \ --region us-west-2 Official documentation Note : Configuration is required for each region. Setting it in the Oregon region doesn't apply to the Tokyo region. If you want to configure all regions via CLI, you'll need to write a script or similar. Internal Mechanism (Event Pattern) When you configure automatic management, internally an event pattern like the following is set as a detailed filter in AWS User Notifications: { "source": ["aws.health"], "detail-type": ["AWS Health Event"], "detail": { "service": ["SERVICEQUOTAS"], "eventTypeCode": [ "AWS_SERVICEQUOTAS_THRESHOLD_BREACH", "AWS_SERVICEQUOTAS_INCREASE_REQUEST_FAILED", "AWS_SERVICEQUOTAS_APPROACHING_THRESHOLD" ], "eventTypeCategory": ["accountNotification"] } } Meaning of each event type ( official documentation ): eventTypeCode Meaning AWS_SERVICEQUOTAS_APPROACHING_THRESHOLD An adjustable quota is approaching the threshold. In automatic adjustment mode, a quota increase request is sent here AWS_SERVICEQUOTAS_THRESHOLD_BREACH A non-adjustable quota has exceeded the threshold. Since the quota cannot be increased, you need to optimize usage AWS_SERVICEQUOTAS_INCREASE_REQUEST_FAILED The quota increase request failed Actual Testing Test Environment Region: us-west-2 (Oregon) Automatic management mode: Notify and Adjust Required Permissions The permissions required to use the automatic management feature and view permissions are as follows. Permissions required to use: ServiceQuotasFullAccess AWSHealthFullAccess Permissions required to view: AWSHealthFullAccess Checking Supported Quotas I checked from View supported quotas in the console, but perhaps because it was just after release, the coverage was more limited than I expected. I hope the supported resources will expand in the future. Examples of supported services: AWS Systems Manager Amazon EC2 WAF (Regional only) ELB Lambda Route53 IAM Examples of unsupported services: VPC API Gateway EventBridge Amazon Simple Email Service (SES) For global services like Route53 and IAM, it seems only notifications are available and automatic adjustment is not supported Verifying Automatic Adjustment Behavior I tested with AWS WAF's Maximum regex pattern sets per account in WAF for regional. This quota has a default value of 10, so creating 8 would reach 80%. Test Procedure 1. Preparation First, configure automatic management in Service Quotas. Enable automatic management in Service Quotas with Notify and Adjust mode (I didn't capture the screen when setting up in the Oregon region, so this is the settings screen from the Virginia region) Move to notification settings. Here you configure AWS User Notifications. This time, I set up Amazon Q Developer to send notifications to a Slack channel. Note : You can select the event source region, but since you can only receive events from regions where automatic management is enabled, you need to configure automatic management for each region you want to monitor (it's a bit confusing because automatic management and AWS User Notifications are separate settings) You can select services to exclude from automatic management, but this time I created it without any settings 2. Create Regex Pattern Sets Next, create regex pattern sets to trigger the threshold. WAF console -> Regex pattern sets -> Create regex pattern set Region: us-west-2 (Oregon) *Select Regional Create 8 with arbitrary names 3. Check Utilization Service Quotas -> AWS WAF -> Maximum regex pattern sets per account in WAF for regional Confirmed that utilization was at 80% 4. Wait for Notification/Automatic Adjustment Wait a few minutes... Test Results Time until notification/automatic adjustment: Not confirmed precisely, but completed in a few minutes Quota value: Changed from 10 to 11. You can't specify the quota value after automatic adjustment, but it seems to update to a quota that falls below 80%. Slack notifications are hard to read Newline codes ( \n ) are displayed as-is, making long text appear as one block. Also, the notification body doesn't include specific information about which quota is approaching the threshold, so you need to check the Affected resources tab in the AWS Health Dashboard via the link attached to the notification. As a notification, you can tell something is approaching the threshold, but it takes extra effort to check the details. Notes and Constraints 1. Limited Supported Quotas Honestly, this is the biggest constraint I felt at the moment. It's disappointing that quotas for basic services like VPC and SES aren't supported. Currently, automatic management of Service Quotas alone won't handle all quota-related issues. We'll have to wait for the supported quotas to expand. 2. Thresholds Cannot Be Customized The 80%/95% thresholds are fixed. Requirements like "I want early notifications at 50%" or "No notifications needed until 100%" cannot be accommodated. 3. AWS Organizations Support Not Implemented As of November 2025, bulk configuration at the Organizations level is not supported, so you need to configure each account individually. There's an --opt-in-level option in the CLI command, so I hope it will be supported eventually. 4. Automatic Adjustment Approval Is Not Guaranteed Automatic adjustment is merely a feature that automatically sends quota increase requests. Whether the request is approved by AWS is a separate matter, and it may be rejected. 5. Notifications/Automatic Increases May Take Time Right after the quota was raised to 11, I added 3 more regex patterns for a total of 11, bringing utilization to 100%. However, this time there was no notification and no automatic adjustment. But several hours later, I confirmed that automatic adjustment had occurred, so it seems that notifications and automatic adjustments may take time in some cases. Conclusion The automatic management feature for Service Quotas is personally a really great update that significantly lowers the barrier to quota monitoring. It's free to start and can be configured with just a few clicks from the console. There are still constraints like limited supported quotas and no IaC (Terraform) support, but I found that for supported quotas, it can actually reduce the effort required for quota expansion work. At our company, we also operate a custom-built quota management tool, and we plan to continue using it for quotas that aren't supported by the automatic management feature. I hope you found this article helpful.
This article is the 12th entry in the KINTO Technologies Advent Calendar 2025 . Introduction I'm Uehara ( @penpen_77777 ), a backend engineer in the FACTORY E-commerce Development Group at KINTO Technologies. I participated in Techbook Fest 19 as part of the KINTO Technologies Writing Club, a circle (a small creator group) formed by volunteer engineers at KINTO Technologies. In this article, I'll share our journey of creating a technical book with company volunteers. Here's the introduction to the new book we created! It's free. If you're interested, please download the digital version. https://blog.kinto-technologies.com/posts/2025-10-31-techbookfest19-announcement/ https://techbookfest.org/product/qCPrJpWLmKnLt7eWVd9zJ6 The Beginning I had written technical books before and had been wanting to write one again after a long break. While tech blogs and presentations are sufficient for getting your writing read by others, there's something deeply satisfying about seeing your writing become a physical book. Since our company had never organized a circle of employee volunteers to write technical books, I decided to take on this challenge. Building the Team Finding Supportive People I started working on this in June, about six months before participating in Techbook Fest. Finding supportive people early on is extremely helpful when moving tasks forward. Our company has a Developer Relations Group that can provide consultation for employees' external technical communications. I truly believe we were able to accomplish this thanks to the Developer Relations Group. I'm very grateful. Finding People Interested in Writing Since participating in Techbook Fest was a first-time endeavor, I was worried about whether we could actually gather participants. Announcing a call for participants company-wide out of the blue felt like a high hurdle. So I decided to reach out to people who seemed interested and gather those who were highly likely to participate in advance. At our company, many people use times (personal update channels) on Slack, which is great for casually expressing your thoughts. By hinting at my desire to exhibit at Techbook Fest, I was able to know who might be interested. About five people gathered at this point, so I felt reassured that even if a company-wide announcement didn't attract more participants, we could still make the project work. Making the Announcement I created a simple slide to recruit writers company-wide. It summarized information about Techbook Fest and the benefits of writing, designed to encourage participation. The official sponsorship materials were helpful for introducing the scale of the event. https://techbookfest.org/assets/tbf18/for-sponsors.pdf Selecting a Printing Company Since we were creating a physical book, we needed to select a printing company. Techbook Fest has designated backup printing companies, and by submitting your manuscript to one of them, they handle everything from printing to delivering it to the venue. It’s a very convenient system. The backup printing companies are Nikko Kikaku and Neko no Shippo, and we chose Nikko Kikaku for this project. Selecting and Configuring the Typesetting System A typesetting system converts manuscripts into a print-ready format. Re:VIEW is commonly used as a typesetting system for technical books. By processing text files written in the proprietary Re:VIEW format through Re:VIEW, they are converted into formats commonly used for e-books such as EPUB and PDF. The benefit is that the separation of page style settings from content allows writers to focus on the essential task of writing without worrying about appearance. For this project, we used Vivliostyle^[It reads "kumihan," but I always mistakenly read it as "soban." https://ja.wikipedia.org/wiki/%E7%B5%84%E7%89%88] as our typesetting system. https://vivliostyle.org/ja/ Vivliostyle's distinguishing feature is the ability to change appearance using CSS, so anyone familiar with frontend technologies should be able to use it without difficulty. Since setting everything up from scratch would be challenging, we utilized a template distributed by YUMEMI. We're very grateful for the distribution of such a template. Thank you! https://github.com/yumemi-inc/daigirin-template Based on the above template, we made the following modifications: Updated the title, publisher, and colophon for our technical book Changed the paper size to B5^[This is when I learned that B5 comes in both JIS B5 and ISO B5. Be careful, as they have different dimensions despite both being called B5.] Enabled automatic table of contents output and adjusted the template for sections that weren't outputting correctly Registering Your Circle for Techbook Fest While there's a lot to prepare, don't forget to submit your circle participation application. It might be a good idea to add it to your calendar. Having Writers to Write I created and shared guidelines so writers wouldn't struggle with the writing process. Overall schedule and what to do in each phase Writing methods (Vivliostyle Flavored Markdown^[A notation that extends common markdown to express book-specific structures. https://vivliostyle.github.io/vfm/#/] syntax, PDF preview methods, etc.) Manuscript Management We managed manuscripts on GitHub, with each writer branching off from the main branch to write. Having each writer create a PR is convenient for tracking progress. Using Slack Lists To prevent topic overlap within the book, I asked writers to add their topics to a Slack list once decided. It's also helpful to include other information you want to track, such as self-introductions for the appendix and writing status. While we could have managed this with tables in Confluence, I personally check Slack more frequently, so I managed it using Slack lists, which can be used similarly to Notion databases. Getting the Book Cover Created When I was wondering whether to create the book cover myself, one of the participants suggested asking designers from the Creative Office for help. Since we wanted to create it in a fun, collaborative way, we decided to hold a Generative AI × Live Visual Creation event where designers would create the cover using generative AI. The event held to create this technical book: Vibe Painting Hour #01 Five designers joined the event and, while participants watched, used generative AI to create covers within a one-hour time limit. Despite my vague request to create a cover with a sense of mobility and futuristic feel, all five final cover proposals were of such high quality that choosing only one seemed like a waste! Through participant voting and my judgment, the cover for this technical book was selected. ![衚玙](/assets/blog/authors/uehara/2025-10-24-techbookfest19-announcement/cover.webp =300x) The cover of our new book, TECH BOOK By KINTO Technologies Vol.01. Setting Manuscript Deadlines This is important. The submission deadline is absolute, so you should set it with plenty of buffer time. Also, it's best to assume that manuscripts won't be ready on the first try. You should set not just one deadline but two or three backup deadlines, with minimum requirements for each deadline. Having Writers Review Each Other's Work We had writers review each other's work. The review items followed our external communication review guidelines, while also keeping in mind that the final product would be a physical book. Since you can't even start reviewing without all manuscripts being submitted, I recommend setting the second deadline early. Proofreading After compiling all manuscripts, we adjusted the overall page layout. After noticing the font size was too small, I made it slightly larger. The table of contents had grown to 10 pages, so I narrowed down the items to include. We also had to adjust the page count to be a multiple of four, or the submission wouldn't be accepted. This caused display issues in some chapters, so we asked writers to make corrections. Since we were working under time pressure, we decided to set the third deadline early. Submission Once the PDF file for submission was ready, we submitted it to the printing company. With Nikko Kikaku, we paid in advance and then sent the cover and body data via a form. If there were any data issues, they would point them out and we'd need to resubmit. This time there were no issues and submission went smoothly. Booth Setup Simulation With help from a Developer Relations team member who was experienced with booth setup, we carried out a simulation the day before. By visualizing the booth in advance and identifying what we needed, I think we avoided the situation where we'd look at the actual booth on the day and feel like "hmm, this isn't quite what I imagined..." The Day of the Offline Event When I first saw the finished book at the offline venue, I thought it was thicker than expected. Since we distributed this thick book for free, we heard surprised reactions from attendees. We printed about 300 copies and distributed them all, so I think it was a great result for our first participation! https://x.com/KintoTech_Dev/status/1989983294059168095 Depositing at the National Diet Library The day after Techbook Fest, we deposited the book at the National Diet Library. Apparently, publications issued for distribution within Japan are generally subject to legal deposit, and even technical doujinshi like ours can be deposited. https://www.ndl.go.jp/jp/collect/deposit/deposit.html Publications issued for distribution within Japan are, in principle, all subject to legal deposit (see "Overview of the Legal Deposit System"). When you deposit publications with the National Diet Library, their bibliographic data becomes searchable as the "National Bibliography" through the NDL Search. Additionally, they are widely used as library materials, preserved as cultural assets shared by the nation, and passed down to future generations as records of the Japanese people's intellectual activities. I also referenced the following article for the deposit process. https://qiita.com/mitsuharu_e/items/850ae6688a94ea3d67f3 : Off to Deposit Being a central government location, various train lines converge here, including the Ginza, Marunouchi, and Hanzomon lines. Exit 2 is the closest to the National Diet Library, so depending on your line, you may need to walk a bit. Area directory near the station. Exit 2 is the closest. I took the Ginza Line, so I had to walk quite a bit. National Diet Library sign. There's a notice that those depositing materials should go to the service entrance (west gate). Enter through the National Diet Library's service entrance (west gate) and tell the security guard at the building entrance that you want to deposit books, and they'll handle the procedure. National Diet Library service entrance (west gate) At the deposit counter, hand over the book and fill out the paperwork. Once the procedure is complete, they'll give you a receipt. Material receipt After depositing, the book appears in National Diet Library Search results and becomes available to read as a resource at the National Diet Library. https://ndlsearch.ndl.go.jp/books/R100000002-I034410569 Reflections After Completion Don't Try to Do Everything Alone; Reach Out for Help Even creating just one book involves many decisions and tasks, and handling everything alone is quite difficult. It's better to delegate tasks that others can do, or that others can do better than you. The Technical Book Expanded Our Connections As well as interacting with attendees at the Techbook Fest offline venue, I believe the connections among company volunteers deepened through creating the technical book. Set Multiple Early Deadlines Even though I thought I had set deadlines with plenty of buffer, I still ended up feeling short on time. Next time, I plan to build in an even larger margin. Setting multiple deadlines is important. Summary While there were many challenges on the road to participating in Techbook Fest 19, looking back, we gained a lot and it was truly enjoyable. If this article has piqued your interest, please try taking on the challenge of creating a technical book. We'll keep working hard so that we can show up even stronger at future Techbook Fests! https://techbookfest.org/product/qCPrJpWLmKnLt7eWVd9zJ6