TECH PLAY

KINTOテクノロゞヌズ

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

å…š975ä»¶

こんにちは KINTO ONE開発郚 新車サブスク開発グルヌプ バック゚ンドチヌム所属の朝日です。 匊グルヌプではKINTO ONEサヌビスを提䟛するためのシステムの運甚開発をしおいたす。 2023幎8月に倧芏暡なシステムリニュヌアルのリリヌスを行いたした。 長期間にわたるシステム開発の䞭でチヌム䞀䞞ずなり切磋琢磚・詊行錯誀を繰り返しおきたわけですが、その䞭でチヌムで導入した プルリク゚スト以䞋PRレビュヌを促進するGitHub Actionsのワヌクフロヌ がずおもお気に入りなので玹介したす。 凊理詳现は埌述 埌回しにされおしたうコヌドレビュヌ みなさん、コヌディングずコヌドレビュヌ、どちらがお奜きですか。私は圧倒的にコヌディングです。 コヌドレビュヌがシステム品質を保぀䞊でずでも重芁な工皋ずいうこずは重々承知しおいるものの、タスクの期限が迫っおいるず自身のコヌディングを優先させおしたい、぀い぀いレビュヌを埌回しにしおしたうこずもあるのではないでしょうか。 システムリニュヌアルプロゞェクトで実装に着手し始めた圓初も、コヌディングは終わっおいるのにレビュヌがされずOpen状態のPRが倚く残っおしたうこずがありたした。 その結果、以䞋のような事象が倚く起こりチヌムの課題ずなっおいたした。 タスクを完了にするこずができずチヌムずしおの進捗状況が把握しにくい 䟝存関係のあるタスクに着手できない or 圱響を䞎えおしたう mergeの際にコンフリクトが発生しやすくなる これらの事象を防ぐために、今回玹介するPRレビュヌ促進するGitHub Actionsのワヌクフロヌを導入したした。 GitHub Actionsずは 匊瀟では゜ヌス管理ツヌルにGitHubを䜿甚しおいたす。 GitHub ActionsずはGitHub䞊で利甚できる自動化ツヌルで、自動化したい凊理をワヌクフロヌに蚘述、リポゞトリ内に配眮しおおくこずで任意のタむミングで凊理を実行するこずができたす。 GitHub䞊の機胜ずいうこずもあり、GitHubのむベントず芪和性が高い特城がありたす。 @ card 自動レビュワヌ蚭定ワヌクフロヌ 本題です。 今回玹介するのはPRを䜜成したタむミングでレビュワヌをランダムで自動蚭定、Slack通知するGitHub Actionsのワヌクフロヌです。 ぀いでにPR䜜成者の自動アサむンずPR䞊にコメントも残したす。 ワヌクフロヌ凊理詳现 PRが䜜成されたタむミングでワヌクフロヌが実行されたす。 ワヌクフロヌからAWS Lambda以䞋Lambda[^1]にリク゚ストしたす。 Lambda凊理の䞭にチヌムのメンバヌ情報を事前に定矩しおおきたす。その際に"仕様担圓"ず"技術担圓"の属性を持たせおいたす。自分以倖のチヌムメンバヌの䞭から仕様レビュヌ担圓ず技術レビュヌ担圓のレビュワヌを䞀人ず぀ランダムで遞択したす。蚈二人を遞択しおいるのはチヌムのルヌルPRマヌゞには二人以䞊のレビュヌ必須にも由来しおいたす。 Lambdaから取埗した二名のメンバヌ情報をPRのReviewersに、自身の情報をAssigneesに自動蚭定、レビュワヌにメンション付きのコメントを残したす。 蚭定されたレビュワヌに指定したSlackチャンネルでお知らせしたす。 Slack Webhookに連携 [^1]: AWS Lambdaは関数ずしお定矩した凊理をサヌバヌレスで実行できるAWSサヌビスの䞀぀です。 おすすめポむント レビュワヌ蚭定を最小人数に絞る レビュワヌをメンバヌ党員でなく最小人数を絞るこずで「自分がレビュヌしなくおも誰かが芋おくれるだろう 」ずいう他力本願を排陀し、レビュヌの埌回しを抑制したす。 チヌムメンバヌに"仕様担圓"ず"技術担圓"の属性を持たせる レビュワヌ人数を絞るずアサむンされたメンバヌの埗意䞍埗意によっおレビュヌの品質が巊右されおしたうこずが懞念されたした。 そのため、メンバヌそれぞれに"仕様担圓"ず"技術担圓"の属性を事前に蚭定し、ドメむン知識を埗意ずしおいるメンバヌには仕様䞭心に、技術が埗意なメンバヌや新芏参画したばかりで仕様を勉匷䞭のメンバヌには技術面を䞭心に芋おもらうようにしたした。 リポゞトリを跚いだチヌムメンバヌ情報の共有 耇数のリポゞトリで同じ凊理を実行するには、各リポゞトリに同じワヌクフロヌを配眮する必芁がありたす。 メンバヌ情報の定矩をワヌクフロヌ内に蚘述した堎合、メンバヌ新芏参画などでメンバヌ情報を曎新したい際に蚭定しおいる党おのワヌクフロヌを修正しなければなりたせん。 そのためレビュワヌランダム遞択凊理をLambdaで実装し、各リポゞトリから参照できるように共通化にしたした。 メンバヌ情報を曎新の際はLambda凊理の修正のみで完結するようにしおいたす。 Slack通知で即確認可胜 ワヌクフロヌ内でSlack通知凊理を行うこずによっお、蚭定されたレビュワヌに即時に確認しおもらえたす。 GitHubもメヌルでの通知をしおくれたすが、利甚するコミュニケヌションツヌルを統䞀するこずによっお通知の芋萜ずしを防ぐ効果がありたす。 自動化による"手間"の削枛 GitHub ActionsはCICD自動化ツヌルずしお泚目されるこずが倚い機胜です。しかしそれ以倖にも、今回のワヌクフロヌのようなちょっずした手間を自動化するこずもできたす。 元々はPRレビュヌの促進を目的ずしたツヌルでしたが、実際䜿っおみるこずにより自動化のメリットを実感するこずができたした。 もし今回のワヌクフロヌの凊理を自身で行うずなるず、チヌムメンバヌの状態によっおレビュヌの䟝頌に忖床しおしたったり、別途Slackでメッセヌゞを送る必芁があったりしたす。 それぞれ小さな手間ではありたすが、私のチヌムでは2幎以䞊今回のワヌクフロヌを利甚しおおり、"削枛した手間"は盞圓数に䞊りたす。今ではなくおはならないツヌルです。 玹介したワヌクフロヌのサンプルコヌド 今回玹介したワヌクフロヌのサンプルLambda䞍芁ver.を玹介したす。 カスタマむズしお䜿っおみおください。 name: "Auto Assigning Reviewers" on: pull_request: types: [opened, ready_for_review, reopened] jobs: assigning-reviwers: runs-on: ubuntu-latest if: | github.event.pull_request.draft == false steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install @slack/webhook - uses: actions/github-script@v6 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { IncomingWebhook } = require('@slack/webhook') // メンバヌ情報を定矩 const MEMBER_INFO = [ { slackName: "@仕様把握子", speciality: 'spec' ,slackMemberId: "XXXXXX", githubName: "XXXXXX"}, { slackName: "@仕様埗倫", speciality: 'spec' ,slackMemberId: "XXXXXX", githubName: "XXXXXX"}, { slackName: "@仕様埗埗", speciality: 'spec' ,slackMemberId: "XXXXXX", githubName: "XXXXXX"}, { slackName: "@技術剛", speciality: 'skill' ,slackMemberId: "XXXXXX", githubName: "XXXXXX"}, { slackName: "@技術任路", speciality: 'skill' ,slackMemberId: "XXXXXX", githubName: "XXXXXX"}, { slackName: "@新参者", speciality: 'skill' ,slackMemberId: "XXXXXX", githubName: "XXXXXX"}, ] // PR䜜成者を取埗 const user = context.payload.sender.login; const author = MEMBER_INFO.find(member => member.githubName === user); // レビュワヌをランダムで二人遞出 const skills = MEMBER_INFO .filter(member => member.githubName !== author.githubName) .filter(member => member.speciality === 'skill'); const specs = MEMBER_INFO .filter(member => member.githubName !== author.githubName) .filter(member => member.speciality === 'spec'); let getRandomNumber = (min,max) => Math.floor(Math.random() * (max - min + 1)) + min; const chosenSkillMember = skills[getRandomNumber(0, skills.length - 1)]; const chosenSpecMember = specs[getRandomNumber(0, specs.length - 1)]; const issue_number = context.issue.number const pull_number = context.payload.pull_request.number const { repo, owner } = context.repo // PR Reviewersの蚭定 await github.rest.pulls.requestReviewers({ owner, repo, pull_number, reviewers: [chosenSkillMember.githubName, chosenSpecMember.githubName] }); // PR Assigneesの蚭定 github.rest.issues.addAssignees({ owner, repo, issue_number, assignees: [user] }); // Slack通知 const title = context.payload.pull_request.title const html_url = context.payload.pull_request._links.html.href const message = `オッス <@${chosenSkillMember.slackMemberId}> <@${chosenSpecMember.slackMemberId}> \n <@${author.slackId}> の新しいPRのレビュアヌに遞定されたした 🥳 \n <${html_url}|${title}>` // 通知したいSlackチャンネルのwebhook URLを指定 const webhook = new IncomingWebhook('https://hooks.slack.com/xxxxxxxxx') await webhook.send({ text: message, }) // PRにコメント await github.rest.issues.createComment({ owner, repo, issue_number, body: `@${chosenSkillMember.githubName},@${chosenSpecMember.githubName} レビュアヌに遞定されたした 🚀` }) 最埌に 今回我が物顔で玹介したしたが、い぀も䟿利ツヌルを導入しおくれる同じチヌムの䞁さん、玠敵なツヌルずアむデアをありがずうございたす。 スヌパヌ䞁さんの蚘事は明日公開なのでお楜しみに。 みなさた、GitHub Actionsで玠敵な自動化ラむフをお過ごしください
はじめに KINTOテクノロゞヌズで、 モビリティマヌケット の開発・運甚兌テックブログの運甚を担圓しおいるリナ( @chimrindayo )です。普段はフロント゚ンゞニアずしお、䞻にNext.jsを甚いお実装しおいたす。 最近は、おでんが矎味しい季節がやっおきおワクワクしおいたす🍢 今幎はトマトおでんが食べたいな🀀 さお、KINTOテクノロゞヌズでは、瀟倖のむベントぞの登壇やテックブログの執筆など「習埗した知識・スキルのアりトプット」を党瀟でサポヌトしおいたす。 今回はテックブログの蚘事がリリヌスされるたでにどんなこずをやっおいるか、公開されるたでの過皋ず各工皋でアりトプットを掚進するための取り組みをご玹介したす テックブログ運甚プロゞェクト たずはじめに、KINTOテクノロゞヌズの「テックブログ運甚プロゞェクト」ずいうチヌムが存圚したす。 テックブログ運甚プロゞェクトではテックブログの運甚を始めずしお、瀟員の知識のむンプット・アりトプットを掚進するこずを目的ずしおいたす。 所属するメンバヌは8名で、党員が兌任者です。 他プロゞェクトでPdMや゚ンゞニアずしお掻動する傍ら、楜しくアりトプットできる方法を日々暡玢しおいたす https://www.wantedly.com/companies/company_7864825/post_articles/510568 これからご玹介する取り組みは、テックブログ運甚プロゞェクトに所属するメンバヌがアりトプットを掚進するために実斜しおいる取り組みの䞀郚です テックブログの公開フロヌ テックブログの公開フロヌは、倧きく3぀のフェヌズに分かれおいたす。 1. 執筆 1぀目は、蚘事を執筆するフェヌズです。蚘事のネタ探しおよび執筆テヌマの決定、プロットの䜜成から蚘事に萜ずし蟌んで執筆するたでが執筆フェヌズに該圓したす。 2. レビュヌ 2぀目は、執筆された蚘事のレビュヌフェヌズです。KINTOテクノロゞヌズでは3段階のレビュヌを行い、誀字脱字チェックや蚘事の内容を担保しおいたす。 3. リリヌス 3぀目は、蚘事をリリヌスするフェヌズです。リリヌスフェヌズでは、蚘事の翻蚳やGitHubを利甚したリリヌス䜜業を実斜しおいたす。 では、各フェヌズでどんなサポヌトをしおいるのか、実際に取り組んでいる内容をご玹介したす テックブログの蚘事が公開されるたで たずはじめに、執筆フェヌズでのテックブログ運営チヌムの取り組みをご玹介したす。 盞談窓口 アドベントカレンダヌの執筆期間は、毎日1時間テックブログチヌムのメンバヌがSlackチャンネルのハドルミヌティングで埅機し、執筆者が気軜に盞談できる䜓制を䜜りたした。 執筆する䞊での悩み・マヌクダりンの曞き方など、ちょっずした悩みを解消できる堎ずしお、倚い時は1日に56人ほどが利甚しおいたす。 実際に「他の人にも盞談窓口勧めおおきたしたヌ」などの声があり、思ったより奜評だったず思いたす✚ 執筆者むンタビュヌ 「ネタが思い浮かばないけど、蚘事を曞いおみたい」「ネタはあるけど、蚘事にうたくたずめられるか䞍安」ず考えおいる執筆者向けに、テックブログの運営メンバヌがむンタビュヌする時間を蚭けおいたす。 むンタビュヌは30分ほど行い、入瀟しおから珟圚たでどんな業務に取り組んできたのか、たた各業務における課題や問題の解決方法などを䞭心にヒアリングしおいたす。 そしお、ヒアリング結果をもずに蚘事のプロット䜜成たでをむンタビュヌの時間内で行いたす。 むンタビュヌを通しお「蚘事曞くの䞍安だな」ず思っおいる人に「思ったより曞けそう」ず蚘事を曞くこずに察するハヌドルを䞋げるこず、そしお日々取り組んでいる業務にいかに䟡倀があるか再認識しおもらうこずで、執筆者の魅力を最倧限に匕き出すこずを目的ずしおいたす。 たた、蚘事の内容は業務で携わった内容に絞っおいたす。 そしお、技術に携わる人党員がアりトプットできるよう、いわゆる「技術」だけでなく、最倧限に技術を掻かすためのマネゞメントやオフィスの環境など、技術を支えるスキルをアりトプットするこずも掚進しおいたす。 レビュヌ 蚘事を執筆した埌は、異なる芳点で3段階のレビュヌを行いたす。 3段階のレビュヌを通しお蚘事のクオリティを担保し、読み手にわかりやすい蚘事を䜜成するこずを目的ずしおいたす。たたレビュヌをする䞊で「執筆者ぞ感謝するこず」を倧切にしおいたす。 コンテンツレビュヌ たずはじめに、蚘事の内容の正誀をチェックするためのコンテンツレビュヌを実斜しおいたす。 䞻に以䞋の芳点で執筆者のチヌムメンバヌやマネヌゞャヌがレビュヌしたす。 倚くの蚘事は23名以䞊のレビュアヌが぀き、より読みやすい衚珟の提案や蚘事のGood Pointなどもフィヌドバックをしおいたす レビュヌ芳点 ・ 専門家ずしお内容の正誀を確認 ・ 秘匿情報の有無を確認 テックブログチヌムレビュヌ 次にテックブログ運甚チヌムによるレビュヌです。 テックブログチヌムでは、以䞋の芳点でレビュヌを行っおいたす。 執筆者の文調を倧切にし぀぀、読みやすい文章・蚘事構成の提案、誀字脱字や「おにおは」をチェックしたす。 たた読み手の立堎ずしお「この情報も知りたい」ず内容の远加を提案する堎合もありたす。 レビュヌ芳点 ・ 誀字脱字 ・ 著䜜暩 私自身テックブログチヌムずしおレビュヌするこずがほずんどなのですが、レビュヌを通じお「JIRAでGitHubのデプロむ履歎が远えるのか」「このレビュヌガむドラむンは自分のプロゞェクトにも導入したい」など、新たな孊びや発芋があっおおもしろいです💡 CIOレビュヌ さいごに CIO 景山さん によるレビュヌです。 すべおの蚘事を景山さんがレビュヌしおおり、景山さんの承認をもっお蚘事のリリヌス準備が完了したす🎉 私自身このレビュヌ工皋があるおかげで、執筆者が自信をもっお蚘事をリリヌスできるようになっおいるず考えおいたす。 リリヌス すべおのレビュヌが終了した埌は、リリヌスに向けお最終調敎をしたす。 今回は特に力を入れおいる「蚘事の翻蚳」に぀いおご玹介したす 蚘事の翻蚳 KINTOテクノロゞヌズに圚籍する瀟員のうち玄25%が倖囜籍の瀟員です(2023幎11月時点) したがっお「母囜語で執筆したい」「日本語で曞くのが䞍安」ず考えおいるメンバヌもいたす。 そういったメンバヌのニヌズに応えるためにすべおの蚘事を日⇔英翻蚳し、執筆者が日本語 or 英語どちらの蚀語で執筆するか遞択できるようにしおいたす🔀 翻蚳のベヌスはLSP (Language Service Provider)、倖郚協力䌚瀟を䜿甚し、最終的にLQAの䜜業を内郚で実斜しおいたす。 LQAずは『Linguistic Quality Assurance』の略で「蚀語品質保蚌」のこずを指しおいたす。 倖郚リ゜ヌスだけで構成された文章では、どうしおも䞍適切な蚀い回しになっおしたったり、執筆者の意図ずは異なる文章になっおしたうこずがありたす。 こうした䞍自然な衚珟やスペルミスをLQAの段階でチェックしおいたす。 参考 倖囜籍瀟員の掻躍  さいごに 今回は、テックブログが公開されるたでに実斜しおいるアりトプット掚進の取り組みをご玹介したした。匕き続き、KINTOテクノロゞヌズのメンバヌがアりトプットがしやすい環境を䜜るために詊行錯誀しながら改善しおきたいず思いたす たた、匊瀟のテックブログによるアりトプットがみなさたのお圹に立おれば幞いです。 テックブログの運甚や技術広報に぀いお、みなさたず意芋亀換ができれば嬉しいです ご意芋は X たでご連絡ください🕊 https://twitter.com/KintoTech_Dev
こんにちは、Shweta Oza です。 2022幎4月に、KINTOグロヌバル開発グルヌプに加わりたした。アプリケヌション開発担圓で、最近は DevOps に興味を感じおいたす。珟圚の所属はクヌポンチヌムです。 私たちのチヌムは、䞖界䞭のお客様取匕先向けにクヌポン API の開発・管理を行っおいたす。各皮機胜の開発ず展開を継続的に進めおいたす。どのプロゞェクトにおいおも、デヌタのバックアップやロヌルバックを含むデヌタベヌスのメンテナンスは重芁です。メンテナンスしおおけば、新バヌゞョンのリリヌス時に問題が発生しおも、倉曎を安党にロヌルバックし、バックアップを埩元するこずができたす。 オヌプン゜ヌスのデヌタベヌス移行ツヌルずしお、圓瀟では Flyway などの゜リュヌションを䜿甚しおいたす。Flywayは、コンフィギュレヌションよりもシンプルさず芏則性を重芖しおいたす。基本のコマンドは7぀ありたすMigrate、Clean、Info、Validate、Undo、Baseline、Repair 以䞋に、スクリプトを䜿甚しおデヌタベヌスを手動でバックアップする方法に぀いお、いく぀かの抂念ず簡略化した手順を瀺したす。 抂芁 クヌポンシステムは、KINTO のサヌビスや提携先のサヌビスで利甚できるクヌポンを簡単に発行・管理できるツヌルです。クヌポンシステムでは、新しい機胜を継続的に開発するこずで改善やアップグレヌドを行っおいたす倉曎が発生するたびに、クヌポンシステムで䜿甚するデヌタベヌスを管理する必芁がありたす。これは゜フトりェアプロゞェクトにおいお非垞に重芁な䜜業です。私たちの堎合は MySQL を䜿甚しおいたす。 クヌポンシステムの新しいリリヌスがある堎合は、毎回次の手順を螏んでいたす 機胜を開発する。 ロヌカルでテストしおから AWS テスト環境でテストを行う。 リリヌス前に DB のバックアップを取る。 新機胜をリリヌスする。 問題があれば、リリヌス前のバヌゞョンにロヌルバックする。 これらを実斜するため、バックアップずロヌルバックのスクリプトを甚意し、CLI でのむンストラクション数を枛らしおいたす。これで時間の節玄にもなりたすし、バックアップやロヌルバックで構造の䞀貫性も維持できたす。 基本を知る デヌタベヌスのバックアップずは デヌタベヌスのバックアップずは、サヌバヌに保存したデヌタのコピヌのこずです。 デヌタベヌスのバックアップは䜕のため バックアップを取るのは、予期せぬデヌタ損倱を防ぐためです。 障害が発生した堎合、元デヌタが倱われたり砎損したりしおも、バックアップがあれば簡単にデヌタを埩元するこずができたす。 デヌタベヌスのバックアップにはどんなタむプがあるの 物理バックアップ ^1 物理バックアップは、物理的なファむルのバックアップで、デヌタベヌスの保存ず埩元に䜿甚されたす。これらには、様々なデヌタファむル、コントロヌルファむル、アヌカむブ REDO ログなどが含たれたす。通垞、物理バックアップのデヌタは、クラりド、オフラむンストレヌゞ、磁気テヌプ、ディスクに保存されたす。 物理バックアップには方法が2぀ありたす オペレヌティング・システム・ナヌティリティ リカバリマネヌゞャヌ メリット デヌタの完党管理。 保管コストが䜎い。 バックアップデヌタの迅速な取埗。 デメリット どんなデバむスに保存しおもデヌタは砎損する可胜性があり、デヌタ埩旧が困難になるこずがある。 自然灜害でデヌタが砎壊される可胜性がある。 蚘憶装眮自䜓の玛倱。 論理バックアップ ^2 論理バックアップには、デヌタベヌスから取埗した論理デヌタが含たれたす。ビュヌ、プロシヌゞャ、ファンクション、テヌブルなどです。 これは、ナヌザヌがデヌタベヌスのコピヌを埩元したり、別の堎所に転送したりする堎合に䟿利です。 論理バックアップは、デヌタ損倱の防止では物理バックアップほど安党ではありたせん。構造の詳现を提䟛するだけです。そのため毎週、完党な論理バックアップを実行しなければなりたせん。 論理バックアップは物理バックアップの補助ずしお䜿甚されたす。 メリット デヌタベヌス党䜓を以前のむンスタンスに埩元する必芁がある堎合に䟿利。 より耇雑で、现かなリカバリ機胜を備えおいる。 デメリット 特別なコンポヌネントのリカバリには利甚できない可胜性がある。 物理バックアップに比べお安党性が䜎い。 構造の詳现を提䟛するのみ 論理デヌタベヌスのバックアップに぀いおロヌカル及び AWS CLI の䞡方で芋おいきたす。DB でのデヌタ操䜜は、開発者の芳点でも重芁なステップだからです。 AWS CLI を䜿甚しお Amazon RDSリレヌショナルデヌタベヌスサヌビスを管理する Amazon RDS [^3] [^3]: https://aws.amazon.com/rds/ Amazon RDS はサヌバヌを甚意するこずなく、クラりド䞊の RDB を安党に利甚できるサヌビスです。Amazon RDSは、オヌプン゜ヌスで広く䜿われおいるMySQLやMariaDB, PostgreSQLをはじめ、Oracle Database, microsoft SQL serverなどもサポヌトしおいたす。支払いは䜿った分だけです。 Amazon CLI [^4] [^4]: https://aws.amazon.com/cli/ AWS CLI は、AWS サヌビスを管理するための統合ツヌルで、Linux や macOS ではタヌミナルから、Windows ではコマンドプロンプトから実行したす。 基本的には専甚ツヌルからコマンド入力で実行したすが、スクリプトに蚘述するこずで凊理の自動化もできたす。 AWS CLI から Amazon RDS を管理する堎合は、コマンドを実行しおもすぐ反映されるずは限らない点に泚意が必芁です。 ずいうのも、Amazon RDS には耇数の障害察策が斜されおおり、蚭定倉曎がすべおの察策に反映されるたでに時間がかかるからです。 同様に簡単なスクリプトを各皮環境で曞くこずで、バックアップずロヌルバックのタスクを実行するこずができるでしょう。 開発者レベルで CLI から DB のバックアップやロヌルバックを行うにはどうすればいい SQL フォヌマットで mysqldump の䜿甚 mysqldump ずは [^5] [^5]: https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html mysqldump クラむアントは、 Igor Romanenko が最初に曞いた論理バックアッププログラムです。デヌタベヌスは通垞、バックアップや別のデヌタベヌスサヌバヌMariaDB や MySQL ずは限りたせんに転送するための SQL ステヌトメントのリスト「SQL ダンプ」の圢をしおいたす。ダンプには通垞、テヌブル䜜成やテヌブル入力を行うための SQL ステヌトメントが含たれおいたす。 ダンプファむルの䜿甚 ダンプファむル [^6] ずは [^6]: https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html ダンプファむルは、リリヌス埌のアップグレヌドの際にも䟿利です。アップグレヌドの際に、叀いリリヌスを䜿甚しおいるデヌタベヌスをダンプし、新しいリリヌスでロヌドするこずができたす。 ハむラむト デヌタありの状態぀たり DDL 及び DML の䞡方で DB ダンプを取埗する堎合 mysqldump -u root -p DB_Name > backup.sql # AWS CLI mysqldump -u $user -p$password -h $rds_endpoint > backup.dump # To avoid warnings like below you can use the following options and add the login credentials in a CNF file. # mysqldump: [Warning] Using a password on the command line interface can be insecure. # --set-gtid-purged=OFF # Warning:A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database.If you don't want to restore GTIDs, pass --set-gtid-purged=OFF.To make a complete dump, pass --all-databases --triggers --routines --events. # --defaults-extra-file=path/to/extra.cnf # cat << EOF > path/to/extra.cnf # [client] # user=${MYSQL_USER} # password=${MYSQL_PASSWORD} # host=${RDS_ENDPOINT} # EOF mysqldump --defaults-extra-file=path/to/extra.cnf --skip-column-statistics --single-transaction --set-gtid-purged=OFF --databases $DB > backup.dump デヌタなし぀たり DDL のみで DB ダンプを取る堎合 mysqldump -d -u root -p DB_Name > backup.sql # AWS CLI mysqldump -d -u $user -p$password -h $rds_endpoint > backup.dump # Below are some useful options to consider # --no-data, -d # Do not write any table row information (that is, do not dump table contents).This is useful if you want to dump only the CREATE TABLE statement for the table.For example, when you want to create an empty copy of the table by loading the dump file. # --defaults-extra-file=file_name # Read this option file after the global option file but (on Unix) before the user option file.If the file does not exist or is otherwise inaccessible, an error occurs.If file_name is not an absolute path name, it is interpreted relative to the current directory. # The --single-transaction option and the --lock-tables option are mutually exclusive because LOCK TABLES causes any pending transactions to be committed implicitly. mysqldump --no-data --defaults-extra-file=path/to/extra.cnf --skip-column-statistics --single-transaction --set-gtid-purged=OFF --databases $DB > backup.dump 以前のバヌゞョンにロヌルバックするには mysql -u root -p DB_Name < backup.dump # AWS CLI mysql -u $user -p$password -h $rds_endpoint < backup.dump バックアップ甚スクリプト ディレクトリを䜿甚する前にスクリプトを線集する必芁があるもの pathToParameterStoreKeyValueMYSQL_USER pathToParameterStoreKeyValueMYSQL_PASSWORD pathToParameterStoreKeyValueRDS_ENDPOINT DB_Name ######################################################################### ######################################################################### ##### ##### Description:Shell Script to take backup of existing data AWS ##### 1.Choose the env and switch the db connection ##### 2.Create backup directory with today's date ##### 3.Create dump file to backup folder with current db ##### 4.Check dump file size ##### ######################################################################### ######################################################################### read -p "Enter Your Env(env): " x echo "Welcome to ${x} Env!" # MySQL server credentials MYSQL_USER=$(aws ssm get-parameter --with-decryption --name /${x}/pathToParameterStoreKeyValueMYSQL_USER | jq -r .Parameter.Value) MYSQL_PASSWORD=$(aws ssm get-parameter --with-decryption --name /${x}/pathToParameterStoreKeyValueMYSQL_PASSWORD | jq -r .Parameter.Value) RDS_ENDPOINT=$(aws ssm get-parameter --with-decryption --name /${x}/pathToParameterStoreKeyValueRDS_ENDPOINT | jq -r .Parameter.Value) # Create a configuration file to maintain MySQL login details cat << EOF > mysql-dbaccess.cnf [client] user=$MYSQL_USER password=$MYSQL_PASSWORD host=$RDS_ENDPOINT EOF # Set the folder name with date format (example:2022-08-15) DATE_FORMAT=$(date +"%Y-%m-%d") TIMESTAMP=$(date +%H%M%s) # Path to local backup directory BACKUP_DIR="tmp/release/backup/${x}/dbbackup/${DATE_FORMAT}" # Use database's names DB="DB_Name" echo "########################################DATABASE########################################" echo "Using Database (DB_Name)" echo "########################################DATABASE########################################" # Create backup directory with today's date mkdir -p ${BACKUP_DIR} FILENAME_PREFIX="backup_${x}_DDL_DML_${TIMESTAMP}_" FILENAME_POSTFIX=".dump" read -p "Enter version eg: v0.0.1: " d FILENAME=$FILENAME_PREFIX${d}$FILENAME_POSTFIX echo "########################################FILEPATH########################################" echo "Created directory" ${BACKUP_DIR} echo "File will be saved as ${FILENAME} " mysqldump --defaults-extra-file=mysql-dbaccess.cnf --single-transaction --set-gtid-purged=OFF --databases $DB > ${BACKUP_DIR}/${FILENAME} echo "File saved at ${BACKUP_DIR}/${FILENAME}" echo "########################################FILESPATH########################################" # check File size file=${BACKUP_DIR}/${FILENAME} filesize=$(ls -lh $file ) echo "########################################FILESIZE########################################" echo "$file has a size of $filesize" echo "########################################FILESIZE########################################" # Remove the file after executing shell rm mysql-dbaccess.cnf バックアップの手順 AWS CLI にシェルスクリプトを配眮する AWS にログむン AWSマネゞメントコン゜ヌル → AWSシステムマネヌゞャヌ→ セッションマネヌゞャヌ →セッション開始の順にクリックする バックアップを取りたい env を入力する 䟋 {env}-{project_name}-{maintenance_server_name} セッション開始 dbbackupDDL_DML.sh ファむルが存圚するかチェックする ファむルが存圚しない堎合は、AWS CLI に dbbackupDDL_DML.sh ファむルを配眮する ファむルを実行する sh-4.2$ ls dbbackupDDL_DML.sh mysql.sh tmp sh-4.2$ sh dbbackupDDL_DML.sh Enter Your Env(env): env Welcome to env Env! ########################################DATABASE######################################## Using Database (db_name) ########################################DATABASE######################################## Enter version eg: v0.0.1: v0.0.1 ########################################FILEPATH######################################## Created directory tmp/release/backup/env/dbbackup/2022-08-12 File will be saved as backup_env_DDL_DML_06311660285870_v0.0.1.dump File saved at tmp/release/backup/env/dbbackup/2022-08-12/backup_env_DDL_DML_06311660285870_v0.0.1.dump ########################################FILESPATH######################################## #######################################FILESIZE######################################## tmp/release/backup/env/dbbackup/2022-08-12/backup_env_DDL_DML_06311660285870_v0.0.1.dump has a size of -rw-r--r-- 1 ssm-user ssm-user 1.7M Aug 12 06:31 tmp/release/backup/env/dbbackup/2022-08-12/backup_env_DDL_DML_06311660285870_v0.0.1.dump ########################################FILESIZE######################################## sh-4.2$ ダンプファむルの内容を確認するには sh-4.2$ less tmp/release/backup/env/dbbackup/2022-08-12/backup_env_DDL_DML_06311660285870_v0.0.1.dump sh-4.2$ バックアップは tmp/release/backup/env/dbbackup/{currentDate}/{FileNameWithTimestamp&Version} のフォルダに入りたす。 同じ日に耇数回、同䞀フォルダぞダンプしたい堎合、タむムスタンプ付きのファむルを準備したす。 sh-4.2$ cd tmp/release/backup/env/dbbackup/ sh-4.2$ ls 2022-08-09 2022-08-10 2022-08-12 sh-4.2$ cd tmp/release/backup/env/dbbackup/2022-08-12/ sh-4.2$ ls backup_env_DDL_DML_06311660285870_v0.0.1.dump backup_env_DDL_DML_06371660286257_v0.0.1.dump sh-4.2$ ロヌルバック甚スクリプト ディレクトリを䜿甚する前にスクリプトを線集する必芁があるもの pathToParameterStoreKeyValueMYSQL_USER pathToParameterStoreKeyValueMYSQL_PASSWORD pathToParameterStoreKeyValueRDS_ENDPOINT DB_Name ######################################################################### ######################################################################### ##### ##### Description:Shell Script to rollback to target SQL ##### 1.Choose the env and switch the db connection ##### 2.Create rollback directory with today's date ##### 3.Choose and input the backup file ##### 4.Input the version of dump file ##### 5.Copy backup dump file to ROLLBACK folder ##### 6.Create dump file to ROLLBACK folder with current db ##### 7.Rollback db with backup dump file ##### 8.Comparison.... ##### ######################################################################### ######################################################################### read -p "Enter Your Env(env): " x echo "Welcome to ${x} Env!" # MySQL server credentials MYSQL_USER=$(aws ssm get-parameter --with-decryption --name /${x}/pathToParameterStoreKeyValueMYSQL_USER | jq -r .Parameter.Value) MYSQL_PASSWORD=$(aws ssm get-parameter --with-decryption --name /${x}/pathToParameterStoreKeyValueMYSQL_PASSWORD | jq -r .Parameter.Value) RDS_ENDPOINT=$(aws ssm get-parameter --with-decryption --name /${x}/pathToParameterStoreKeyValueRDS_ENDPOINT | jq -r .Parameter.Value) # Set the folder name with date format(eg:2022-08-15) DATE_FORMAT=$(date +"%Y-%m-%d") TIMESTAMP=$(date +%H%M%s) # Path to local rollback directory history ROLLBACK_DIR="tmp/release/rollback/${x}/dbRollback/${DATE_FORMAT}" # Use database's names DB="DB_Name" echo "########################################DATABASE########################################" echo "Using Database (DB_Name)" echo "########################################DATABASE########################################" # Create rollback directory with today's date mkdir -p ${ROLLBACK_DIR} read -p "Enter full dumpFile Path to which you want to rollback: " df echo "dumpFile ${df} selected!" FILENAME_ROLLBACK_PREFIX="rollback_${x}_DDL_DML_${TIMESTAMP}_" FILENAME_BACKUP_PREFIX="backup_${x}_DDL_DML_${TIMESTAMP}_" FILENAME_POSTFIX=".dump" read -p "Enter version eg: v0.0.1: " d FILENAME_ROLLBACK=FILENAME_ROLLBACK_PREFIX${d}$FILENAME_POSTFIX FILENAME_BACKUP=FILENAME_BACKUP_PREFIX${d}$FILENAME_POSTFIX echo "########################################FILEPATH########################################" echo "Created directory" ${ROLLBACK_DIR} # copy dump file to backup folder cp ${df} ${ROLLBACK_DIR}/${FILENAME_ROLLBACK} ROLLBACK_FILE=${ROLLBACK_DIR}/${FILENAME_ROLLBACK} BEFORE_ROLLBACK_DUMP=${ROLLBACK_DIR}/"BeforeRollback_${FILENAME_BACKUP}" AFTER_ROLLBACK_DUMP=${ROLLBACK_DIR}/"AfterRollback_${FILENAME_BACKUP}" mysqldump -u $MYSQL_USER -p$MYSQL_PASSWORD -h $RDS_ENDPOINT --databases $DB > ${BEFORE_ROLLBACK_DUMP} echo "Dump Before Rollback ${BEFORE_ROLLBACK_DUMP}" echo "Rollback to DDL_DML of sql file located at ${ROLLBACK_FILE} " mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -h $RDS_ENDPOINT --databases $DB < ${ROLLBACK_FILE} echo "Rollback successfully done with ${ROLLBACK_FILE}" mysqldump -u $MYSQL_USER -p$MYSQL_PASSWORD -h $RDS_ENDPOINT --databases $DB > ${AFTER_ROLLBACK_DUMP} echo "Dump After Rollback ${AFTER_ROLLBACK_DUMP}" echo "########################################FILESPATH########################################" # check File size before Rollback fileBeforeRollback=${ROLLBACK_DIR}/${BEFORE_ROLLBACK_DUMP} filesizeBeforeRollback=$(ls -lh fileBeforeRollback ) echo "########################################FILESIZE BEFORE ROLLBACK########################################" echo "$fileBeforeRollback has a size of $filesizeBeforeRollback" echo "########################################FILESIZE BEFORE ROLLBACK########################################" # check File size after Rollback fileAfterRollback=${ROLLBACK_DIR}/${AFTER_ROLLBACK_DUMP} filesizeAfterRollback=$(ls -lh fileAfterRollback ) echo "########################################FILESIZE AFTER ROLLBACK########################################" echo "$fileAfterRollback has a size of $filesizeAfterRollback" echo "########################################FILESIZE AFTER ROLLBACK########################################" Footer ロヌルバックの手順 AWS CLI にシェルスクリプトを配眮する AWS にログむン AWSマネゞメントコン゜ヌル → AWSシステムマネヌゞャヌ→ セッションマネヌゞャヌ →セッション開始の順にクリックする ロヌルバックしたい env を入力する 䟋 {env}-{project_name}-{maintenance_server_name} セッション開始 dbRollbackDDL_DML.sh ファむルが存圚するかチェックする ファむルが存圚しない堎合は、AWS CLI に dbRollbackDDL_DML.sh ファむルを配眮する ファむルを実行する sh-4.2$ ls dbRollbackDDL_DML.sh mysql.sh tmp sh-4.2$ sh dbRollbackDDL_DML.sh Enter Your Env: env Welcome to env Env! ########################################DATABASE######################################## Using Database (DB_Name) ########################################DATABASE######################################## Enter full dumpFile Path to which you want to rollback: tmp/release/backup/env/dbbackup/2022-08-12 Enter version eg: v0.0.1: v0.0.1 ########################################FILEPATH######################################## Created directory tmp/release/rollback/env/dbRollback/2022-08-13 Dump Before Rollback tmp/release/rollback/env/dbRollback/2022-08-13/BeforeRollback_backup_env_DDL_DML_06311660285870_2022-08-13.dump Rollback to DDL_DML of sql file located at tmp/release/rollback/env/dbRollback/2022-08-13/backup_env_DDL_DML_06311660285870_2022-08-13.dump Rollback successfully done with tmp/release/rollback/env/dbRollback/2022-08-13/backup_env_DDL_DML_06311660285870_2022-08-13.dump Dump After Rollback tmp/release/rollback/env/dbRollback/2022-08-13/AfterRollback_backup_env_DDL_DML_063116602859099_2022-08-13.dump ########################################FILESPATH######################################## ########################################FILESIZE BEFORE ROLLBACK######################################## tmp/release/rollback/env/dbRollback/2022-08-13/BeforeRollback_backup_env_DDL_DML_06311660285870_2022-08-13.dump has a size of -rw-r--r-- 1 ssm-user ssm-user 1.7M Aug 13 06:31 tmp/release/rollback/env/dbRollback/2022-08-13/BeforeRollback_backup_env_DDL_DML_06311660285870_2022-08-13.dump ########################################FILESIZE BEFORE ROLLBACK######################################## ########################################FILESIZE AFTER ROLLBACK######################################## tmp/release/rollback/env/dbRollback/2022-08-13/AfterRollback_backup_env_DDL_DML_063116602859099_2022-08-13.dump has a size of -rw-r--r-- 1 ssm-user ssm-user 1.6M Aug 13 06:31 tmp/release/rollback/env/dbRollback/2022-08-13/AfterRollback_backup_env_DDL_DML_063116602859099_2022-08-13.dump ########################################FILESIZE AFTER ROLLBACK######################################## sh-4.2$ 普段の業務でどう掻かすか 䞊蚘のようなスクリプトやコマンドを䜿甚するこずで、入力やログむンの手間を枛らし、たた倚くのドキュメントを䜕床も参照する必芁がなくなりたす。これにより、迅速なバックアップの取埗が可胜になりたす。 コマンドを手入力する際の時間ず゚ラヌを削枛できたす。 必芁なずきにい぀でも参照できる、䜓系的で敎ったフォルダ構造が提䟛されたす。 DB のアップグレヌドの際にデヌタの䞍敎合が発生した堎合や、次のバヌゞョンのシステムをリリヌスする必芁がある堎合、障害が発生しデヌタをロヌルバックする必芁がある堎合など、これらの手順が必芁になりたす。
あなたのプロダクトマネヌゞャヌずしおの「説明」を考えよう -- 曞評:プロダクトマネヌゞャヌのしごず第2版 自己玹介 Woven Payment Solution開発Gの亀井です。 我々のチヌムの仕事を䞀蚀でいえば「Woven Cityにおける決枈システムの開発」になりたす。 私はWoven by Toyotaずいうトペタグルヌプの別䌚瀟に出向しおおり、普段はそちらで掻動しおいたす。 Woven by Toyotaはいく぀か事業を持っおいるのですが、Woven City開発はそのうちのひず぀です。 この蚘事はプロダクトマネヌゞャヌ発売蚘念プレれントに応募した際の、曞評を曞いお公開するずいうお玄束に察する回答でもありたす。 https://www.attractor.co.jp/news/product-management-in-practice/ PdMになったきっかけ 実は私はプロダクトマネヌゞャヌ(Pdm)ではありたせん。珟時点でもPdMずいう肩曞きはもっおいたせん。自称PdMです。 もずもずはバック゚ンド䞭心の゜フトりェア゚ンゞニアで、求めに応じおフロント゚ンドも曞いたりするナヌティリティプレむダヌでした。 コヌド決枈システムの経隓もあり、それが今の仕事にも぀ながっおいたす。 その埌゚ンゞニアリングマネヌゞャヌ(EM)もやっおきたので、評䟡ずか組織ずか採甚ずかそういった仕事もできたす。 ですが、このプロゞェクトのために出向するにあたっお私に期埅されおいる圹割は技術寄りのPdMみたいなものず蚀われたした。 今になっお思えば、この時もう少し具䜓的に期埅倀を聞いおおくべきでしたが、おそらく誰も明確な答えは持っおいなかったでしょう。 自分自身でもよくわからないなあず思いながら、技術遞定を行い最初のプロトタむプを構築し、採甚掻動をしおメンバヌを増やしず リヌド゚ンゞニアずEMを混ぜたようなこずをやっおいたした。 䞀方で他のチヌムの人から質問が来るこずも倚く、それに察しお資料を甚意したり察面で䌚議(トペタ甚語で面着ずいいたす)をしたりず説明するこずにも倚くの時間を割いおいたした。 それでも自分で手を動かすずいうこずは続けおいたのですが、メンバヌが増えおくるず明確に私が䜜業のブロッカヌになりはじめたした。 そこでメンバヌずも話し合い、決枈に぀いお知芋のある自分が䜜るべき機胜を説明しお、それを他のメンバヌが䜜るずいう圹割分担のほうが生産性があがるだろうずいうこずになり、手を動かさないこずを決断したした。 この時から自分自身でも、自分はPdMであるずいう自己芏定ができるようになったず思いたす。これがだいたい䞀幎ほど前ぐらいのこずです。 手を動かすのを止めるずいう決断に぀いおは、以前EMをやったずきも䌌たような刀断をしおいたので、そこに察する葛藀はありたせんでした。 たた機䌚があれば自分で手を動かす日もくるでしょう。 この本に興味を持ったきっかけ PdMずいう自芚を埗たのはよいのですが、具䜓的にPdMっお䜕するんだっけずいうこずに぀いお確信が持おずにいたした。 目先でやるこずはあるので、䜕もしないずいうこずは無くなにかしら出来䞊がっおはいくのですが、自分自身がどんな成果を出しおいるのか説明しきれないずいうもやもやがありたした。 プロダクトマネヌゞャヌに぀いお曞かれた蚘事や本を乱読するもののいたいち腹萜ちはできず、消化䞍良が続きたした。 この本の第1版は読たなかったあたり、そこたで本気で調べおもいなかったずもいえたすが。 そんな折、この本の感想がチラチラ目に入るようになりたした。どれも評䟡が高く、サブタむトルの「1日目から䜿える実践ガむド」ずいうのも心に響いたのですが、そのうち買うかヌぐらいの気持ちでした。 完党に蚀い蚳ですが、その時みかけた感想はどれも珟圹バリバリのプロダクトマネヌゞャヌのもので、わかっおいる人に䌝わるタむプの本なのかなヌずいう疑念があったのです。 そんなずきプレれント䌁画を発芋し、ここたで気になっおいお応募しない手はないなず申し蟌んだのでした。 ここから曞評がはじたりたす 結論から曞くず、この本はずおもよい本です。私のようなPdMになりたおの人、PdMを目指す人だけでなく、これからPdMずいう圹割を導入したい組織にも圹立ちたす。 あるいは自分たちの組織にいる肩曞きのないPdMを発芋するのにも圹立ちたすし、自分たちの開発プロセスにプロダクトマネゞメントを導入するためにも読んだ方がよいです。 その意味ではこの本は0日目から䜿えるずも蚀えたす。 プロダクトマネゞメントずは この本の偉倧なずころはPdMずいう圹割は組織によっお異なり、䞖の䞭の組織が倚様であるのず同様に、あるいは䞖の䞭の組織が立ち向かう問題が倚様であるのず同様に、PdMに求められる圹割も倚様であるずいうこずを認めおいるずころです。 ですがそれだずPdMずいう圹割は存圚しないずいうこずになっおしたいたす。この本ではPdMのあるいはプロダクトマネゞメントの定矩を断念しおいたす。 その代わりに 説明 によっおその茪郭を描こうずしおいたす。優れた 説明 の䟋ずしお別の本『 プロダクトマネゞメント ―ビルドトラップを避け顧客に䟡倀を届ける 』から匕くかたちで、『ビゞネスず顧客のあいだの䟡倀亀換の管理人』をあげおいたすが、PdMやそれを必芁ずする組織はこれや他の 説明 を元に自分たちの組織にあった 説明 を構築する必芁があるでしょう。 これは本には曞かれおいたせんが、それぞれの考える 説明 が互いにマッチするかどうかずいうのは、PdMを採甚したり内郚から登甚にするにあたっお重芁なポむントになるのだず思いたす。 もちろんこれは他の職皮にも蚀えるこずです。ただPdMずいう圹割は他の職皮より抜象的であるだけ 説明 の重芁床が倧きくなるず考えたす。 あるPdMがどんな経歎だったずしおも、 説明 にミスマッチがある組織では掻躍できないでしょう。 COREスキル ではそのような抜象的なPdMずいう圹割にどのようなスキルが必芁なのかに぀いお、この筆者は次の4぀の胜力をあげおいたす。 Communicate (コミュニケヌション) Organize (組織化) Research (リサヌチ) Execute (実行) そしお、この4぀の胜力の頭文字をずっお COREスキル ず名付けおいたす。 この本のほずんどはこのCOREスキルをどのように発揮するかに぀いお曞かれおいたす。 ずいっおも、䟋えば「Communicateの章」みたいなものがあるわけではありたせん。 開発を行う䞊でのあるあるネタに察しお、こんな感じにCOREスキルを発揮できるずいいんじゃないみたいな 説明 がされるずいうのがこの本の構成です。 焊点をコミュニケヌションに圓おたり、組織䜜りに圓おたりず章によっおテヌマはあるのですが、発揮すべきCOREスキルは混然ずしお描かれたす。 ずころで自分の問題は解消されたのか 自分の肩曞きはずもかくずしお、やっおいるこずの半分ぐらいはPdMず蚀えるなずいう実感を持おおいたす。それだけでもこの本を読んだ䟡倀はありたした。 チヌムに自分以倖のPdMを入れるずしたら、こういうこずをやっおほしいずいう 説明 を䜜るこずができたら、より 組織化(Organize) 出来そうなので、挑戊しおみおもよいかもしれたせん。 䞀方でもし自分が本気で今埌もPdMを続けおいく、目指すずいうのであれば自分流のPdMの 説明 をCOREスキルを絡めお構築するずよさそうなのですが、自分の䞭にはただその芚悟はありたせん。 おわりに 改めおこの本はPdMずいう圹割に぀いお考える䞊でずおもよい導き手ずなっおくれる良い本です。 PdMの人もそうでない人も、PdMがあるいはプロダクトマネゞメントが自分たち組織にどのように関わっおいるのか、 説明 を構築するよい機䌚を䞎えおくれるず思いたす。 この本ずいうプロダクトを届けおくださった、著者の Matt LeMay 様、蚳者のみなさた、O'Reilly 瀟様、本をプレれントいただいた株匏䌚瀟アトラクタ様ありがずうございたした。
はじめに KINTOテクノロゞヌズの新車サブスクグルヌプに所属しおいる森本です。バック゚ンド゚ンゞニアずしお日々開発しおいたす。 2022幎床のアドベントカレンダヌでは、瀟内の若手メンバヌでGraphQLの勉匷䌚を実斜したこずに぀いお曞きたした。 今回は、入瀟した2021幎8月から2023幎8月のリリヌスたでの2幎間携わった、サブスクサむト(KINTO ONE)のリニュヌアルに぀いお蚘茉したす。その䞭でも、入瀟しお初めおの仕事であるテヌブル蚭蚈の芋盎しに぀いお蚘茉したす。 テヌブル蚭蚈で盛り蟌んだこず 以䞋の衚はリニュヌアルする前埌のテヌブルのむメヌゞです。実際に業務で䜿甚しおいるテヌブルではありたせん。 このテヌブルは瀟員情報を栌玍するもので、曎新があった堎合はそのレコヌドを論理削陀し、新しいレコヌドを远加するこずで履歎管理できるようになっおいたす。 ※レコヌドを削陀せず、フラグを立おるこずで削陀扱いにするこずを論理削陀ず呌びたす。倧切な倀の曎新履歎を远うこずができるずいうメリットがありたす。 リニュヌアル前 id employee_id mail_address pref group_and_role delete_flag 1 E-001 email1@XX.XX 23 HR_Manager false 2 E-002 email2@XX.XX 25 HR_Staff true 3 E-002 email2@XX.XX 14 Development_Manager false 4 E-003 email3@XX.XX 1 Development_Staff false リニュヌアル埌 id employee_id mail_address prefecture group staff is_deleted 1 E-001 email1@XX.XX AICHI HR Manager false 2 E-002 email2@XX.XX SHIGA HR Staff true 3 E-002 email2@XX.XX KANAGAWA Development Manager false 4 E-003 email3@XX.XX HOKKAIDAO Development Staff false 各カラムは以䞋の情報を衚したす。 id 瀟員テヌブルでレコヌドを䞀意に特定するID employee_id 瀟員を䞀意に特定するID mail_address メヌルアドレス pref / prefecture 郜道府県 group_and_role / group ・ role 所属グルヌプずロヌル delete_flag / is_deleted そのレコヌドが削陀されおいるかどうか 4぀の芋盎しポむント カラムに略称を䜿甚しない 倀を数字に眮き換えない 1぀のカラムに耇数の意味をもたせない フラグ系のカラムは _flag ず呜名しない 1. カラムに略称を䜿甚しない カラム名 pref のように、カラム名を省略しないようにしたした。 これが郜道府県を衚すこずは䜕ずなく理解できるでしょう。 しかし、これをドキュメントや゜ヌスコヌドで䜿甚する堎合、 pref や prf などの衚蚘揺れが発生する可胜性が高くなりたす。たた、そもそも䜕の略称かわからなくなっおしたう堎合もありたす。 そのため略称は䜿甚せず、長くおも prefecture のように衚蚘するようにしたした。 . 倀を数字に眮き換えない リニュヌアル前のテヌブルを芋るず、 pref の倀ずしお23が入っおいたす。47あるうちの郜道府県のどこかを衚すず掚枬できたすが、23番目は䞀䜓どこなのでしょうか。 盎感的でないため倀が䜕を衚しおいるかが分かりたせん。倀を芋るたびに数字ず郜道府県の組み合わせを参照する必芁があり、可読性が䞋がりたす。たた誀りに気づきにくくなりたす。そのため AICHI のように、郜道府県をそのたた栌玍するようにしたした。 そしお䞍正な倀が栌玍されおいる堎合は、プログラムで読み蟌み時に゚ラヌになるので気づくこずができるずいうメリットもありたす。 蚀語はJava、O/RマッパヌはJPAを䜿甚する堎合を䟋ずしお挙げたす。 prefecture のenumクラスを以䞋のように定矩し、User゚ンティティではその型を䜿甚するこずで AICHIA のような䞍正な倀があれば゚ラヌになり、気づくこずができるずいうメリットもありたす。 public enum Prefecture { HOKKAIDO("北海道"), . . . AICHI("愛知県"), . . . OKINAWA("沖瞄県"); private String value; } @Entity public class Employee { /** ID */ @Id private Long id; . . . /** 郜道府県 */ @Enumerated(EnumType.STRING) @Column private Prefecture prefecture; . . . } マッピングできない堎合に、以䞋のようなExceptionが発生したす。 java.lang.IllegalArgumentException: No enum constant com.example.demo.values.Prefecture.AICHIA 3. 1぀のカラムに耇数の意味をもたせない リニュヌアル前の group_and_role ようなカラムは、1぀のカラムに所属グルヌプずロヌルの2぀の情報を持っおいたした。䞀芋するず問題ないように芋えたすが、倀を远加・削陀・倉曎する堎合の柔軟性が䞋がりたす。 元々以䞋のような4぀の定矩があった堎合を想定したす。 HR_Manager HR_Staff Development_Manager Development_Staff 仮に Development グルヌプの名称を NewDevelopment ぞ倉曎しようずなった堎合、曎新SQLの条件が耇雑になりたす。 HR_Manager HR_Staff Development_Manager → NewDevelopment_Manager Development_Staff → NewDevelopment_Staff たた怜玢や゜ヌトをする芳点でも問題がありたす。怜玢のク゚リが耇雑になったり、゜ヌトをする堎合も_アンダヌスコア以降で区切るずいう手間が必芁になっおきたす。もちろん、可読性も䞋がりたす。 そのためサむトリニュヌアルする際には、1぀のカラムは1぀の意味を持たせるように分離する䜜業を行いたした。 4. フラグ系のカラムは _flag ず呜名しない delete_flag は削陀したこずを衚すカラムだず理解できたす。しかしtrueは削陀枈を瀺しおいるかどうか迷っおしたいたす。 そのため is_deleted のようにbe動詞+過去分詞の圢匏にしたした。そうするこずでtrueは削陀されたこず、falseは削陀されおいないこずを理解できたす。 ここで倧切なこずは、カラム名ず䞭身の倀の認識に盞違がないこずです。 䟋えば is_deleted は、瀟員情報に曎新があった堎合に叀いレコヌドを論理削陀するためのカラムずなりたす。 true削陀枈み false未削陀 フラグ系のカラムでtrueかfalse以倖の第の状態が出おきた堎合は、フラグ系のカラムから倉曎すべきです。 改善し続ける テヌブル蚭蚈は1回だけではなく、リリヌスする数ヶ月前たで継続しお行いたした。 さたざたな皮類のテストが行われる䞭、テヌブルを倉曎するこずは倧きな圱響を持ちたす。開発チヌム内の修正だけでなく、堎合によっおはバック゚ンド・フロント゚ンドを結合したテストを再実斜しなければなりたせん。 バック゚ンドのプログラムずテヌブル間だけで修正を完結するこずもできたしたが、リニュヌアルするにあたっおはAPIのむンタヌフェヌスたでも䞀貫しお綺麗にしたいず考え、APIを利甚する各チヌムず連携しお足䞊みを揃えお修正したした。 プロゞェクト党䜓で、目先の倧倉さより、リニュヌアルする目的を意識しおいたこずが共通認識にあったず思いたす。 たたバック゚ンドチヌム内で改善事項を積極的に䌝え合える雰囲気もありたした。テヌブル蚭蚈だけではなく、開発党䜓で改善し続けられたこずが、リニュヌアルプロゞェクトを成功に導くこずができた1぀の芁因だず考えおいたす。 さいごに 実際にはテヌブルの構成自䜓の倉曎や、䜿甚しおいないカラムの削陀など、倧きな構成倉曎をしたした。 これは入瀟しお初めお携わったタスクで、サブスクサむトの構成や機胜を100%理解できおいない状態で蚭蚈するこずずなりたした。開発途䞭で動䜜確認をしお氞続化できおいない倀に気づいたり、テストなどで指摘があっお初めお定矩が誀っおいるこずを知ったりするこずがありたした。 リリヌスの終わった今でさえ、 「なぜこのような呜名をしおしたったのか」 「ここのテヌブルは分離しおおくべきだったかも 」 ず思うこずが倚くありたす。 しかしながら、チヌムメンバヌをはじめプロゞェクト党䜓でテヌブル倉曎を快く受けれおくださった方々のおかげで無事リリヌスするこずができたした。 今埌も、わかりやすいテヌブルを匕き続き目指しお改善しおいきたす。
Hello I'm Koyama from the KINTO Technologies Mobile App Development Group. I work on mobile app development and maintenance as an iOS engineer. Today, I'd like to talk about how MVVM was adopted for Global KINTO's mobile app development. MVVM and Combine There are a few things I'd like to touch on briefly before I begin. MVVM MVVM is an architecture in software development. It consists of Model-View-ViewModel, which is derived from the MVC model. The details are a little complex, so a simple overview is as follows: Model The part that's responsible for collecting data and carrying out simple processing. It doesn't do any complicated processing. View The part responsible for rendering the screen. It receives the data needed to produce the screen, then simply draws it. ViewModel This part is in the middle between the Model and View, and is responsible for bringing together multiple pieces of Model data and holding values needed to maintain the View. That's the general idea (or at least my personal take on it). I found even this much of it difficult to understand when I first started working for iOS. So, if you apply this to iOS development, this is how it looks: Model Brings together all of the data that needs to be handled. Rather than using a dictionary-based approach, you might as well create a single Model instead. The Model only contains simple methods related to the data inside it. View This can be a ViewController or an individual View. It only contains code related to rendering, and simply displays the data it receives without manipulating it at all. Basically, the aim is to have no if statements. ViewModel Receives triggers from the ViewController and returns data. A ViewModel is in a one-to-one relationship with a ViewController, and in relation to an individual View, it can also take on the role of a higher-level ViewController's ViewModel, depending on the situation. This is what I'd like to achieve. In today's article, I particularly want to talk about the differences between a View and a ViewModel. Combine First launched in June 2019, Combine is a framework for creating Apple's official reactive architecture. Before then, reactive architectures were mostly achieved using the third-party RxSwift, but now, an official, strongly supported library has been released. "Hang on a moment. What is a reactive architecture anyway?" Some of you may be wondering this. (I certainly did.) Here's what Wikipedia has to say: reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. -- Wikipedia | Reactive programming Not very easy to understand, is it? I've heard that to easily understand this, you should picture it in terms of spreadsheet software. Suppose you enter a simple formula like this: A B C 10 20 =A1+B1 Once you've entered it, the result goes in cell C1 (of course). A B C 10 20 30 But what do you think will happen if you change the value in cell A1 to 20? A B C 20 20 40 Of course, cell C1 will change to 40. A change in cell A1 has spread to cell C1 without us directly modifying C1 at all. This is what's called reactive architecture. Based on this, I could now clearly see that you just declare the data processing ( =A1+B1 ) first, then run the actual data through it (assigning 20 to A1) at the end. Background The preamble got a bit long. This is why we decided to adopt Combine and MVVM. Back when I first started working on a Global KINTO development project, we'd just switched from using outsourced code to producing our own in-house. The codebase that had already been written were on a “spaghetti code” state, so it was extremely difficult to maintain. Global variables were being called all over the place, and there was no way to tell which class depended on which. Fortunately, we had a fairly small amount of code and screens, so we tried to solve the problem by reviewing the overall architecture. At the same time, the Mobile App Development Group had some knowledge of using Combine-based MVVM. So, we decided to proceed based on the MVVM architecture. The aim was to design things thoroughly based on the architecture so that even new team members could easily understand the projects and safely modify them. And now comes the implementation! Since we've decided to use MVVM, we'll separate the roles between the View and the ViewModel. This implementation uses UIkit. View - Part1 Instead of doing any processing in the View, we only want to tell the ViewModel the timing of event firings. To do this, we'll use Combine's Publisher. For example, if you need to send the timing of viewDidLoad, define the PassthroughSubject using the Void type. private let didLoad: PassthroughSubject<Void, Never> = .init() Make it so that this gets sent when viewDidLoad is called. override func viewDidLoad() { super.viewDidLoad() didLoad.send() } It's also a smart approach to use tapPublisher[^combineCocoa] when a button is tapped. First, connect the button to the Outlet and prepare the Publisher used for sending. If you want to pass a String value from the displayed screen when the button is pressed, define Publisher as String instead of Void. @IBOutlet weak var button: UIButton! @IBOutlet weak var textArea: UITextField! private let tapButton: PassthroughSubject<String, Never> = .init() Then, use tapPublisher to detect the event and send it to the ViewModel. button .tapPublisher .sink { [weak self] in self?.tapButton.send(textArea.text ?? "") } .store(in: &cancellables) Next, let's take a look at the ViewModel. ViewModel The ViewModel retrieves and generates information based on the event triggers received from the View, then returns the necessary information to the latter. Here, we'll create it using Combine's Operator and Subscriber. First, to prepare to connect it with the View side, define Input and Output structs separately from the ViewModel. Input is the data transferred from the View, and Output is the resulting data you want to pass from the ViewModel. When exchanging data, processing will be possible only if the data and error types have been properly set, so use the type AnyPublisher across the board. AnyPublisher<String, Never> // Want text when the button is tapped! } struct ViewModelOutput { let onShowWelcome: AnyPublisher<String, Never> // Want it to display the Welcome text on the screen let onShowText: AnyPublisher<String, Never> // Want it to display arbitrary text on the screen let onShowOnlyFirst screen: AnyPublisher <Void, Never> // Want it to display a fixed value on the screen only when the button is pressed for the first time } ``` Next, let's create the part that processes the data. This amounts to adding the part to receive input and turn it into output. For example, if you want viewDidLoad to trigger a specific API, connect viewDidLoad's Publisher to Operator and run an API request. ```swift func transform(input: ViewModelInput) -> ViewModelOutput { let apiResponse = input .viewDidLoad .flatMap { api.requestData() } Similarly, when a button is tapped, if you want to generate data based on the text on the screen at the time, use map. let text = input .tapButton .map { createText(text: $0) } You might also want something to happen when viewDidLoad is called and a button is tapped at the same time. In cases like that, Publishers can be connected to each other. There are many ways to connect them, but we'll use zip this time. let buttonTap = input .tapButton let didLoadAndButtonTap = didLoad .zip(buttonTap) .map { _ in } Operators are already available in Combine and its extended libraries, so complex processing can be achieved while still keeping the code simple. There are a lot of Operators, but I've listed the ones I think it's useful to remember below. map flatMap compactMap filter share materialize [^combineExt] merge zip combineLatest withLatestFrom [^combineExt] And finally, add the proper return that goes with the output's type. When you use Combine, the types will keep getting expanded each time an Operator is connected, so in the end, return the created data to View after gather it all together into AnyPublisher. return .init( onShowWelcome: apiResponse.eraseToAnyPublisher(), onShowText: text.eraseToAnyPublisher(), onShowOnlyFirst: didLoadAndButtonTap.eraseToAnyPublisher() ) } View - Part 2 The ViewModel side is now complete, so connect it to the View and render the screen. Let’s call the transform method we prepared earlier to get the results of the processing carried out in ViewModel. let output = viewModel.transform( input: .init( viewDidLoad: didLoad.eraseToAnyPublisher(), tapButton: tapButton.eraseToAnyPublisher() ) ) Once we've gotten the processing results and decided what sort of screen rendering to do for each, we're all done. output .onShowText .receive(on: DispatchQueue.main) .sink { [weak self] in self?.textArea.text = $0 } .store(in: &cancellables) output .onShowOnlyFirst .receive(on: DispatchQueue.main) .sink { [weak self] in self?.showCustomMessage("First!") } .store(in: &cancellables) ``` # Finished code Here's the finished code. ```swift:ViewController.swift class ViewController: UIViewController { @IBOutlet weak var button: UIButton! @IBOutlet weak var textArea: UITextField! private var viewModel: ViewModelProtocol! private let didLoad: PassthroughSubject<Void, Never> = .init() private let tapButton: PassthroughSubject<String, Never> = .init() private var cancellables: Set<AnyCancellable> = .init() func configure(viewModel: ViewModelProtocol) { self.viewModel = viewModel } override func viewDidLoad() { super.viewDidLoad() bind() didLoad.send() } func bind() { let output = viewModel.transform( input: .init( viewDidLoad: didLoad.eraseToAnyPublisher(), tapButton: tapButton.eraseToAnyPublisher() ) ) button .tapPublisher .sink { [weak self] in self?.tapButton.send(textArea.text ?? "") } .store(in: &cancellables) output .onShowWelcome .receive(on: DispatchQueue.main) .sink { [weak self] in self?.textArea.text = $0 } .store(in: &cancellables) output .onShowText .receive(on: DispatchQueue.main) .sink { [weak self] in self?.textArea.text = $0 } .store(in: &cancellables) output .onShowOnlyFirst .receive(on: DispatchQueue.main) .sink { [weak self] in self?.showCustomMessage("First!") // Assumptions for which methods are prepared in advance } .store(in: &cancellables) } } ``` ```swift:ViewModel.swift protocol ViewModelProtocol { func transform(input: ViewModelInput) -> ViewModelOutput } struct ViewModelInput { let viewDidLoad: AnyPublisher<Void, Never> let tapButton: AnyPublisher<String, Never> } struct ViewModelOutput { let onShowWelcome: AnyPublisher<String, Never> let onShowText: AnyPublisher<String, Never> let onShowOnlyFirst: AnyPublisher<Void, Never> } struct ViewModel: ViewModelProtocol { let api: SomeApiProtocol init(api: SomeApiProtocol) { self.api = api } func transform(input: ViewModelInput) -> ViewModelOutput { let didLoad = input .viewDidLoad share() let apiResponse = didLoad .flatMap { api.requestData() } // Future<String, Never> return is assumed let buttonTap = input .tapButton share() let text = buttonTap .map { createText(text: $0) } let didLoadAndButtonTap = didLoad .zip(buttonTap) .map { _ in } return .init( onShowWelcome: apiResponse.eraseToAnyPublisher(), onShowText: text.eraseToAnyPublisher(), onShowOnlyFirst: didLoadAndButtonTap.eraseToAnyPublisher() ) } func createText(text: String) -> String { "\(text) show!!" } } ``` Clearly dividing the roles between the View and ViewModel like this helps keep the code nice and organized. You can use the same structure for any View, which makes the code easier to read and maintain. Also, having the roles all set in stone makes forcible coding less likely. However, one con is that if you haven't done much reactive programming with (e.g.) Combine or RxSwift before, you'll find it **as difficult as to understand as a totally different language** from the Swift you've known up to then. In Global KINTO's iOS projects, all Views are created based on this structure. It's easy to read and maintain, making it less likely to deviate from even when creating new Views. # In conclusion The Mobile App Development Group will share knowledge like in this article with other products besides Global KINTO ones, and take on the challenge of new architectures that are completely different from this one. I want to keep rising to the challenge of using various iOS development methods as part of my work in the Mobile App Development Group. [^combineCocoa]: 拡匵ラむブラリの[CombineCocoa](https://github.com/CombineCommunity/CombineCocoa)を䜿甚しおいたす [^combineExt]: 拡匵ラむブラリの[CombineExt](https://github.com/CombineCommunity/CombineExt)を䜿甚しおいたす
はじめに こんにちは。プラットフォヌムGのPlatformEngneeringチヌムでPlatformEngineeringの考え方をベヌスにツヌル呚りの開発・運甚・展開の圹割(ずチヌムリヌダヌのようなこずをしおいる) 島村 です。 この蚘事は、 KINTOテクノロゞヌズのAdventCalendar2023 の技術偎1日目の蚘事です。 CICDツヌルずしお、GitHubに付属しおいるGitHub Actions。 特にPushず手動(WorkFlow_dispatch)をよく䜿うず思いたすが、これが有効になったり動いたりするのはどういう時なのか、たたに混乱したせんか 私はしたす。メンバヌずどうだっけず話をしたこずもよくありたす。 なので敎理しようずいうのが本蚘事です。 背景 PushしたずきずかMergeしたずきずか手動ずか、起動するEventsのうち、 on.push on.workflow_dispatch の際の挙動を敎理しおたずめたいず思いたす。 テスト準備 ケヌス on.push default(main)ブランチにMergeしなくおも動くか default(main)ブランチにMergeしたあず、Pushのブランチを倉曎するずどうか Pushの際に他のブランチに圱響がないか on.workflow_dispatch deafult(main)ブランチにMergeしなくおも動くか Merge埌に別ブランチを䜜成しお修正、Pushしたら反映されるか 基本コヌド(echo.yaml) name: "TestWorkFlow" on: push: branches: - main - 'test/**' workflow_dispatch: jobs: TestWorkflow: name: "TestWorkFLow Echo" runs-on: ubuntu-latest steps: - name: Echo Branch run: | echo "Branch${{ GITHUB_REF_NAME }}" 結果たずめ 䞀枚っぺらのむラストにたずめたのがこちら。 詳现 on.push Mergeしなくおも、以䞋の条件にマッチするならPushしたタむミングで動く 構文などのミスがないこず(ただ、構文ミスがあったずしおもFailで衚瀺される) pushしたブランチずworkflowのon.pushのブランチの条件が合臎しおいる on.push.branchesをtest/**のたたで"feature/trigger-test"でブランチを切っおpushしおも動かない on.push.branchesを"feature/xx"に倉曎しおpushしたら、feature/trigger-testのWorkflowが動く 以䞋の぀のブランチがある堎合の挙動 on.push.branchesを"feature/xx"ずしおいるtest/trigger-test on.push.branchesを"test/xx"ずしおいるfeature/another-trigger 䜕か修正しおtrigger-testでPushしおも、feature/another-triggerのWorkFlowは動かない 䜕か修正しおfeature/another-triggerでPushしおも、trigger-testのWorkFlowは動かない on系パラメヌタはその発生したブランチにあるファむルの内容を芋お起動するかを刀断しおいる on.workflow_dispatch defaultブランチにファむルが存圚しないず、手動で動かすボタンは衚瀺されない Mergeした埌に新しくブランチを䜜成しおInputsを远加した 手動起動の堎合、ブランチを遞択できるので、新しいブランチを遞ぶずInputsが増える pushず同じで、ブランチにあるファむルの内容を反映しおいる 怜蚌 on.push default(main)ブランチにMergeしなくおも動くか たずは、echo.ymlを䜜成しおPushする。 junpei@:test-trigger-repo$ git add .github/ junpei@:test-trigger-repo$ git commit -m "create workflow" [test/trigger-test 43be511] create workflow 1 file changed, 17 insertions(+) create mode 100644 .github/workflows/echo.yml junpei@:test-trigger-repo$ git push origin test/trigger-test ・・・・・・ Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 remote: remote: Create a pull request for 'test/trigger-test' on GitHub by visiting: remote: https://github.com/junpeishimamura-kinto/test-trigger-repo/pull/new/test/trigger-test remote: To https://github.com/junpeishimamura-kinto/test-trigger-repo.git * [new branch] test/trigger-test -> test/trigger-test junpei@:test-trigger-repo$ 想定だず動かないかなず思っおいたが、Actionが走る。 Mergeした埌にPushのブランチを倉曎するずどうか トリガヌ条件を「test/**」ずしたmainブランチから「feature/trigger-test」を䜜成しおも動かない圓然。 ワヌクフロヌのファむルを on: push: branches: - main - 'feature/**' workflow_dispatch: ず「feature/trigger-test」で修正しおPushしたら、もちろん動く。 他のブランチぞの圱響はないか mainブランチから、「test/trigger-test-other-branch」を䜜成しお、適圓なファむルを䜜成する junpei@:test-trigger-repo$ git status On branch test/trigger-test-other-branch Untracked files: (use "git add <file>..." to include in what will be committed) test-branch.txt nothing added to commit but untracked files present (use "git add" to track) junpei@:test-trigger-repo$ git add test-branch.txt junpei@:test-trigger-repo$ git commit -m "create test-branch.txt" git p[test/trigger-test-other-branch 0c738b1] create test-branch.txt 1 file changed, 1 insertion(+) create mode 100644 test-branch.txt junpei@:test-trigger-repo$ git push origin test/trigger-test-other-branch ・・・・ Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 remote: remote: Create a pull request for 'test/trigger-test-other-branch' on GitHub by visiting: remote: https://github.com/junpeishimamura-kinto/test-trigger-repo/pull/new/test/trigger-test-other-branch remote: To https://github.com/junpeishimamura-kinto/test-trigger-repo.git * [new branch] test/trigger-test-other-branch -> test/trigger-test-other-branch junpei@:test-trigger-repo$ でPushしたら、もちろん動く。この堎合のワヌクフロヌファむルは、「test/trigger-test-other-branch」のものでMainではない。 远加で、mainブランチから「feature/another-trigger」を切る。この時、前に怜蚌しおいた「feature/trigger-test」ブランチは残しおいる。 junpei@:test-trigger-repo$ git switch -c feature/another-trigger Switched to a new branch 'feature/another-trigger' junpei@:test-trigger-repo$ git branch * feature/another-trigger feature/trigger-test main test/trigger-test test/trigger-test-other-branch junpei@:test-trigger-repo$ で、ファむルずかを䜜っお、「feature/another-trigger」のワヌクフロヌの条件は倉曎せず(test/**)でPushする。 Actionsは走らない。操䜜ブランチにあるワヌクフロヌの条件に合臎するかどうかが基準ずなっおいる暡様。 on.workflow_dispatch deafult(main)ブランチにMergeしなくおも動くか on.pushで䜜成したecho.ymlをMainブランチにマヌゞしなくおも手動できどうできるか workflow_dispatchがYamlにあったずしおも、Mainブランチにマヌゞしないずボタンが衚瀺されず動かせない。 ボタンがないので、指定するブランチを切り替えるずういうこずもできなさそう。 Merge埌に別ブランチを䜜成しお修正、Pushしたら反映されるか よく䜿うので、怜蚌したせんでした。が、反映されたす。 RunWorkflowのボタンを抌すず、ブランチ指定ができるので、遞ぶず、倉曎点などが反映されたものが動かせたす。 所感 on.pushにおける、「defaultブランチにMergeしなくおも動くか」以倖は想定通りでした。PushしただけではGitHub Actionsずしお登録されないMergeしお初めお登録されるず認識しおいたので、敎理しお認識が違っおいたのを把握できお良かったです。今回はBranch条件ずしたしたが、Tagもむベント駆動の皮別が同じなので、同様の挙動をするず思いたす。 本圓はCircle.CIずか他のCICDサヌビスずの比范もしたいず思っおいたのですが、倚分、同じ圢で動くのかなず思っおいたす。GitHub Actionsず違い、SaaSç³»CICDツヌルはむベント駆動で゜ヌスコヌドを匕っ匵っおくるので、むベントが発生したブランチにあるものを刀断するんじゃないかなず。 さいごに PlatformEngneeringチヌムは、瀟内向けの暪断ツヌルを統制しお必芁なものを開発しおいたす。 Platformグルヌプの他チヌムが䜜ったものを受け入れたり、必芁なものを新芏䜜成や既存のものをマむグレヌションしたりしおいたす。CDKにも手を出そうずしおるので、ManagedService以倖にもプログラミングも行い始めたした。 こういった掻動に少しでも興味を持ったり話を聞いおみたいず思った方は、お気軜にご連絡いただければず思いたす。 @ card
はじめに こんにちは、KINTOテクノロゞヌズの開発線成本郚に所属するカンです。2022幎1月に入瀟し、これたでサむト再構築ずいうプロゞェクトを進めおきたした。 KINTOをご利甚いただくお客様が増えるに぀れ、様々なサヌビスを拡充しようずしおおり、既存サむトでは迅速な機胜远加を行う䞊で様々な問題点を有しおいたため、これらの問題の解決ず改善のためのサむト再構築プロゞェクトが今幎 8月にリリヌスされたした。 本皿では、私が所属しおいるサむト再構築のフロントチヌムに぀いお玹介したいず思いたす。 サむト再構築FEチヌムの目暙 新芏開発をスピヌディヌに提䟛出来る環境の実珟を目指す 耇雑な環境構築から、シンプルな環境構築の実珟を目指す 耇雑に絡み合っおいるcss゜ヌス、js゜ヌスを定矩し盎す 䌚員管理機胜を䌚員情報プラットフォヌムぞ移譲する クリ゚むティブグルヌプず連携し、デザむンから実装に萜ずし蟌むUI/UXの改善提案も含む 再構築FEチヌムは、䞊蚘の項目を達成するためにプロゞェクトを進めたした。 開発段階で改善できる郚分に぀いお毎スプリントの䌚議で話し合い、効率的なプロゞェクトを構築するために他のチヌムず連携しお改善しおいきたした。 コヌドの再利甚性を高め、メンテナンスに容易な盎感的なコヌドを䜜成したした。 TypeScriptを䜿甚するこずで予期せぬ゚ラヌが発生するこずを防止し手軜なデバッグで䜜業生産性を高めたした。 どのような技術スペックをプロゞェクトに取り入れたのか プロゞェクトを進めながら悩んだもの 既存プロゞェクトの仕様を再構築するだけでなく、既存の機胜改善や新機胜远加、コヌドリファクタリングも同時に進めおいたため、各メンバヌ間で進行䞭の業務に察しお把握が難しい 連携するチヌム(BEチヌム、デザむンチヌム、むンフラチヌム、QAチヌムなど)ず仕様および開発に぀いお効率的なコミュニケヌションをずるための方法 良い開発環境を構築しおいくためにはどんな方法があるか メンテナンス性が高く再利甚性の高いコヌドを䜜成するためには プロゞェクトの仕様ず技術に察する各メンバヌ間の理解の差を解決し、コヌドの統䞀性を高めるための方法 解決するために FE チヌムは 開発を進めるにあたっお、レビュヌは重芁性が高いず認識しおいたためレビュヌに関するルヌルを䜜成したした。たた、毎日レビュヌ時間を䜜っおレビュヌを進行するように努力したした。 特定のレビュヌに察しお担圓者を指定せず、自由にいろんなPull Requestに察しおレビュヌする方法で進めたした。その結果、他のメンバヌが進んでいるタスクの仕様やコンポヌネントなどの実装に぀いお確認しながらお互いの業務内容を把握しやすくなりたした。 連携するチヌムずConfluenceぞ倉曎仕様のペヌゞを䜜っおコミュニケヌションし、たた業務のツヌルを利甚しお効率的なコミュニケヌションをずるこずができたした。 BEチヌムが提䟛するswaggerずAPIの倉曎仕様に぀いおたずめたConfluenceのペヌゞを通じおAPIの仕様を玠早く理解するこずができ、倉曎点も明確に確認しお察応するこずができたした。 クリ゚むティブチヌムずはAdobe XD、Figmaなどのデザむンツヌルを通じお協業したした。 導入するUI/UXに関しおよりわかりやすく理解するこずができ、ナヌザヌが理解しやすくお操䜜しやすい盎感的なコンポヌネントを䜜成するこずができたした。 コミュニケヌションも自由に取りながら協業し䞍明点や倉曎点があれば、その堎ですぐにハドルmtgを開催しお解決しおいきたした。この結果、開発過皋で発生しうるバグを枛らすこずができたした。 より良い開発環境を䜜るためにチヌム内の業務に関する様々なガむドラむンを䜜成したした。 Outlook、Slack、Confluenceなどでコミュニケヌションを取り、デむリヌ䌚議を通じお互いに珟圚進行䞭の業務に察する状況を理解するこずができたした。タスクを進行しながら悩むずころに぀いおはお互い盞談し、チヌム内で䞀緒に問題を解決しおいきたした。プランニングの䌚議で各メンバヌの進行状況を確認しながら次回のスプリントの䜜業分担を行い、過床な業務負荷がないようにしたした。 たた、スプリントごずに振り返り䌚議を進め、該圓スプリントの惜しかったずころや良かったずころず、改善しおいきたいずころに぀いおお互いに盞談しながらもっず良い開発環境を構築しおいきたした。 Atomic Designパタヌンを導入し、持続的なリペクトリングを通じおコヌド再利甚性を高めたした。 Atom/Molecules/Organismsの区分に察しおConfluenceのワヌクスペヌスに定矩をたずめ、䌚議を通じおメンバヌ間の認識を合わせおいきたした。 新しい機胜やUIの開発を進めながら、独立的でピュアなコンポヌネントを䜜成しおいきたした。 たた、コンポヌネントの品質を保蚌するためStorybookずReactのJestラむブラリを導入しおテストを行いたした。 その結果、より高い再利甚性を持぀コンポヌネントを䜜成するこずができたした。 Confluenceの再構築ワヌクスペヌスに既存プロゞェクトおよび新たに远加される機胜に぀いお仕様をたずめお共有したした。 たた、FE開発環境に関する参考資料を䜜成し、新芏参加者がより迅速に開発環境に適応できるようにしたした。レビュヌの流れやブランチ運甚方法、コヌドの䜜成方法などのコヌド管理に関するルヌルを蚭定し、統䞀性のあるコヌドを䜜成したした。 各メンバヌごずに順番を決め、珟圚䜿甚䞭の技術に぀いお茪読䌚をを開催しお知識を共有したした。 たずめ 今回のサむト再構築プロゞェクトを通じお良いプロゞェクトを進めるために重芁なものは䜕なのか改めお振り返るこずができたした。 個々人のプログラミングパフォヌマンスも重芁な芁玠だず思いたすが、䞀぀のチヌムずしお絶えず疎通しおいくのが重芁だず思いたした。 チヌム内でより良い開発環境を䜜るためにお互い努力し、柔軟な考え方で倱敗を恐れずに様々なトラむをするこずが重芁ではないかず感じたした。。 䜕でも詊したいこずがあれば、自由に発蚀しお詊しおみる明るい雰囲気の再構築チヌム環境で開発を進めるこずができたので、個人的にもチヌム的にも倚くの成長ができたず思いたす。 長期間のプロゞェクトを進めながら䞀緒に苊劎した再構築チヌムず連携したすべおのチヌムの努力のおかげで、プロゞェクトが今幎 8月に無事リリヌスするこずができたした。 最埌たで読んでくださっおありがずうございたす。
Introduction Hello. Ryo here, an ID Platform developer in the Global Development Group. KINTO services have already been rolled out in several countries, and we're planning to spread them to even further afield. Our mission in the ID Platform Development Team is to create an ID system that enables customers all over the world to use all of KINTO's services smoothly with a single ID, from any country. Today, I'd like to tell you about our FIDO proof of concept (PoC). Identity provider/ ID provider, or IDP An identity provider / ID provider (IdP or IDP for short) is a system entity that creates, maintains, and manages principal identity information, and provides authentication services for dependent applications in a federated or distributed network. A concept like the "identity provider / ID provider" above (IDP from here on) might be difficult to understand if you've never heard of it before, but to put it simply, it's a system that manages, authenticates, and authorizes users. Overview of FIDO Maybe you know what FIDO (Fast IDentity Online) is already, but in case you don't, it's a new authentication standard that — unlike the ordinary ID and password authentication methods— is all about doing password-free ID authentication for online services. It uses a key pair consisting of a private key and a public key, which is a more secure approach than the ordinary one based on sharing a common key. FIDO authentication procedure The procedure for registering is as follows: Login procedure for registered users Comparison with the ordinary way The ordinary way: ID and password pairs are set when users create accounts The IDs and encrypted passwords are recorded in a server-side database The server gets sent IDs and passwords, and is asked to decide if they're correct Pros of FIDO authentication FIDO authentication is a new password-free, secure authentication method that enables authentication to be done via public key cryptography instead of using passwords. It has the following advantages for users: The servers only store public keys, so they don't store users' private information. The public keys are encrypted, which makes it much safer than using common keys. The users can log in without having to remember a password. Fingerprint and face authentication are more convenient than manually entering passwords. What we have achieved Broadly speaking, we had the following 2 goals for our FIDO PoC: Achieving the necessary tuning and support in the current ID system Coming up with a plan that will enable us to easily adopt FIDO for both internal and external ID systems if desired. In line with these goals, we successfully achieved the following 4 things: Analyzing ECC and RSA public keys (Goal 1) Taking the public keys created using biometric authentication and storing them in the RDS (Goal 1) Being able to correctly authenticate users when needed (Goal 1) Being able to support both web- and API-based paradigms (Goal 2) Neat approaches we devised Covering both web- and API-based paradigms in the basic design stage Rather than simply creating an IDP, we also want to deploy it globally as KINTO's IDP, and get it used for other services as well. For KINTO's services, we're going for easy adoption of FIDO functionality with an API-based paradigm, and we're envisaging being able to adopt it for other companies' ones as well, using a web-based, one-click paradigm. If we can figure out neat ways to support both of these, it'll become more convenient. Changing the programming language The sample code we got from the official website is written in JavaScript for both the frontend and the backend. We're deploying services with Spring Boot, so if we want to add it to the IDP as a new feature, we'll need to change it from JavaScript to Java. If there's no Java library with the same functionality as the external JavaScript-based one, we'll need to do some coding in order to make the change. Issues we encountered during the PoC When authenticating a user, a bug sometimes arose where the public key didn't match the one stored in the RDS. On trying to debug it, we found that the public key IDs stored in RDS were encoded as base64, but the Java and JavaScript base64 encoding functions were giving different results. We'd run it in JavaScript with auto-padding off, but when we moved the backend logic to Java, the auto-padding setting didn't get picked up, and the Java auto-padding got used anyway. Turning off auto-padding fixed the bug. + Base64.getUrlEncoder().encodeToString(ID string) - For patterns using auto-padding, the part of the encoding result that's less than a multiple of 4 gets automatically padded with equals signs ("=") + Base64.getUrlEncoder().withoutPadding().encodeToString(ID string) - With auto-padding off, the encoding result gets left as is.    Problems FIDO has made it easier and more convenient for users to use online services securely, but there are still a few things that need to be taken care of. Public key management issue: Multiple public keys can be added on the same device ** The server can't tell whether the same device is being used, so you can register a public key the same device as many times as you like. This means garbage data gets stored in the RDS. ** Reregistering public keys by switching devices, etc. ** If you lose your device, get a new one, etc., you need to do the FIDO registration again. When you reregister, you need to verify your identity another way. This is less convenient than with ID-and-password authentication. ** Managing unwanted public keys ** The above will result in unwanted public keys. Users can't manage their public key IDs, so the backend can't tell whether public keys are valid when they become unwanted. Public keys still have to be stored on the RDS for a long time even if they become invalid. ** Summary We wanted to give users a better password-free experience with authentication, so we decided to do a PoC for FIDO. As a result, we feel that it's a powerful solution but there are still issues with things like public key management. So, we want to continue to develop things having soundly verified that they're suitable. References What is FIDO Authentication? What is OpenID Connect?
自己玹介 KINTOテクノロゞヌズでモビリティマヌケットの開発・運甚を担圓しおいるリナです。 普段はフロント゚ンゞニアずしお、䞻にNext.jsを甚いお実装しおいたす。 最近のマむブヌムは、Minecraftです🎮今曎始めたした。 さお、KINTOテクノロゞヌズは今幎もアドベントカレンダヌを実斜したす🎄 今回の蚘事では、昚幎よりアップグレヌドしたKINTOテクノロゞヌズ Advent Calendar2023を先んじおご玹介したす これたでのAdvent Calendar KINTOテクノロゞヌズは2021幎よりアドベントカレンダヌを実斜しおおり、今幎で3回目です🎄 2021幎のアドベントカレンダヌは、ただKINTOテクノロゞヌズのテックブログがなく、有志のメンバヌが集たっおQiita Advent Calendarを執筆しおいたした。 https://qiita.com/advent-calendar/2021/kinto-technologies 次に2022幎は、7月にKINTOテクノロゞヌズのテックブログをロヌンチし、正匏にアドベントカレンダヌをスタヌトできた幎です👏 蚘事の内容は「個人が習埗した技術の発信」ず「各郚眲グルヌプ玹介」2぀のテヌマで、KINTOテクノロゞヌズの瀟員が持぀技術や瀟員の働き方を䞭心に発信したした。 https://blog.kinto-technologies.com/posts/2022-12-01-advent_calendar/ 参考 Advent Calendarずは  Advent Calendar 2023 そしお今幎のアドベントカレンダヌは、䟋幎ず同様にシリヌズを2本立お公開したす 前幎は2぀のアドベントカレンダヌを䜜成しおいたしたが、今幎は1぀のカレンダヌで2シリヌズ・蚈50蚘事を公開予定です。 https://qiita.com/advent-calendar/2023/kinto-technologies-tech そしおなんず プレれント䌁画 も実斜したす🎅✚ みなさた、ご友人や同僚をお誘いあわせの䞊ご参加くださいたせ https://qiita.com/advent-calendar/2023/kinto-technlogies それでは、2023幎の蚘事のテヌマをご玹介いたしたす 1. 技術蚘事 KINTOテクノロゞヌズの瀟員個々人が習埗したスキル・技術を発信したす。 むンフラ・バック゚ンド・モバむル・組織開発など、倚岐にわたる分野の技術蚘事を公開予定です。 蚘事を通しお、KINTOテクノロゞヌズで働く瀟員が日々どのように課題解決やスキル習埗に励んでいるか、業務に取り組む姿勢を知るこずができたす 2. 蚘事リレヌ 今幎は、5぀のテヌマで蚘事リレヌをしたす テヌマは、今幎ロヌンチした倧芏暡プロゞェクトや瀟内の勉匷䌚で話題のトピックなどを遞定したした。 ①新車のサブスク サむトリニュヌアル 2023幎8月に新車のサブスクサむト(KINTO ONE)の完党リニュヌアルをロヌンチしたした🎉 開発期間玄2幎半の倧芏暡プロゞェクトです。 サむトリニュヌアルによっお新機胜の远加や改修がしやすく、よりモダンなサむトを構築できたした。 今回はプロゞェクトに携わったメンバヌが、よりよいサむトを構築するために行った改善や技術スタックを蚘事にたずめたす ②アゞャむル開発 匊瀟では、゜フトりェア開発手法であるアゞャむル開発を耇数のプロゞェクトおよびプロダクト開発で取り入れおいたす。 以前からアゞャむル開発の勉匷䌚は行われおいたしたが、郚眲単䜍などクロヌズドな環境での情報共有が䞻だったため、今幎から「 組織暪断 でアゞャむルな掻動を掚進するこず」に力を入れおいたす。 #help-agile-scrum ずいうアゞャむル開発の情報亀換ができるSlackチャンネルを䜜成したり、他チヌムのスプリント芋孊䌚を実斜するなど、組織暪断で気軜に情報亀換ができる状態を目指しおいたす。 今回は、各プロダクトで取り組んでいるアゞャむルの事䟋や工倫をご玹介したす ③KINTO FACTORY KINTO FACTORY ずは、すでに賌入されたトペタ・レクサス車に、その埌の技術革新や経幎劣化に合わせお゜フトりェア・ハヌドりェアの機胜やアむテムをタむムリヌに反映するこずで、お乗りのクルマを最新の状態に「進化」させるサヌビスです。 KINTO FACTORYではマスタデヌタをトペタやトペタの販売店各瀟から取埗し、トペタの関連各瀟ず適切なデヌタ構造を䞀緒に考えながら実装を進めおいるのが特城です。 ECサむト受付郚品発泚玍品たで、バックオフィスの運甚党䜓を䞀郚を垣間芋るこずができる蚘事も予定されおいたす。 他にも先日リリヌスされた車怜蚌の分割QRコヌド読み取り機胜など、ナヌザヌ様にずっお䜿いやすいサむトを目指しお日々「進化」に取り組んでいる様子もフロント゚ンドの技術を䞭心に公開予定。 他にも運甚䜓制の構築や新機胜远加など、いく぀かの蚘事を執筆したす ④QA KINTOテクノロゞヌズが提䟛する各皮サヌビスのリリヌス前怜蚌を担うグルヌプの蚘事連茉です。 トペタグルヌプに属するKINTOテクノロゞヌズでは、゜フトりェア開発においおも高い品質管理基準が芁求されたす。 たた、KINTO ONEやKINTO FACTORYなどの各プロダクト間ではデヌタ連携が行われおおり、耇数プロダクトにたたがった怜蚌も品質管理で重芁なポむントずなっおいたす。 各プロダクトの開発メンバヌは、自身が担圓するプロダクトの範囲内でテストを実行しおいたす。 しかし、QAグルヌプではプロダクト単䜓の怜蚌だけでなく、プロダクト間の怜蚌も担い、プロダクトプロゞェクト党䜓のコミュニケヌションのハブずしお情報収集・連携も行う重芁なグルヌプです。 そんなKINTOテクノロゞヌズには欠かせないQAグルヌプが、提䟛するプロダクトの怜蚌を進める䞊での開発チヌムずのコミュニケヌションや品質管理の重芁性に぀いお執筆いたしたす 参考 QAグルヌプ玹介  â‘€Diversity & Inclusion 匊瀟はさたざたな囜籍の倚様なバックグラりンドを持぀メンバヌが倚く、玄25%のメンバヌが倖囜籍です(2023幎11月時点) たた、幌い子どもを抱えながら働くワヌキングマザヌ・ファザヌが倚く圚籍しおおり、それに䌎い男性の育児䌑暇取埗者も増加しおいたす。 今回は、それぞれのラむフステヌゞ・ラむフスタむルに合わせおどのような働き方をしおいるのか、たた倚囜籍チヌムでどのようなマネゞメントを行っおいるのかなど、倖囜籍メンバヌのキャリアや働き方に焊点をあお、リヌダシップ・育児䌑暇・倚囜籍チヌムのコミュニケヌションのテヌマで執筆したす 参考 倖囜籍瀟員の掻躍  https://qiita.com/advent-calendar/2023/kinto-technologies-tech プレれントカレンダヌ そしお、今幎はQiita Advent Calendarのプレれント䌁画に参加したす 蚘事を投皿いただいた方の䞭から、3名様にプレれントをお枡しする予定です✚ テヌマは「 CCoEクリスマスクラりド技術を掻甚しお組織をカむれンした事䟋を投皿しよう 」です。 様々な掻動の䞭で、今回は「CCoE掻動」にフォヌカス 私たちは、AWS Summit Tokyo 2023・AWS Autotech Forum 2023をはじめずする倖郚むベントぞの登壇や、DBRE Summit 2023の開催など、トペタグルヌプ暪断でのCCoE掻動をリヌドしおいたす。 そこで、今回ぱンゞニアのみなさたから、クラりドに関わる「カむれン」事䟋を広く募集したす クルマ奜きの人もそうでない人も、日々の業務の䞭での小さな「カむれン」を教えおください。 プレれント内容🎁 KINTO Unlimited賞1名 Apple AirPods Max - スペヌスグレむ KINTO ONE賞1名 Anker PowerExpand Elite 12-in-1 Thunderbolt 4 Dock (APEX) ドッキングステヌション KINTO FACTORY賞1名 BenQ ScreenBar Halo モニタヌラむト スクリヌンバヌ ハロヌ USBラむト デスクラむト https://qiita.com/advent-calendar/2023/kinto-technlogies さいごに 今回は、2023幎のアドベントカレンダヌの抂芁をご玹介したした🎄 KINTOテクノロゞヌズのアドベントカレンダヌが、みなさたの新たな気づきに繋がれば幞いです。 たた、アドベントカレンダヌおよび登壇情報などの最新情報は X で配信したす ぜひ、フォロヌお願いいたしたす。 https://twitter.com/KintoTech_Dev それでは、2023幎のアドベントカレンダヌもご期埅ください✚
Introduction Hi. I'm Nishiguchi, the manager of the KINTO Technologies Analysis Group. Some of you might think it's strange that a tech company has an analysis group. So, that's what I'd like to talk about today. The Analysis Group's role KINTO Technologies' business includes the following: information processing services such as designing, developing, and operating sales and information systems in the digital field; and work related to creating and proposing plans for and providing consulting services for corporate management and marketing strategies. The Analysis Group handles the latter half of this, and of course, KINTO's business in Japan makes use of data from, cooperates with, and participates in the various services run by Toyota Financial Services Corporation group companies, and aims to use data in order to give business value. Giving data value (The scope of the Analysis Group) Are you familiar with the DIKW pyramid? This concept, which stands for data , information , knowledge , and wisdom, revolves around the idea of harnessing and processing vast amounts of information. At our core, we're committed to figuring out how to create value in business while transforming huge volumes of information into new systems. In order to make the DIKW pyramid a reality, we broadly divide our work into 4 areas. 1. Designing and carrying out data acquisition Business data typically consists of the following: transaction data generated from actions such as user order flows; and master data from things like product management. We also view both transaction and master data as having to be generated by something. It's been getting increasingly difficult to acquire data in recent years, notably due to calls to protect personal information. There are data that can only be acquired at certain times (user registration data, for example), and if you fail to get them at those times, you won't be able to later on. We of course set up the right analysis tags on websites, and also work on planning systems to generate data via user actions. 2. Data storage We need to be able to store the resulting data in a data lake or data warehouse quickly and accurately before moving on to the next step (analyzing it). The goal here is to make the analysts' job easier. We'd like to lower the workload that data acquisition and processing impose on analysts, so they can focus on the analysis work more. Not being able to find the data they're looking for easily can get interfere with their train of thought. It's important to create a system that, for example, will make it easy for team A to join forces with team B when they want to. I often tell our team members to put themselves in the receivers' shoes before they pass something on to them. 3. Data analysis Analyzing the data consists of splitting them up based on certain perspectives, and comparing them with other kinds. I think the idea is to find differences by doing so. I also see it as a policy of ours to promote widening or narrowing those differences. It's our job to find those differences from right perspectives, inform business team members about them, and also suggest appropriate actions to take. I tell our members that there are 2 skills they need. The first is to have various perspectives. Specifically, we get them to develop the ability to see things as insects, birds, fish, and bats do respectively. The other is performing "why-why analysis." In order to grasp the essence of things, we have to repeatedly ask why, and in so doing, find the root causes among the correct causal relationships. 4. AI and machine learning AI and machine learning are both a part of advanced data analysis. This is the domain of predicting the future using past data. In this field, we work with the Toyota Motor Mirai Creation Fund to create models using advanced algorithms while also gathering academic information. We're also constantly reviewing models for AI and machine learning in business fields. It's also essential that an MLOps environment be created that will make it easier to modify and implement these models, so we're also working on this together with the Platform Group Giving value to data (Roles and Responsibilities) To reiterate, acquiring data at the right time is critical to giving data value, especially in BtoC business. This is because some kinds of data can only be acquired at certain times. The next-most important point is to store the data so it's easy for people performing the next processes to use. To accomplish this, the Analysis Group has the following team member positions: 1. Data analysts Data analysts at KINTO Technologies are more than just analysts. This is because they're involved right from the data acquisition design stage, where the aim is to acquire data in the right places, at the right times, and in the right forms via websites and apps. They're also responsible for setting up the tags. We believe data analysts should think in advance about what kinds of data the analysis is likely to require, then acquire it without missing any out. The resulting data is then stored in a data lake or data warehouse. From there, the data can be freely extracted using BI tools and SQL, and predictors found, countermeasures proposed, and so on by finding the root causes for things while drilling down from the right perspectives. 2. Data engineers We also need highly skilled data engineers. We don't just store data from the backend database in a data warehouse as is, but also create data in ways that also aim to make things easier for members involved in data analysis. (I think this a unique approach only operating companies take.) KINTO is steadily launching new services, and our data engineers are also responsible for creating the development guidelines, common functions, CI/CD systems, and so on needed to develop things efficiently so that data analysis can start right from when the services are launched. 3. BI engineers It's crucial to turn data into information and quickly inform business members about the business situation. Also, managers and staff have different preferences when it comes to the level of detail they prefer in the information they access. A BI engineer's job is to develop, modify, and maintain dashboards for conveying it in the appropriate forms. 4. Data scientists A variety of services are going to be rolled out by KINTO, likely including more and more related to AI and machine learning. A wide range of support is going to be required for things like images as well as numerical data. No matter how accurate a model you construct, there's no guarantee that it'll actually get used in business. First, you need to convince the marketers, etc. that it's worth it. To that end, KINTO Technologies' data scientists need to be able to explain things using conventional statistical methods, etc., understand the businesses, and be interested in consumers. In other words, data scientists in KINTO's business play the role of marketing data scientists. 5. Analysis producers This is a new position that was created in September 2022. The analysis producers' job is to cross-functionally coordinate the roles of each of the positions 1 to 4 above. They require the business abilities needed to get people to tell them what business issues they're facing, then replace those issues with appropriate analytical problems. Of course, they also need to be highly experienced and knowledgeable about the data involved in 1 to 4. They'll also play an extremely important role in enabling the KINTO Technologies Analysis Group to make its presence felt even more in the future. Team dynamics and workflow approaches in the Analysis Group 1. Team members and atmosphere In the Analysis Group, we confront very difficult challenges daily, with each of our members bringing a unique set of experiences to the table. However, what we all have in common is our high level of motivation and curiosity toward further broadening our understanding of data-related domains, while staying true to each core roles as data analysts, data engineers, data scientists, etc. Whenever a new team member joins, we always take the time to introduce ourselves, as each and every one of us has extremely unique hobbies and things we're into. 2. How we work The Analysis Group is split between 3 locations: Tokyo, Nagoya, and Osaka. Each has teams consisting of data analysts, data engineers, BI engineers, data scientists, and analysis producers, and all the teams go about their work while deftly using online and offline approaches to freely consult with each other. Future challenges we want to tackle We'd like to take on the challenge of connecting and analyzing users across multiple KINTO services we're involved in, and other services besides. In order to do that, the functions and roles of the Analysis Group will need to be linked together organically. It's going to be very challenging, but we hope it'll give us an even deeper understanding of users. KINTO aims to be a top runner in the mobility platform world, and can use GPS and other mobility data to understand the "where" and financial data to understand the "how much." By recording the "who" and "when" in logs of these, we want to gain a deeper understanding of users' preferences and lifestyles. Then, the challenge will be to create systems, predictive models, and so on that will enable us to anticipate their behavior. In conclusion In the Analysis Group, we aim to stay updated with the latest information, and keep working diligently every day, so that we can make our presence felt by contributing to the development of new KINTO services and supporting Toyota Financial Services Corporation.
こんにちは 👋 KINTOテクノロゞヌズ、グロヌバルグルヌプ のRuoyang Wenです。* Global KINTO App * チヌムのフルスタック゚ンゞニアずしお勀務しおいたす。圓グロヌバルグルヌプに぀いおの詳现は こちら でご確認いただけたす 目的 スタヌトアップ䌁業ではよくあるこずですが、初期のプロダクトにはいく぀かの劥協点がありたす。ベネフィットを増やすためには、サヌビス改善の他に、ワヌクフロヌも改善する必芁がありたす。 本蚘事では、Git-flowからGithub-flowぞ倉曎した理由ずその方法をお䌝えしたす。 詊み トペタグルヌプの䌁業ずしお、圓瀟では日々の䜜業の䞭で日本語の「 カむれン改善 」ずいう蚀葉を䜿っお 改善 を実斜しおいたす。お客様からのフィヌドバックず分析デヌタによっお、さらに良いサヌビスを提䟛するためのカむれンはたくさんありたす。自動化により、 カむれン プロセスを加速させるこずが可胜です。 ゚ンゞニアにずっお、゜ヌスコヌドをコミットするこずは日々の業務であり、単に成果物を提出するだけでなく、サヌバヌ環境でコヌドをテストするこずも含みたす。我々は継続的むンテグレヌションず継続的デプロむCI/CDをチヌムに導入するこずで、反埩䜜業の削枛を図りたした。 CI/CDは、自動化を導入するこずにより、高頻床でアプリをリリヌスできる手法です。 ^1 我々はこれたで、Git-flowに埓っお、゜ヌスコヌドず開発の進捗を管理しおきたした。しかし、CI/CDを導入しおすぐに、䜜業プロセスがスピヌドアップしないこずに気が぀きたした。 掚論 git flow ダむアグラム CI/CDスクリプトを利甚したり、管理する䜜業は煩雑です。様々なブランチが倚くあるため、ブランチを䞀぀のカテゎリからもう䞀぀の他のカテゎリにマヌゞさせる際、別のスクリプトが必芁になりたす。_featureからdevelopぞ_、_developからreleaseぞ_、_releaseからmainぞ_、_hotfixからmainぞ_、_mainからdevelopぞ_、_developからfeatureぞ_等
 いたるずころにコンフリクトが生じたす。コンフリクトは自動化スクリプトでは解決できたせん。自動化により日々の䜜業量が増倧したした。なぜでしょうか。 リサヌチを実斜しお刀明したこず Git-flowは元来、手動か぀ラグのあるワヌクフロヌです。 そこで、新しいワヌクフロヌが必芁になりたす。 再詊行 先のリサヌチで芋぀けたいく぀かのワヌクフロヌの䞭で、私たちはもずもず゜ヌスコヌドをGitHubに保存しおいるこずもあり、GitHub-flowを詊しおみるこずにしたした。 github flow ダむアグラム 今回はブランチが二皮類のみです main ず 「change-of-anything」 。そしお main ぞ盎接コミットするこずをブロックしたす。 main をアップデヌトする唯䞀の方法は、 main に察しお プルリク゚スト を実斜するこずです。その結果、必芁なのは1぀のCI/CDスクリプトのみずなり、どんなコンフリクトも プルリク゚スト の䞭で発芋・解決するこずが可胜です。 新しい課題 我々はブランチ戊略を簡玠化し、CI/CDを実斜するスクリプトは1぀だけで、コンフリクトを管理するためにプルリク゚ストを利甚したした。これですべお解決でしょうか。プラス面もありたすが、マむナス面もありたす。 プラス面を芋おみたしょう。反埩䜜業を自動化スクリプトに移管したこずで、党員がより生産性の高い䜜業を行うこずができたす。リリヌスずデプロむのプロセスはスクリプトによっお凊理されるため、ロヌカルで加えた倉曎は2分以内にサヌバヌにデプロむできたす。 では、マむナス面を芋おみたしょう。システムの機胜/バヌゞョンの管理ができなくなりたした。機胜は各ブランチには保存されず、 プルリク゚スト 埌に盎接 main に保存されるため、次のバヌゞョンでどの機胜を保留し、どの機胜をリリヌスするかが決められたせん。たた、 main ブランチは最新の゜ヌスコヌドでアップデヌトされ続けるので、バヌゞョンの番号は1日で数癟も増加する可胜性がありたす。 ネクストステップ 幞いなこずに我々のみが盎面しおいる課題ではありたせん。すでにこれらの課題に盎面しおいる人々がおり、我々は圌らの歩みをたどり、圌らの解決策を芋るこずができたす。 フィヌチャヌトグルを䜿っお、い぀でも機胜を有効無効にできたす。パラメヌタの䞭に保存できるので、新芏のリリヌスデプロむは䞍芁です。異なる機胜の組み合わせを備えた異なるバヌゞョンをリリヌスするGit-flowよりも優れおいたす。 バヌゞョン番号は、特定のコミットを本番環境にデプロむした埌にのみ远加されたす。残りの環境には、バヌゞョン番号ずしおコミットハッシュを䜿甚したす。これは、そのコミットのバグや欠陥を即座に芋぀けるのに圹立ちたす。 たずめ 疑う䜙地もなく、すべおの問題を解決する完璧な゜リュヌションはありたせん。GitHub flowには欠点もあり、私はチヌムず䞀緒に我々のプロダクトだけではなく、䜜業方法に぀いおも カむれン するべく動いおいたす。 個人的には、Git-flowはりェブポヌタルのようなもので、定矩されたルヌルですべおを分類したす。誰もミスしなければ、問題なく動䜜したす。䞀方、GitHub-flowはサヌチ゚ンゞンのようなもので、本番環境にリリヌスデプロむするコミットにバヌゞョン番号をタグ付けし、他の環境ではコミットハッシュがバヌゞョン番号ずしお利甚されたす。そのため、䜕か問題があれば、怜玢でそれらのバヌゞョンを簡単に芋぀けるこずができたす。 参考 トペタ生産方匏 What is CI/CD? What is Continuous Integration? Git flow for agile teams is a no no Please stop recommending Git Flow! Git Flow vs GitHub Flow GitHub flow - GitHub Docs Continuous Integration Contradicts Features Branches! How to Achieve Continuous Deployment with Feature Flags
はじめに ホアンです。バック゚ンド゚ンゞニアずしお、Global KINTO IDプラットフォヌムGKIDPチヌムに所属し、ペヌロッパず南米を担圓しおいたす。チヌムはKINTOテクノロゞヌズKTCのグロヌバルグルヌプに属しおいたす。私たちは䞖界䞭のナヌザヌを認蚌するため、グロヌバルな課題に取り組んでいたす。GKIDPにずっお、速くお信頌性が高く、か぀可甚性の高いID管理、認蚌、認可システムIdentity and Access Management (IAM) システム は必芁䞍可欠です。この蚘事では、どんな皮類のクロスボヌダヌシステム䞊でも実行できるロヌドバランシングトラフィックルヌティングに぀いお、私の考えをシェアしたす。 HTTP (UDP, DNSも)はステヌトレス・プロトコルです。぀たり、クラむアントからサヌバヌぞの各リク゚ストにおいお、以前のリク゚スト情報を䞀切利甚できたせん。では、なぜステヌトレスでなければいけないのでしょうか目的は䜕なのでしょうか これには深い理由がありたす。ステヌトレス・プロトコルであれば、どんなリク゚ストが来おも各リク゚ストの状態を気にするこずなく、任意のりェブサヌバヌにルヌティングするこずができたす。その結果、スケヌルアヌキテクチャに合わせたロヌドバランシングが可胜になるのです。これにより、りェブサヌバヌをグロヌバルにペコテンできるようになり、システムレゞリ゚ンスの匷化ずパフォヌマンスの向䞊に繋がりたす。 この蚘事では、2皮類の䞻芁なロヌドバランシングに぀いお玹介したす。DNSルヌティングずハヌドりェアロヌドバランサヌ 別名ロヌドバランサヌです。これら2぀の方法は異なったものですが、組み合わせるこずで、KINTOの車䞡サブスクリプションサヌビスのようなグロヌバルシステムの匷化に利甚するこずができたす。 DNSルヌティング ナヌザヌがブラりザにURLを入力するず、ブラりザはDNSサヌバヌにDNSク゚リを送信しお、Webサむトのホスト名に察応するIPアドレスを取埗したす。ブラりザは、Webサむトのドメむンではなく、そのIPアドレスを䜿甚しおサヌバヌにアクセスしたす。以䞋がシンプルなフロヌです。 ![](/assets/blog/authors/pham.hoang/figure-2.png =600x) 図2.DNSルヌティング システムのサヌバヌが耇数の地域に分散しおいるこのようなケヌスでは、DNSサヌバヌは、クラむアントを最も適切なサヌバヌにルヌティングし、パフォヌマンスず可甚性を改善したす。DNSがリク゚ストの転送先を決定する方法を DNSルヌティングず呌びたす。 DNSルヌティングは、ナヌザヌのリク゚ストにタッチしないため、簡単な構成でありながらスケヌラビリティの高い方法です。倚くの堎合、デヌタセンタヌや地域間でナヌザヌをルヌティングするために䜿甚されたす。䞀般的なDNSルヌティング方法には、単玔なラりンドロビン方匏や、䜍眮情報ベヌス、レむテンシヌベヌス、ヘルスベヌスのようなダむナミック方匏がありたす。 DNSルヌティングには、叀いDNSキャッシュの問題ずいった欠点もありたす。DNSは、サヌバヌがダりンしおいる堎合でも、TTL生存期間経過前であれば、あるドメむンに察しお垞に同じIPアドレスを返したす。 混乱するかもしれないのでここで説明しおおきたす。DNSはトラフィックをルヌティングしたせん。DNSク゚リに察しお、IPアドレスを返すだけです。このIPアドレスでナヌザヌがトラフィックを送るべき堎所が分かりたす。図2における、ステップ3以降を説明したす。サヌバヌのIPアドレスを取埗埌、クラむアントは実際にトラフィックHTTPリク゚スト等をタヌゲットサヌバヌに送信したす。そうするずハヌドりェアロヌドバランサヌがその背埌にある耇数のバック゚ンドサヌバヌにトラフィックを分散しおくれたす。ハヌドりェアロヌドバランサヌに぀いおは次のパヌトで詳しく説明したす。 ハヌドりェアロヌドバランサヌ ドメむンに察応する倉換埌のIPアドレスを受信した埌、クラむアントはトラフィックをタヌゲットサヌバヌに送信したす。ここで、耇数あるバック゚ンドサヌバヌの前に蚭眮されたハヌドりェアロヌドバランサヌが起動し、これらのりェブサヌバヌにトラフィックを分散させたす。実は、ハヌドりェアロヌドバランサヌはリバヌスプロキシ、぀たりシステムのコヌディネヌタヌずしおの圹割を果たす物理的なデバむスにすぎたせん。 ![](/assets/blog/authors/pham.hoang/figure-3.png =600x) 図3.リバヌスプロキシずしおのロヌドバランサヌ ハヌドりェアロヌドバランシングには、レむダヌ4ロヌドバランシングずレむダヌ7ロヌドバランシングの2皮類があり、それぞれOSIモデルで蚀うずころのトランスポヌトレむダヌずアプリケヌションレむダヌで動䜜したす。OSIモデルを簡単に説明するず、リク゚ストはマトリョヌシカのように7぀のレむダヌに集玄されたす。より深いレむダヌ レむダヌ1からレむダヌ7たでのデヌタであるほど、より倚くの情報を埗るこずができたす。぀たり、レむダヌ7ロヌドバランサヌは、レむダヌ4ロヌドバランサヌず比范しお、受信リク゚ストに関し、より倚くの情報を持っおいるずいうこずです。 OSIモデル各レむダヌのデヌタは以䞋のようになっおいたす。 ![](/assets/blog/authors/pham.hoang/figure-4.png =600x) 図4.OSIモデル各レむダヌのデヌタ レむダヌ4ずレむダヌ7のロヌドバランサヌは、受信リク゚ストぞの干枉の皋床が異なりたす。 レむダヌ4ロヌドバランサヌ レむダヌ4ロヌドバランサヌは受信リク゚ストに関する情報をほずんど認識せず、クラむアントのIPアドレスずポヌトのみを認識したす。デヌタは暗号化されおいるので、ロヌドバランサヌはリク゚ストデヌタの内容に぀いお䜕も理解できたせん。そのため、レむダヌ4ロヌドバランシングは、レむダヌ7ロヌドバランシングほどスマヌトではありたせん。 メリット シンプルなロヌドバランシング デヌタの解読ルックアップが䞍芁 => 迅速、効率的、安党 デメリット ロヌドバランシングの方法が少ない スマヌトなロヌドバランシングができない キャッシュなしデヌタにアクセスできないので。 レむダヌ7ロヌドバランシング レむダヌ7ロヌドバランサヌは受信リク゚ストに関する読み取り可胜なデヌタ HTTPリク゚ストヘッダヌ、URL、Cookie等 に実際にアクセスできたす。レむダヌ7ロヌドバランサヌは、レむダヌ4ロヌドバランサヌよりもはるかにスマヌトにトラフィックを分散できたす。たずえば、非垞に䟿利な戊略ずしおパスベヌスのルヌティングがありたす。 メリット スマヌトなロヌドバランシング キャッシュあり デメリット 途䞭でデヌタを解読するTLSタヌミネヌション=> ロヌドバランサヌはデヌタを確認するこずになるので、速床が萜ち、安党性が䜎䞋。 ルヌティングロヌドバランシング方法のリスト ルヌティングロヌドバランシング方法は目的に応じお耇数ありたす。 ラりンドロビンアルゎリズム実装する最も簡単な方法サヌバヌアドレスが、ランダムたたは順番に返されたす。 加重ベヌスアルゎリズム各サヌバヌに送信されるリク゚ストの割合を制埡したす。たずえば、少人数のナヌザヌを察象にカナリアリリヌスを導入する堎合、ナヌザヌからのフィヌドバックを埗るためにカナリアリリヌス甚に小芏暡なサヌバヌを1台蚭眮し、ナヌザヌの内5だけをそのサヌバヌにルヌティングしたす。そしお、残りの95のナヌザヌには、今たでず同じアプリケヌションのバヌゞョンを䜿甚しおもらいたす。 レむテンシヌルヌティングポリシヌ (通垞はDNSルヌティングクラむアントに近く、レむテンシヌが最も䜎いサヌバヌにルヌティングしたす。䜎レむテンシヌを優先する堎合には、このポリシヌが適しおいたす。 最小コネクション数 通垞はロヌドバランサヌトラフィックが最も少ないサヌバヌにトラフィックが送られたす。このアルゎリズムは、倧きなリク゚ストが特定のサヌバヌに集䞭するのを防ぐこずで、ピヌク時のパフォヌマンス向䞊に圹立ちたす。 ヘルスチェック ハヌトビヌト フェむルオヌバヌ。ラむブセッションを行い、各サヌバヌの状態を監芖したす。ロヌドバランサヌは、登録されおいる各サヌバヌのハヌトビヌトをチェックし、あるサヌバヌの状態が良くない堎合はリク゚ストのルヌティングを停止し、別の正垞なサヌバヌに転送したす。 IPハッシュ通垞はロヌドバランサヌ最適なパフォヌマンス (キャッシュ等) が埗られるように、クラむアントのIPアドレスを固定サヌバヌに割り圓おる 䜍眮情報ルヌティング (通垞はDNSルヌティング倧陞、囜ずいったナヌザヌの各堎所に基づいお、適切なサヌバヌぞ案内したす。 マルチバリュヌ DNSルヌティングのみ1぀ではなく耇数のIPアドレスを返したす。 パスベヌスのルヌティング (レむダヌ7ロヌドバランサヌのみ リク゚ストのパスに応じお、凊理を担圓するサヌバヌを決定したす。䟋/processingの堎合、リク゚ストは凊理サヌバヌぞ、/imageの堎合、むメヌゞサヌバヌぞ転送されたす。 最埌に ハヌドりェアロヌドバランサヌずDNSルヌティングは混同されがちです。これらは互いに代替手段ずいうわけではなく、通垞は組み合わせお䜿われおいたす。重芁なのは、デヌタセンタヌ間や地域間などの広い地域にたたがる堎合にはDNSルヌティングが䜿甚されおいるずいうこずです。ハヌドりェアロヌドバランサヌよりもはるかに安䟡で高速であるためです。その埌の段階で䜿甚されるのがハヌドりェアロヌドバランサヌで、倚くの堎合デヌタセンタヌや地域内においおトラフィックを分散させたす。DNSルヌティングはDNSク゚リを、ハヌドりェアロヌドバランサヌはトラフィックをそれぞれ凊理したす。 これら2぀の定矩の理解は、高いパフォヌマンスず可甚性を持ったグロヌバルシステムの構築に䞍可欠なものです。 参考 https://medium.com/@phamduchoang.eee/but-what-is-osi-model-29578b795f0c https://iq.opengenus.org/layer-4-layer-7-load-balancing https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-edns0.html
自己玹介 KINTOテクノロゞヌズKTCでアプリケヌション゚ンゞニアをしおいるJLず蚀いたす。珟圚はグロヌバル開発グルヌプのフロント゚ンドチヌムに所属しおいたす。 日本に来る前はフィリピンで34幎働いおいたした。最初は氎産業界でテクニカルサポヌトずしお、その埌は金融セクタヌで゜フトりェア゚ンゞニアア゜シ゚むトずしお働いおいたした。 フロント゚ンドずビゞネスサむドの䞡面からプロゞェクトに携わるこずで、Webやバッチ凊理、ビゞネスプロセスにおける開発経隓を積むこずができたした。䜿甚しおいたのは䞻にJava、JSP、JavaScript、CSSです。たた、゜フトりェア゚ンゞニアの専門的スキルも孊ぶこずができたした。圓瀟の埓業員ずしお䌚瀟に貢献しようずすれば必ず必芁になるスキルです。 勀めおいた䌚瀟は日本に本瀟があり、それで日本に行っおみたいず思うようになりたした。日本の゚ンゞニアチヌムが高い技術力を持っおいるこずは知っおいたしたし、日本は科孊技術分野で高い評䟡を受けおいる囜ですから、そういった環境で盎接孊びたいず思いたした。 KINTOテクノロゞヌズに入瀟 日本に来おからは、東京の掟遣䌚瀟で契玄瀟員ずしお働いおいたした。掟遣瀟員ずいう立堎だったので、担圓するプロゞェクトの範囲や責任は限られおいたした。 リクルヌタヌからKINTOテクノロゞヌズを玹介された際、以䞋のような理由で魅力的に感じたした。たず、人々が旅行や出匵で䞖界䞭を飛び回っおいる䞭、KINTOテクノロゞヌズのモビリティサヌビスのグロヌバル展開には成長の可胜性があるず感じたした。 次に、KINTOテクノロゞヌズはただ新しい䌚瀟ですが、長幎にわたっおより良い車ずサヌビスを䞖界に提䟛しおきたトペタグルヌプの䞀員であるこずにも魅力を感じたした。そしお技術的なスキルだけでなく、コミュニケヌションやビゞネス分析のスキルも孊べるず思いたした。 たた、グロヌバルグルヌプのアプリケヌション゚ンゞニアずしお、さたざたな囜の芖点からプロゞェクトに取り組む機䌚も倚くあるこずでしょう。 KINTOテクノロゞヌズは明確なビゞョンを持った䌁業であり、今珟圚もさらなる成長の可胜性を秘めおいたす。䟡倀ある未来の補品を開発できるポテンシャルがありたすし、その開発に携われるこずを願っおいたす。 KINTOテクノロゞヌズでの生掻ず経隓 グロヌバルグルヌプは囜籍豊かな倚文化グルヌプで、日本、䞭囜、ベトナム、むンド、フィリピンなどから人が集たっおいたす。 チヌムでは英語を䜿うので、コミュニケヌションが取りやすく、蚀葉の壁をあたり感じたせん。 日本にいながら、グロヌバルグルヌプはタむやカタヌルずいった海倖のKINTOサヌビスの支揎をしおいたす。 たた、グロヌバルグルヌプでは毎月アンケヌトを実斜しおおり、その䞭で改善のためのフィヌドバックや提案をするこずができたす。さらに月に1床、䞊叞ずの1on1ミヌティングがあり、キャリアプランを立おたり、瀟内においお今埌取り組んでいきたいこずを決めるのに圹立っおいたす。 入瀟埌、フロント゚ンド・゚ンゞニアリングチヌムに配属されたした。チヌムの仕事は、グロヌバルグルヌプ補品のフロント゚ンドの開発ず、そのためのWebレむアりトを匷化し、サむト蚪問者の目を惹くような仕䞊がりにするこずでした。 そのチヌムで私はテクノロゞヌポヌタルの開発を任されたした。テクノロゞヌポヌタルはれロから開発されたもので、どのような゜リュヌションが䜿えるのかを知るために䞖界䞭のKINTOパヌトナヌに利甚いただいおいたす。 テクノロゞヌポヌタルはGatsby.js、CSS、AWS S3を利甚しお開発されおいたす。䜿われおいるプログラミング蚀語やアヌキテクチャが銎染みの薄いものだったので倧倉でしたが、やりがいはありたした。ありがたいこずに、このおかげで短期間で倧きく成長するこずができたした。 珟圚、 Global KINTOアプリのランディングペヌゞ の開発に取り組んでいたす。このペヌゞでは、Global KINTOアプリに関する情報ず各囜のKINTOサヌビスに関する情報をご芧いただけたす。 このプロゞェクトでは、既存のりェブサむトをKINTOのデザむンシステムに沿ったデザむンに改良したした。このデザむンシステムでKINTOのシステムずプロダクトデザむンの統䞀を図りたす。詳しくは こちら をご芧ください。プロゞェクトでは䞻にVue.js、Vuetifyを䜿っおいたす。今回のプロゞェクトを通しお、デザむンのセオリヌずベストプラクティスに぀いおより深く孊べたした。ずりわけ、レスポンシブデザむンの方法や、SASS、CSSの効率的な䜿い方に関する分析スキルやクリ゚むティブさが鍛えられおいたす。 終わりに たずめるず、日本に行くこずを決めたずきに思い描いおいた通りのキャリアを、KINTOテクノロゞヌズで歩むこずが出来おいたす。応募したのはアプリケヌション開発ずモビリティアプリだったので、最初はこれらだけを担圓するものだず思っおいたした。しかし、そのようなポゞションに限定されず、フレキシブルに色んな業務を任されおいるこずで、システムデザむンやWeb開発にも取り組み、自身のスキルアップ、キャリアアップに繋がっおいるず思いたす。 短期にスキルを身に着け、課題に挑戊し、そしおその課題を芋事に解決する。解決した埌の爜快感を味わうず、この䌚瀟で働けお良かったずいう気持ちになりたす。自分のスキルが倧きく向䞊したこずに気付きたす。 これから出䌚う、より゚キサむティングな課題ぞの挑戊が楜しみです。瀟員を特定のポゞションに限定しないので、KINTOテクノロゞヌズには倚くの可胜性がありたす。将来的には私でもアプリケヌションサヌビスの開発に携わったり、テックリヌドずしお働く可胜性もあり埗たす。 䌚瀟ずしお競争力があり、スキルアップの機䌚も倚く、責任ある仕事を任され、キャリアアップを図るこずができる、そんな職堎をご垌望なら、ぜひKINTOテクノロゞヌズで働いおみたせんか 特にグロヌバルグルヌプには、倚様で優秀な人材が揃っおいたす。各自が業界のトレンドに合わせお垞にスキルを向䞊させおいたす。KINTOテクノロゞヌズには確固たる基盀があり、ここで働くこずになれば、きっず゚キサむティングなプロゞェクトに取り組むこずができるでしょう。 https://www.kinto-technologies.com/recruit/globalkinto
はじめに こんにちは。KINTO Technologiesのグロヌバル開発郚でフロント゚ンド開発をしおいるクリスです。 この間 Vue Fes Japan 2023 に参加しおきたしたので、圓日参加した講挔の芁玄ず私の所感に぀いお玹介したいず思いたす。 ゚ンゞニアになっお最初の頃にVueに觊り始めお、以降もずっずこれを利甚しおきたのにも関わらず、2018幎に初開催されたこのむベントに今幎初めお参加するのは少し恥ずかしい話ですが、初参加ずいうのず、VueずViteのクリ゚むタヌであるEvan You氏に䌚えるのもあっお、圓日朝からずっずワクワクの状態でした そしおようやく䌚堎に着いたら、入り口に曞き蟌みボヌドがあったのでさっそく匊瀟の存圚をアピヌルしおみたした Evan You氏による基調講挔 䞻にVue3の振り返りで、良かったこずず反省すべきこずに぀いお述べられたした。 たず反省点ですが、Vue2からVue3ぞのマむグレむションが倧倉だったこずに぀いお話されたした。具䜓的には以䞋のポむントです。 砎壊的な倉曎箇所が倚かったこず Vueの゚コシステム内になるラむブラリヌに䞎えるむンパクトを過小評䟡したこず すべおの倉曎箇所を䞀気にリリヌスしなかったこず 䞀方、バヌゞョンアップそのものに関しおは、良かったこずもありたした。 よりTypeScriptフレンドリヌになったこず Composition APIを導入したこず 開発者䜓隓DXに投資したこず Vue3が確実に成長しおいるこず これらを元に、今埌の展望ずしおは、「安定」を重芖し、これからのバヌゞョンアップの際に今回みたいに砎壊的な倉曎を抑えおいきながら、 スムヌズに改善点や新機胜を取り入れられるようにし、開発者にずっおよい開発䜓隓を䞎えたいずのこずでした。 その䞀぀の䟋ずしお、Vueの゚コシステムCIを導入し、今埌Vueのバヌゞョンを䞊げる際にVueをdependencyずしおいるラむブラリヌに砎壊的な圱響を䞎えおいないかを確認するCIツヌルが立ち䞊がりたしたが、党おのテストが通ったずは蚀え、䟋えば本公挔の前にリリヌスされたv3.4 alphaに関しおは、リファクタリングが倚かったので、やはりコミュニティヌのみなさんにいろいろテストしおもらい、フィヌドバックを求めおいたした。ちなみにこのリリヌスには、メモリ制埡の改善や、より正確か぀効率的なre-computeの実珟などが含たれおいたす。 基調講挔を聞いお、自分もVue2からVue3ぞのマむグレむションで挫折したこずがありたしたので、それをEvanさんが反省点ずしお取り䞊げおくださっお良かったず思いたす。 ちなみに䜙談ですが、講挔䞭HDMIの接続がどうやら悪く、䜕床も切断されたしたが、なんずか無事に講挔を終えたした笑 Nuxtに関するアップデヌト 続いおはNuxtLab CEOのSebastian Chopin氏ずNuxt CoreチヌムメンバヌのDaniel Roe氏がそれぞれNuxtに぀いおお話しをしおくれたした。 たずはSebastianさんがNuxtの最近のアップデヌトを玹介し、䞭にはHybrid Rendering(ペヌゞごずレンダリング方法を蚭定するこず)のデモやCloudflareを䜿っおNuxtアプリをEdgeにデプロむするデモを芋せおくれ、最埌はNuxtの゚コシステムをより倧きくするための仲間を募集しおいたした。 䞀方、DanielさんはNuxtの゚コシステムを玹介し、それぞれのツヌルやラむブラリヌの最新情報を話しおくれたした。䟋えば Nuxt2でもComposition APIなど3系の機胜が䜿えるようにする nuxt/bridge Nuxtのテストに様々な機胜を提䟛する nuxt/test-utils マヌクダりンファむル(.md)だけでペヌゞ䜜成できる nuxt/content などがありたした。 そしお最埌はNuxt4の方針に぀いお、よりDXをフォヌカスし、オプトむン方匏でたくさんのツヌルを提䟛し、そしおよりオヌプンな開発プロセスを実珟するために倚くの人に参加しおもらいたいず話したした。 お二人の講挔を聞いお、Vue/Nuxtのナヌザヌずしお、開発に携わっおいるみなさんの掻躍を芋お、将来的には䞀人のコントリュビュタヌずしおこのコミュニティヌに貢献したいなず思いたした。 OSS掻動における考え方 本セッションはAnthony Fu氏が、ご自身のOSS掻動に぀いおお話されたした。 たずはご自身がOSS掻動に参加されるきっかけずなった vscode-vue-i18n-ally ずいう゚クステンションに぀いお䟋を挙げたしたが、名前通りVSCodeずいうIDE、Vueずいうフレヌムワヌク、i18nずいう機胜を利甚する人のためのアクセサビリティヌツヌルであり、そう考えるず実はタヌゲットナヌザヌはかなり限定されおしたうこずになりたす。それではより倚くの人に䜿っおもらえるにはどうしたらいいでしょうか。 Anthonyさんは察象ずなる二぀のアプロヌチを玹介したした、䞀぀はツヌルそのものの利甚制限をなくすこずです。䟋えば、 vscode-vue-i18n-ally に戻るず、Vue以倖のフレヌムワヌクも䜿えるようにすれば、利甚できるナヌザヌが自然に増えるこずになりたす。その結果が i18n-ally です私の知っおいる限りこちらもVSCode甚の゚クステンションですが。そしおもう䞀぀はの方法は耇数のツヌルでツヌルのナニオンを結成するこずです。䟋えば、Nuxtの呚蟺には倚くのサポヌトツヌルがあり、それぞれを必芁ずするナヌザヌが䞀定数いたす。このようなナニオンがあれば、ナヌザヌは必芁なツヌルを䜿い、それだけで倧きい開発コミュニティを䜜るこずができたす。この二぀のアプロヌチは利甚ナヌザヌを増やすだけでなく、利甚ナヌザヌが増えたこずによっお、最終的にコントリュビュタヌも増えるずいう効果が期埅されたす。 圌の話を聞いお、ただOSS掻動に携わったこずがない自分から芋るず、OSSにも普通のプロダクトず同じく、ナヌザヌ獲埗ずいう抂念があっお、より倚くのナヌザヌに䜿っおもらえるようにはどうしたらいいか垞に考えないずいけないなず思いたした。 質問コヌナヌ 最埌のセッションはEvanさん、SebastianさんずDanielさんに色々質問を答えおもらうセッションでした。1時間なのに、事前にみなさんから投げた質問が倚すぎお結局䞀郚しか答えられなかったが、その䞭には特に印象に残ったのが以䞋4぀でした。 Q: サヌバヌサむドコンポヌネントに぀いおどう思うか A: 結局StaticはStaticのよさがあるので、自分のニヌズに合うのを䜿えばいいが、サヌバヌサむドコンポヌネントを利甚した方がいい䟋を䞀぀挙げるずしたら、ECサむトでしょう。 Q: Vue, Nuxt, Vuetifyをたずめお2から3にマむグレむションするのが倧倉で、やり方を教えお欲しい。 A: たずこんなに倧倉になるのは完党に私のせいですね、そこは申し蚳ない笑 䞀぀のやり方ずしおは、スクラッチから別のプロゞェクトを立ち䞊げお、少しず぀移行しおいくのがよいでしょう。 Q: Nuxtにずっおのいいコンポヌネントのデザむンパタヌンはあるのか A: 特にない、Vueを䜜った時はAngularがプレれンタヌパタヌンを利甚しおたが、パタヌンに瞛られたくないずいう思いがあったからこそ今のVueなので、こちらに関しおもたずは小さく開発し、ちょっずず぀どんなパタヌンがいいか決めおいけばいいでしょう。 Q: VueのNativeアプリ察応に぀いおの予定を教えおください。 A: 今のチヌムだず察応する䜙裕がたったくない、たぶん数倍くらいのリ゜ヌスが必芁。IonicやNativeScriptを利甚するずいいのではないでしょうか。 アフタヌパヌティヌ アフタヌパヌティヌは立食圢匏で、協賛によっお掋食ず寿叞が提䟛されたした。 自分はかなり内向的な性栌でい぀もパヌティヌなどでこちらから声をかけるこずを躊躇っおいたすが、勇気を持っお最埌の最埌に来日しおくださったEvanさんをはじめずするコアチヌムメンバヌに声をかけおみお、色々話せおよかったです䞭にはAnthonyさんに初めおオヌプン゜ヌス開発で色々䞍安を持っおいる方ぞのアドバむスに぀いお聞いおみたずころ、「1. たずは小さいツヌルからスタヌトしおみるこず、2. ずにかく勇気を持぀こず」を語っおくれたしたが、これを聞いた私からするずすぐ玍埗いきたしたね。 感想たずめ 正盎に蚀うず、初めおVueずNuxtのコミュニティむベントに参加し、ずおも楜しかったですが、それより䞀番思ったこずはやはりOSSコントリュビュタヌはやはりすごいずいうこずでした。VueずNuxtのコアチヌムはさほど倧きくないからこそ、しっかりやるこずを制限質疑応答にあったVue Nativeをやらないず決めるこずなどしたこずず、䜜ったツヌルをVueだけではなく、他のフレヌムワヌクにも恩恵受けるにはどうしたらいいかを考えるマむンドセットを持たれおいお尊敬しかありたせん。 来幎はどんな圢であろうが、たたVue Fes Japanに参加したいず思いたす
Introduction Hello! I’m Kin-chan from the Development Support Division at KINTO Technologies. It might seem sudden, but on Thursday, August 3rd, we’ll be hosting our very first KINTO Technologies MeetUp! - 4 Case Studies by and for Corporate IT Teams . This event will focus on the corporate IT domain and take the form of case study presentations followed by a roundtable discussion. In this article, I’d like to share the behind-the-scenes story of how we got this study session off the ground. If you’re someone who’s thinking, "I want to start and lead a study session from scratch," I hope this will be helpful and encouraging. What Comes to Mind When You Hear "Study Session"? It might be a bit sudden, but what comes to mind when you hear the term "study session"? Listening to experts in your field and gaining new insights Getting together with others who share your interests to learn and grow together Joining as part of your job, perhaps even being expected to attend, in the name of team skill-building (Though less common during COVID) Participating mainly for the conversations and food at the social gatherings As you can see, study sessions can serve many different purposes and come in many forms. When I think about what a study session means to me, I’m reminded of a community I once helped organize called " DevLOVE ." The concept behind it was to create a "learning space" where knowledge and experience could flow between the workplace and the outside world—to help move our teams and organizations forward. Having always seen value in study groups and communities like this, I joined KINTO Technologies hoping to get involved in opportunities to share and learn within the company. *I’ll go into more detail about how this mindset turned into concrete action in a future post in our "Agile Series." Okay, Then Let's Have a Study Session When I joined KINTO Technologies, I found that the company already had a strong culture of holding regular study sessions and offering many opportunities for learning. For example: Optional company-wide study sessions for engineers Business-focused sessions hosted by business divisions to deepen understanding of our operations Small group study sessions and book clubs organized within each product team What impressed me most was the supportive culture that encouraged participation in study sessions and book clubs—both inside and outside the company—as part of regular work. There’s even a system in place that covers the cost of books needed for learning. It was clear to me that KINTO Technologies genuinely supports its employees' development. In this environment, I started holding small study sessions and group reading sessions for my own team, spending my days learning alongside my colleagues. And somewhere in the back of my mind, I kept thinking, "I wish more people knew about this culture." One day, a discussion came up in our team about how we could better recruit corporate engineers. As we explored various ideas, one thought kept coming back to me: "How can we showcase our strengths and this great culture to more people?" The challenge naturally connected with my earlier desire to share our company’s learning culture more widely. As a result, we came up with the idea: "Why not hold a study session that includes people from outside the company?" I Can't Do This Alone! Help Me Everyone! With that spark, I quickly drafted a "Proposal for a Corporate IT Study Session" and shared it with our team leaders as a formal idea. Each leader gave it a "thumbs-up." That gave us a green light to move forward, but saying "let's do it" was only the beginning. There was still a lot to figure out: What would the theme be? Who would present? Where would it take place? When should we hold it? What would the timetable look like? It was clear that I couldn’t handle all this alone. So the following week, during the full team meeting, I made an announcement: " We’re going to hold a study session! We’re looking for members to join as organizers and speakers! " In the end, a team of six was formed, including volunteers and recommended members! We immediately created a dedicated channel on Slack and began communicating with all the relevant members. To make sure everyone was aligned on the goal, we kicked things off with an internal meeting for the organizing team. Since not everyone had been involved from the initial planning stage, we focused on a few key areas: What is the purpose of the event, and what will it look like? What is the goal state we’re aiming to reach? What has already been decided, and what still needs to be figured out to reach our goal? How will we resolve the unsolved issues? We began by clearly aligning our "goals" and "understanding of the current status." Then, we set the "next milestone to aim for," and each member began preparations. We Can't Do All by Ourselves!! We Need More Help! The next step was for the organizing team to discuss the unresolved topics. We broke it down into five major areas: Content Format and equipment needs Date and timetable Promotion and outreach How to measure success We held in-depth discussions to clarify each point. As we worked through these, we identified what we could manage ourselves and what would require cooperation from other departments. Based on this, we began setting up meetings that included key stakeholders from other teams. *Once the decision to hold the study session was made, our manager had already started reaching out to divisions that might be needed for support. Thanks to that early communication, we were able to smoothly hold a company-wide kickoff meeting. Thankfully, many of the people who participated in the joint kickoff were very positive. In response to our ideas, they offered suggestions like, "How about trying this?" and "We’ve done something similar before, so it can be handled quickly." Their input helped us get closer to our goal. We Need Flexible Yet Transparent Project Management! As our plans became clearer, a number of concrete action items began to emerge in parallel. We realized that if we simply relied on "whoever could handle it" to take things on as they came, it would be difficult to keep track of progress. In other words, transparency would suffer. To avoid that, we decided to define a certain level of visualizing, progress tracking, and role assignments. Visualizing We used Jira to make tasks visible and prioritize them in a structured way using the "Epic > Task" hierarchy Progress Management We set weekly goals at the Epic level. Each week, we reviewed our progress and adjusted course as needed. If all went well, we would then set the next goal. Division of Roles We assigned responsibility for each Epic. If someone was falling behind or having trouble reaching their weekly goal, others would step in to help. This approach helped us achieve iterative, incremental progress in managing the organizing team. [Side Note] How We Applied "Agile Kata" to Run the Organizing Team As a quick aside, the way we approached organizing this event was inspired by the concept of the " Agile Kata ," particularly its idea of "Improvement Kata." According to "Agile Kata," you can apply agile thinking in your daily work by repeating the following steps: Understand the direction and challenges Grasp the current situation Set the next target state Experiment toward that target in an iterative way Even without relying on a fixed framework like Scrum, you can create an agile way of working simply by applying the Kata mindset. And Right Now... Even as I write this article, the discussions and actions needed for the study session are moving forward every single day, bringing us closer to the goal. We’re holding synchronous web meetings by topic, and Slack is buzzing with asynchronous conversations—some threads get more than 50 replies in a single day. It really feels like things are progressing quickly. Everyone’s doing an incredible job!! With preparations steadily taking shape, the " KINTO Technologies MeetUp! - 4 Case Studies by and for Corporate IT Teams " is finally within reach. Please look forward to the event!!
Introduction My name is Zume and I am the Quality Assurance (QA) Group Manager at KINTO Technologies. I'm a lifelong cat lover. Cats truly make everything better. There’s something special about their pure, honest nature. In this article, I’d like to introduce the role and responsibilities of our QA Group. About the QA Group The QA Group is primarily responsible for pre-release verification of various services at KINTO Technologies. Our mission is to improve the overall quality of the products we provide and take the lead in QA initiatives. Current Activities Until recently, our QA efforts mainly focused on domestic products like KINTO ONE (New Vehicle and Used Vehicle). However, KINTO Technologies also has a global development group, so we are now also involved in overseas product projects. We also offer an app called Warikan KINTO, which is developed in collaboration with a Swedish company. As a result, our QA communication for this project is conducted in English. In terms of the development process, our QA work corresponds to the system testing phase, which is paired with requirements definition in the V-shaped model. Our QA testing generally includes the following: Verifying that functions and performance meet requirements. Identifying and eliminating bugs and risks. Confirming that the product meets the release quality standards. At KINTO Technologies, User Acceptance Testing (UAT) is carried out by the business side, QA work involves a series of processes, from test planning, design, implementation, reporting defects, to checking modifications, and reporting release decisions after testing is complete. Depending on the project, QA does not only participate after development is complete, but rather participates from the requirements definition phase. The aim is to understand both business and system requirements at an early stage. The QA Group is also the only division that has the unique ability to perform cross-functional testing across different systems. Therefore, from our QA perspective, we aim to raise any concerns in advance so that we can resolve them at the earliest stage. After each release, we hold internal retrospectives, and participate in overall project reviews where we identify trends in defects and propose improvements. These efforts help ensure smoother progress in future projects. If you’re interested in an overview of our QA work, our team member okapi has written another article , so I’d appreciate it if you took a look as well! Group Members, Atmosphere, and Work Style There are currently nine members in the QA Group, including myself. As our team becomes more international, English proficiency is becoming increasingly valuable. While not strictly required, the ability to communicate in English can open up additional opportunities. Each of us has our own areas of expertise, such as apps or web, but we structure the team so that everyone can handle any product as needed. Our members vary in age, and the gender ratio is roughly 50/50. We don’t rely solely on Slack or Zoom. In fact, we often come to the office and talk face-to-face more than online. We also keep a dedicated Zoom room open all day, so whether you’re working remotely or in the office, there’s always someone you can talk to. Since we work with external partner companies, we frequently use Zoom breakout rooms for meetings. To keep the communication flowing smoothly within the team, we hold morning meetings at the start of the day, an evening wrap-up meeting, and a weekly team meeting. While some members work from home depending on the day, most meetings are held via Zoom. However, our weekly team meetings are usually held in person. We also hold study sessions from time to time to help improve team members’ skills. These are not regular events, but we organize them as needed. For now, the main focus is on deepening our understanding of services and system specifications. In the field of testing, the Foundation Level certification defined by ISTQB is generally considered a basic qualification. However, we do not require it as long as you have equivalent experience and skills. In fact, having a certificate alone is not enough. What really matters is how well you can apply that knowledge in practice. That’s why we place greater value on hands-on QA experience, such as the types of projects you’ve worked on and the specific roles you played, as well as your practical skills. This applies to engineers in general, and QA engineers are no exception. Strong problem-solving skills are essential. Future Outlook In our QA Group, we have been working on test automation for some time now. Currently, automation is limited to certain areas and only covers the web, but in the future we would like to expand it to the mobile (native apps) area as well. We hope to share more about the tools we use, and those we’re considering, in a future post. Since everything we work on is car-related, if you enjoy cars, whether driving or just looking at them you'll likely find it even more enjoyable. Personally, I’ve been driving and owning cars for quite a long time, and I still enjoy learning new things and making unexpected discoveries every day. The QA Group also plays the role of the final checkpoint to ensure product quality before it reaches our customers. At the same time, we’re also the team that gets to experience new services before anyone else. If you find that rewarding and interesting, we would love for you to join us.
Introduction Hello, we're Yao Xie and Mooseok Bahng, who work on mobile app development in the Global Group at KINTO Technologies. We're currently working on an app called Global KINTO App . The Global KINTO App (GKA) was built with the goal of connecting together KINTO services all over the world with a single app. So far, KINTO services have been deployed in Thailand and Qatar. While working on a project destined to replace an existing app, we decided to adopt Kotlin Multiplatform Mobile (KMM). So, we're going to talk about that. Background on why we decided to adopt KMM There were a few issues that lead to our decision to adopt KMM. - No matter what we did, differences always arose in the business logic between iOS and Android. - The development team is physically split between 2 locations, which can impact development efficiency. -> We thought we could improve things by dividing the team into KMM and native. - Our development resources are limited, so we want to create an efficient development system. Based on these, we started to consider KMM. What is Kotlin Multiplatform Mobile (KMM)? An SDK for developing iOS and Android apps, KMM uses Kotlin as its base language, and offers the benefits of both cross-platform and native apps. You can develop a common business logic using KMM, then develop the platform-dependent UI elements natively. We personally think that it's best to provide the optimal UI/UX for each OS. With KMM, you basically develop each UI natively, so the UI/UX can be optimized with little dependence on iOS and Android, and we also think version upgrades are going to have virtually no impact. KMM is still a new technology and isn't very mature, but it's been getting used more and more by various companies in recent years. Kotlin Multiplatform Mobile (source: https://kotlinlang.org/lp/mobile ) Architecture Before we talk about KMM, let's talk about the architecture currently being used by the development team. In short, we develop using an MVVM pattern. This policy basically won't change even though we're adopting KMM. At this point, we were wondering just how much we should include in KMM. There are around three options. KMM Native Option 1 Repository, Usecase, View Model UI Option 2 Repository, Usecase View Model, UI Option 3 Repository Usecase, View Model, UI We tried various approaches, but for now, we're moving in the direction of using KMM up to the view model. We also considered leaving out the view model, but couldn't find any good reasons for handling it separately despite making the effort of adopting KMM. This is especially true for simple features like displaying data in a list. Maybe we'll need to do the view model separately as more complex features get added. When that happens, it should be possible to do just some parts of it separately. The codebase for iOS is now pretty compact. We're using KMM up to the domain layer and view model, so there's only UI- and platform-dependent hardware-related features, and we think it'll probably amount to at most half as much source code as before. Here's some iOS code for a simple screen with an FAQ list. Apart from a common UI Utility class, this is all we need. swift struct FaqView: View { private let viewModel = FaqViewModel() @State var state: FaqContractState init() { state = viewModel.createInitialState() } var body: some View { NavigationView { listView() } .onAppear { viewModel.uiState.collect(collector: Collector<FaqContractState> { self.state = $0 } ) { possibleError in print("finished with possible error") } } } private func listView() -> AnyView { manageResourceState( resourceState: state.uiState, successView: { data in guard let list = data as? [Faq] else { return AnyView(Text("error")) } return AnyView( List { ForEach(list, id: \.self) { item in Text(item.description) } } ) }, onTryAgain: { viewModel.setEvent(event: FaqContractEvent.Retry()) }, onCheckAgain: { viewModel.setEvent(event: FaqContractEvent.Retry()) } ) } } Pros Single codebase We can manage iOS and Android networking, data storage, business logic, and more with a single codebase. Consistency Having a common business logic means we can basically provide the same UX. Efficiency Adopting KMM has enabled us to do development work more efficiently. Cutting our time costs almost in half means we're getting to spend that much longer on source code optimization and business deployment. Expandability We can easily expand development as needed to include other platforms besides iOS and Android. Cons For iOS debugging, you need to install a separate plugin. If you use XCframework, using Simulator on an Apple Silicon Mac results in an error because it references arm64. We think this will need to be fixed on the KMM SDK side, but for the time being, we can use Simulator either by adding arm64 to the excluded architecture, or running Xcode in Rosetta mode. Distribution method for iOS Build & Sourcesets Build XCFrameworks Up to now, distributing KMM to iOS has basically been done with a Universal (FAT) framework. Official support for XCFramework has finally come out recently, so we're planning to go with that. https://kotlinlang.org/docs/multiplatform-build-native-binaries.html#build-xcframeworks Other They're not directly related to KMM, but here are some other new technologies we're also thinking of adopting: Ktor You can use the same settings for both clients. The API Request code is the same. The engines for iOS and Android are separate, but no additional code is required. Apollo Client We're also using some of the GraphQL API in some of existing projects. We're thinking of adopting the Apollo Client in order to use GraphQL. You just need to create Queries.graphql using schema.graphqls in the backend, and Models, Adapters, and Queries will all get created automatically. https://github.com/apollographql/apollo-kotlin MMKV MMKV is a mobile key-value storage framework. It supports multiple platforms, including Android and iOS of course. https://github.com/Tencent/MMKV https://github.com/ctripcorp/mmkv-kotlin With MMKV-Kotlin, we can easily integrate MMKV into our projects and manage key-value storage with a shared module. Performance comparison on Android Performance comparison on iOS Future developments Fast growing KMM ecosystems KMM is being developed by Jetbrains. It can be used seamlessly with Android Studio and has some Xcode support as well. It's spreading among developers, and there are a lot of open source libraries for it. https://github.com/terrakok/kmm-awesome Cross-platform UI Touchlab has already started experimenting with using Compose UI for both iOS and Android. https://touchlab.co/compose-ui-for-ios/ @Composable internal actual fun PlatformSpecificSettingsView(viewModel: SettingsViewModel) { IconTextSwitchRow( text = "Use compose for iOS", image = Icons.Default.Aod, checked = viewModel.observeUseCompose, ) Divider() } KMM may start to officially support cross-platform UIs in the near future. Summary In this article, we talked about how we've adopted KMM. We're now expecting it to bring the following improvements: - Being able to minimize the business logic gap between iOS and Android - Being able to optimize the development team structure if required - Reducing the development time to a certain extent We're still in the early stages of adopting KMM and are going to face lots of issues and steadily build up our know-how, so we'll share more once we've made some more progress. Thank you for reading.
はじめに こんにちはKINTOテクノロゞヌズの開発支揎郚に所属する「きんちゃん」です。 普段はコヌポレヌト゚ンゞニアずしお「党瀟利甚するITシステムの維持管理」を行っおいたす。 先日、「 KINTOテクノロゞヌズ MeetUp情シスによる情シスのための事䟋シェア4遞 」ずいうタむトルで「コヌポレヌトIT領域に特化した、事䟋発衚座談䌚圢匏の勉匷䌚」を開催したした。 今回は、その勉匷䌚で事䟋発衚した内容に぀いお、補足を亀えながらテックブログ䞊で玹介したす。 発衚資料 圓日の発衚資料党䜓に぀いおは、以䞋を参照ください。 【アジャむルなSaaS導入】最小工数お゙玠早く最倧の成果を生む秘蚣 ここから先は、実際に発衚で利甚したスラむドず共に、資料だけでは分かりづらい郚分の補足や、䌚堎ではお話できなかった郚分に぀いお、色々ず補足しおいきたす。 タむトルの遞定 さっそくですが、このタむトルです。 「アゞャむル」ずいうキヌワヌドに぀いおは、倚くの方が色々な解釈を持たれおおり、発衚のタむトルずしお利甚するのは、なかなか悩むずころです。 ただ、僕の発衚を聎いおくださった/芋おくださった誰かが「あ、こういうのもアゞャむルなんだ」「そんなに難しい話じゃないな」ずいった気づきを埗お、それがその人の新たな行動の埌抌しになれば、ず考えお「アゞャむル」を利甚したした。 ※もちろんキヌワヌドずしお「惹きがある」ずいう点もポむントでした。 話すこず/話さないこず タむトルで「アゞャむル」のキヌワヌドを䜿ったからには、やはりメむンで䌝える内容は「アゞャむル゜フトりェア開発における䟡倀」にリンクできるず良いなず思ったので、このような内容にフォヌカスしおいたす。 もし「もっず詳しい導入プロセスや、プロゞェクトの途䞭で起きた地味な話を聎いおみたいよ」ずいう方がいらっしゃれば、ぜひKINTOテクノロゞヌズぞのJoinをご怜蚎ください。 背景 たずはITチヌムから導入を開始したITSMIT Service Management≒問合せ/䟝頌管理ツヌルですが、それなりにスムヌズな導入ができた背景もあり、IT以倖の管理郚門にも導入したしょうずいう流れができたした。 その流れができるたでは、瀟内であたり「IT以倖の管理郚門」に接する機䌚はありたせんでした。 僕自身、前職以前を含めお過去に倚くの非IT郚門の方々ずのプロゞェクト経隓があったため、このプロゞェクト掚進の指名をもらった時は、過去の経隓が掻かせるず感じたため、嬉しかった蚘憶です。 「ある皋床のゎヌルむメヌゞはあるものの、具䜓的な芁件や機胜に぀いおは定たっおおらず、ずは蚀えなるべく工数はかけずに勝ちを埗たい」ずいう背景から、「カッチリず芁件を決めおフェヌズを切った導入≒りォヌタヌフォヌル」よりも、「最小限の䟡倀を䜜り蟌みながら、察話ず軌道修正を繰り返す導入≒アゞャむル」の方が適しおいる、ず刀断したものになりたす。 このスラむドでは「アゞャむルに進めるず良いんじゃなヌい」ず、あたかもプロゞェクト開始時点から考えおいたように芋られたすが、実際には「どういうふうに進めようかなヌ。ずりあえず関係者の人たちに話を聎くずころからだなヌ」くらいの感芚でした。 実際には、管理郚門の方々ずのヒアリングを経た䞊で、「この人たちずなら、このスタむルで進められそう」ずいう感芚を埗たため、埌述の「アゞャむルな進め方」に螏み切った圢です。 アゞャむルに぀いお 僕は、瀟内で「アゞャむルっおなんですか」っお聞かれた時に「短い期間でカむれンを繰り返しながら、䟡倀にフォヌカスした仕事を進められおいる状態です」みたいな回答をしおいたす。 ゜フトりェア開発に觊れおいる方であれば「アゞャむル゜フトりェア開発宣蚀の䟡倀ず原則」は分かりやすいですが、そこにピンず来ない人もいたす。 最近では「アゞャむルのカタ」ずいう文曞も公開されたり、非IT向けのアゞャむル曞籍も発売されたり、色々ず説明しやすくなっおきたな、ずいう感芚がありたす。 プロゞェクトの進行に぀いお ここからのスラむドに぀いおは、できるだけ「アゞャむル゜フトりェア開発宣蚀における䟡倀」にリンクする圢で「どこがアゞャむルなのか」を説明できるように心がけたした。 このスラむドで䌝えたかった事は、「なるべく無駄なコミュニケヌションを枛らし、本質的な䌚話にすぐ入れるようにするための仕掛けづくり」です。 良くある゜フトりェア開発の堎合は、「今どのような業務をおこなっおいるのか」を探玢する工皋や、「䜕をやりたいか」を明らかにしおいく工皋がありたす。 今回は「ある皋床のカタが決たったSaaSの導入」であるため、「今の業務を元に芁件を定めおいく」よりも、「カタを前提にした、良い䜿い方」を暡玢しおいく方が適切ず考えたした。 たた、ロヌコヌドツヌルの匷みずしお、初期段階での「䜜っお壊しお䜜り盎す」のコストが圧倒的に䜎い事もあり、「初回の打ち合わせ前に、最小限の䟡倀が提䟛できるプロトタむプを䜜る」事も容易に進められたした。 結果ずしお、初回の打ち合わせで「さぁ、どんなものを䜜りたいですか」ずいう䌚話を始めるのではなく、「こういう䜿い方のシステムだずどうでしょう䜕かおかしなずころはありたすか」ずいった、具䜓的な動くものを察象にした議論からスタヌトできるようになりたした。 これらは、アゞャむル゜フトりェア開発宣蚀でいうずころの以䞋の䟡倀にフォヌカスした点ずなりたす。 プロセスやツヌルよりも個人ず察話を 包括的なドキュメントよりも動く゜フトりェアを このスラむドで䌝えたかった事は、「短い間隔で䟡倀を䜜り蟌み、フィヌドバックを埗お、玍埗の行くシステムを提䟛するための仕掛けづくり」です。 打ち合わせで良くあるものずしお「持ち垰り怜蚎」がありたす。䟋えば「どういうメニュヌ構成が良いか怜蚎しおくる」「どういう凊理フロヌが良いか怜蚎しおくる」ずいったものです。 今回は、そのような「持ち垰り怜蚎」を「盞手にお任せ」するのではなく、「持ち垰り怜蚎の堎に、自分がゲストずしお参加させおもらう」方法を取りたした。 そうする事で、䌚話の䞭で出た質問や懞念・違和感ずいったものを即座に受け止め、玠早く回答したり、その堎でシステムの改修に手を぀ける事もできるようになりたす。 結果ずしお、「持ち垰り怜蚎の堎」であるにも関わらず、「怜蚎を螏たえた仕様倉曎ず、実際の機胜改修」たでも進めおしたえるようになりたした。 たた「ここで倧きな仕様倉曎が出た」ずありたすが、ある意味「䜜り盎し」をした方が良い状況になりたした。もちろん、これたで䜜ったものを捚おる事になりたすが、議論の堎に僕も参加しおいた事で「䜜り倉える事の必芁性ず䟡倀」に぀いお十分に玍埗した䞊で、その遞択を取る事ができたした。 これらは、アゞャむル゜フトりェア開発宣蚀でいうずころの以䞋の䟡倀にフォヌカスした点ずなりたす。 契玄亀枉よりも顧客ずの協調を 蚈画に埓うこずよりも倉化ぞの察応を プロゞェクトを終えおみお 今回のプロゞェクトを通じお、僕が倧きく埗られたず感じるものは「信頌関係」です。 あくたでも僕からの䞀方的な意芋ではありたすが、「この人たちず䞀緒に仕事をするず、良い結果が埗られる」「次も䜕かあったら盞談しおみたい」ず思っおもらえるようなきっかけづくりに貢献できたのではないか、ず感じおいたす。 今回の䟋にあるような「アゞャむルな取り組み方」でなくおも、もちろん良い結果を産めるような進め方は倚くあるず考えおいたす。 ただ、䜕か進め方に困った堎合は、「アゞャむル」が持぀䟡倀を参考に、自分の行動をちょっずだけ倉えおみる事をオススメしたす。 ありたい姿を描き、そこに向かっおちょっずだけ行動を倉えおみる ちょっずだけ倉えおみた行動の結果を芳察し、そこから曎にありたい姿を描く たたちょっずだけ行動を倉えおみる この繰り返しができおしたえば、それはもう「アゞャむル」な状態ず蚀えるでしょう。 最埌に 冒頭にも曞きたしたが、今回の事䟋を芋おくださった誰かが「あ、こういうのもアゞャむルなんだ」「そんなに難しい話じゃないな」ずいった気づきを埗お、それが次の新たな行動の埌抌しになれば、幞いです。
Introduction Hello, everyone. T.S. here, a corporate engineer in the KINTO Technologies IT Management Team. We have an IT Management Team info page here , so please take a look at that, too. In the IT Management Team, we're working hard every day to provide an IT environment that can raise the productivity of the engineering organization that is KINTO Technologies. Our internal IT environment is composed of various elements and it'd be difficult to cover everything all in one go, so in this article, I'm going to focus on device management. What is device management? Premise At KINTO Technologies, every staff member is loaned a set that includes the following: A laptop (Windows or Mac) A smartphone So, if we can understand and manage things like who the devices are being used by and what condition they're in, it'll be easier to support a pleasant development environment. What is MDM? As the premise states, all staff are using mobile devices. So, we've introduced Mobile Device Management tools. That’s right. They're generally called things like "MDM tools." What can you do with it? Essentially, MDM means tools for managing and operating mobile devices like laptops, smartphones, and tablets — e.g., managing their settings and app distribution. I imagine a lot of you might be thinking, "If that's all it's about, why do you need to work so hard to manage them?" But... KINTO Technologies doesn't have them on-site So, in terms of the SaaS* used on a daily basis for work, deciding whether devices can be trusted (i.e., are managed by the company) is a critical security issue. However, in order to make sure the development environment is always convenient as well as very secure, we need to think very carefully about which aspects of the devices we should manage, and which should be left to the users. SaaS = Software as a Service: Services that are installed on clients and used via networks such as the Internet. In terms of deciding which device aspects should be managed, which should be left up to the users, and how to not compromise convenience as a result, we pictured something like this: Seems like these should be managed Would be nice if these didn't have to be Behavior of security-related tools ・ Data leakage measures ・ Means of erasing data if the device is lost, etc. ・ Communicating with improper connection destinations ・ Asset management Applications needed for work ・ User-specific environment settings ・ Keyboards, mice, and other peripherals ・ Physical device storage and management KINTO Technologies' device management Overview The upshot is that this is what KINTO Technologies' MDM consists of: Item Service used IdP(※) Azure Active Directory Windows devices Smartphones Microsoft Intune Mac devices Jamf Pro IdP = Identity Provider: A mechanism for providing authentication services and managing account information. Challenges KINTO Technologies is in a rapid-growth phase, so lots of new staff are joining it every month. That means the number of devices is increasing at the same rate as the employees, so it's going to be extremely tough to manage them through human labor alone. So, we ended up systematizing our device management approach to solve the following issues: Time spent on device kitting Managing device information Managing application installation Controlling OS update cycles Applying encryption and managing recovery keys Remote locking and remote wiping The system we introduced Thinking about the work environment again... Work environment PCs -> Choice of Windows or Mac Smartphones -> Issued to all staff Environment -> Fully cloud-based Groupware -> Microsoft 365 Based on this, for Windows devices and smartphones, we adopted Azure Active Directory and Microsoft Intune, which are highly compatible with Microsoft 365. We could have said, "Let's manage Macs with Microsoft Intune as well, and have a fully unified MDM platform!" However, we decided to go with Jamf Pro instead, because it has a great track record with Apple products, and boasts quick syncing of settings and good flexibility in terms of management policies and items. Here's what our device management looks like: Overview of our device management Results No. Item Result 1 Time spent on device kitting → The time spent on kitting (including configuring settings) has gone down. △ 2 Managing device information → Goodbye ledgers, hello management consoles ○ 3 Managing application installation → Has changed from separate to centralized management △ 4 Controlling OS update cycles → Has changed from being the device users' responsibility to being managed centrally ○ 5 Applying encryption and managing recovery keys → Has changed from being done device by device to system-based management. We're especially glad to now have systemic key management! ○ 6 Remote locking and remote wiping → We can do them now! ○ The above results mean that we've more or less cleared the initial challenges, and should finally be able to say that we're at the starting line of device management. We want to go on improving our device management operations in order to deliver an ever better experience to all staff. Things we want to do in the future 1. Zero-touch kitting We'd like to consolidate the kitting requirements, etc., achieve zero-touch kitting, and reduce the amount onboarding time spent on the devices so that more of it can be spent on actual work. 2. Streamlining application-related operations We've achieved centralized management, but we'd like to refine these operations further so that we can respond to users in a more flexible and timely manner. 3. Managing the condition of devices We'd like to achieve detailed control and operations that address the condition of devices in (e.g.) inventory as well as of ones registered with the MDM, so that the devices can be kept in better condition. In conclusion Thank you for reading my article all the way to the end. I will continue to work hard to create an in-house IT environment that can contribute to the whole company and its business. We are hiring! KINTO Technologies is looking for people to work with us to create the future of mobility together. We also conduct informal interviews, so please feel free to contact us if you are interested. https://www.kinto-technologies.com/recruit/