every Tech Blog

株式会社エブリーのTech Blogです。

誰でもわかるStoreKitTesting

誰でもわかるStoreKitTesting

f:id:kai_ios:20210304143718p:plain

はじめに

はじめまして。エブリーでiOSエンジニアをしている佐藤です。

DELISH KITCHENで、主にプレミアムサービスや課金周りを担当しています。

今回は、WWDC2020で発表されたStoreKitTestingについて紹介したいと思います。

概要

概要としては以下が挙げられるかと思います。

  • AppleStoreサーバに接続せずにローカル課金テストができる
  • ローカルでテスト商品を作れる
  • 購入トランザクションの管理ができる
  • 割引系(お試しオファー、プロモーションオファーなど)のデバッグが可能
  • プロモーションオファーはローカルの秘密鍵を作成可能
  • レシートはローカルで署名されている
  • 課金のユニットテストが可能

ローカルで実行できる課金環境がとても充実してきていますね。

次にStoreKitTestingの導入の流れを簡単に説明していきたいと思います。

Configurationファイルを作成

まずはNew FileでStoreKit Configuration Fileを選択し、作成します。 f:id:kai_ios:20210304143646p:plain

次にサブスクリプショングループを作成します。 f:id:kai_ios:20210304143653p:plain

次に課金商品を作成していきます。 選べるのは以下の3つ。

  • 消耗型
  • 非消耗型
  • 自動更新サブスクリプション

f:id:kai_ios:20210304143705p:plain

作成が終わるとこんな画面になります。 f:id:kai_ios:20210304143714p:plain

Product IDや期間などは任意で選択可能です。

オファーの作成

更にStoreKitTestingではAppleが用意している様々な購入オファーの選択も可能です。

そのひとつが、Introductory Offer(お試しオファー)です。

これは初回購入ユーザーに対してアプローチ可能なオファーになります。

選べるのは以下の3つ

  • Pay As You Go(都度払い)
  • Pay Up Front(前払い)
  • Free (無料)

f:id:kai_ios:20210304143701p:plain

2つ目がPromotional Offer(プロモーションオファー)

これは再登録者や継続ユーザーへアプローチ可能なオファーです。 詳しい実装は割愛しますが、AppleStoreConnectで作成した秘密鍵をもとに署名を作成し、StoreKitでの購入時に必要なパラメータを含めると購入可能になります。

詳しい実装方法

StoreKit Testingではローカルで秘密鍵を作成可能で、それをもとに署名を行うことで購入テストが可能になります。

f:id:kai_ios:20210304143650p:plain

残念ながらiOS14から使用可能になったもうひとつのオファーである、オファーコードはStoreKit Testingで使用することはまだできないようです。 参照

Configuration Fileを設定する

Product > Scheme > Edit Scheme > Runを開き、 以下画像のように作成したConfiguration Fileを設定します。

Schemeごとに設定可能なので、 任意のSchemeに作成したConfiguration Fileを設定することでStoreKit Testingでの購入が有効になります。

f:id:kai_ios:20210304143712p:plain

様々なデバッグ

StoreKitTestingでは様々な購入デバッグが可能です。

以下のようなものが設定可能です。

f:id:kai_ios:20210304143643p:plain

  • 既定購入ストアの設定(購入する国別ストアの選択)
  • 既定表示言語
  • タイムレート(購入有効期限の時間短縮率)
  • 購入割込のデバッグ有効化
  • トランザクションを失敗させる(エラー種別も選択可能)
  • 購入確認の表示
  • プロモーションオファーのローカル秘密鍵とKeyIDの生成
  • ローカル証明書の生成(StoreKitTestingでのレシート検証のため)

※選択できるエラー種別

f:id:kai_ios:20210304143708p:plain

またトランザクションの管理も行うことができます。

f:id:kai_ios:20210304143721p:plain

まとめ

StoreKitTestingの設定方法をかんたんにまとめてみましたがいかがだったでしょうか。

今まで開発中は実機でSandboxでの課金テストを行っていましたが、StoreKitTestingによって開発効率は上がったように感じます。 直近ではプロモーションオファー関連の開発デバッグを簡単に行うことが出来、導入のメリットを感じることができました。

課金テストの自動化など安全面でも導入の強みはあるのではないかと思いますので、 まだ未導入の方もしくはIn App Purchase実装の練習をしたい方などはぜひお試しを!

Adobe Premiere Pro エクステンションによるレシピ動画編集の効率化

Adobe Premiere Pro エクステンションによるレシピ動画編集の効率化

はじめに

DELISH KITCHENでは日々多くのレシピ動画を公開していますが、その動画は全てAdobe Premiere Pro(以下 Premiere Pro)を使用して編集しています。

今回はPremiere Proのエクステンションを作成して動画の編集効率を向上させた話をご紹介します。

これまで発生していた問題

レシピ動画にどのような材料を使っているか、どのような工程があるかは全てダッシュボード(データ管理用Webサイト)で管理しています。 動画編集者は動画データをPremiere Proに取り込み、対象レシピの情報をダッシュボードから開き、見比べながら作業していました。

動画にテロップを表示する際には、材料や工程の文章をダッシュボードからPremiere Proにコピペしながら編集作業を行っていました。

f:id:ton1517:20210224142824j:plain
肉巻き半熟卵の動画テロップ例

この作業は地味に時間がかかる上にコピペミスをしやすく、手戻りが発生したりミスが残ったままレシピ動画が公開されてしまうこともありました。

そこで、編集作業の効率化 & ミスの削減のためにPremiere Proのエクステンションを開発しました。

エクステンションの紹介

エクステンションを有効にした状態でPremiere Proを開くと以下のような画面になります。 画像右上のパネルがエクステンションの画面です。 これから編集するレシピの情報が自動的に表示されるため、自分でダッシュボードを開く必要はありません。

f:id:ton1517:20210224142935p:plain
Premiere Proでエクステンションを開いたところ

レシピのタイトルを挿入するときはタイトルの項目にある緑のボタンをタイムラインの好きな位置にドラッグ&ドロップします。 そうすると自動的にDELISH KITCHENで決められたデザインのタイトルテロップが挿入されます。 あとは表示する秒数やデザインを微調整すればタイトルテロップは完成です。

f:id:ton1517:20210224143019p:plain
タイトルテロップをドラッグ&ドロップで挿入

材料も同様に、表示させたい位置にドラッグ&ドロップすれば材料用のテロップが表示されます。

f:id:ton1517:20210224143140p:plain
材料テロップをドラッグ&ドロップで挿入

このようにタイトルや材料などのテロップをドラッグ&ドロップで動画内に挿入できるので、これまでのコピペ作業は必要なくなり、 ポチポチするだけである程度レシピ動画が作れてしまうというのがこのエクステンションの良いところです。

使用している技術

Adobe CEP

このエクステンションはAdobe CEP (Common Extensibility Platform) という技術を用いて作られています。 これはHTML5/JavaScript/Node.jsを使って様々なAdobeソフトウェアのエクステンションを開発できるというものです。

詳しくは以下のGitHubや記事で詳しく解説されています。

エクステンションの画面はChromium Embedded Frameworkというアプリケーションに埋め込んで使用するChromiumフレームワークを用いて表示しているため、 一部制限はありますがほぼ通常のChromeでHTML5/JavaScriptを実行するのと遜色ありません。 またNode.jsが実行できるためローカルファイルの読み書きも行えます。

AdobeソフトウェアのバージョンによってAdobe CEPのバージョンも変わり、それによって使えるAPIやChromium / Node.jsのバージョンも決まってくるため、 事前にサポートするバージョンを確認しておいた方が開発がスムーズになります。

参考: CEP-Resources/CEP 10.0 HTML Extension Cookbook.md at master · Adobe-CEP/CEP-Resources

Nuxt.js

Chromiumの上でHTML5/JavaScriptが実行できるとなると、ほぼWebサイトを作成するのと変わりません。 そのため、このエクステンションはNuxt.jsを使用しています。 (当初は素のVue.jsだったのですが、最近Nuxt.jsにリプレイスしました)

DELISH KITCHEN WEB を構成する技術のお話 でも紹介したように、 DELISH KITCHENのWebサイトにはNuxt.jsを使用しています。またレシピ管理用のダッシュボードでも同様にNuxt.jsを使用しています。

Nuxt.jsはサーバーサイドレンダリング(SSR)が特徴として挙げられがちですが、SSR以外にもページのルーティングルールやコンポーネント、プラグインの設置場所などが全て定められているというのが大きな特徴で、 Nuxt.jsで開発したことのあるWebエンジニアであればすぐにプロジェクトの構成が把握できるのが強みです。 そのためこのエクステンションでもNuxt.jsを使うことによって自分以外のエンジニアがエクステンションを開発する際にもプロジェクト構成の把握が容易になり、 共通のライブラリやプラグインが使用できるため開発がスムーズになります。

工夫した点

編集対象のレシピ情報を自動的に表示する

動画を編集する際に、毎回ダッシュボードから編集対象のレシピを開くのは地味に面倒な作業なので、Premiere Proを開くと自動的にレシピの情報が表示されるようにしました。

仕組みは単純で、以前からレシピ編集のルールとしてPremiere Proのプロジェクトファイルには <レシピID>_<レシピタイトル>.prprojというような命名規則で名前をつけることが決まっていたので、 Premiere ProのAPIでファイル名を取得し、正規表現でレシピIDを抜き出してからDELISH KITCHENのAPIでレシピ情報を取得し表示しています。

ドラッグ&ドロップでテロップを挿入

なるべく直感的にテロップを挿入できるようにしたかったため、ドラッグ&ドロップで挿入できるようにしました。 ドラッグ&ドロップ自体は通常のWebと同じくdragイベントをハンドリングしdataTransfer.setData()でテロップのデータを渡せば良いのですが、setData()の第一引数に渡すformatは"com.adobe.cep.dnd.file.0"という文字列でなければいけません。 (複数データを渡す場合は最後の数字をインクリメントしていく)

参考: Samples/ext.js#L84 Adobe-CEP/Samples

PRTL

ドラッグ&ドロップでテロップを挿入、と言いましたが、実際には何のファイルをドラッグ&ドロップで渡しているかというと、PRTLというフォーマットのファイルを渡しています。 これは現在Premiere Proでレガシータイトルと呼ばれているテロップのフォーマットで、XML形式のファイルになっています。

テンプレートとして使用するPRTLファイルは予めエクステンション内に保存してあり、 材料などのテロップ挿入ボタンがドラッグされた瞬間にテンプレートのPRTLを読み込み、指定された箇所の文字列を材料名で置き換えます。再度PRTLファイルとして書き出した後にdataTransfer.setData()にそのファイルパスを指定すると、 ドロップした場所にそのPRTLファイルがテロップとしてインポートされ表示されるという仕組みです。

余談

Premiere Proにはレガシータイトル以外にもエッセンシャルグラフィックスというテロップの機能があります。 こちらもテンプレートがありAPIでPremiere Proに取り込むことができるのですが、若干扱いづらく、XML形式であることや直感的にドラッグ&ドロップで取り込めるという点でPRTLを採用しました。

ただし、PRTLはフォーマット仕様が公開されておらず(公開されていたらどなたか教えて下さい)、独自にパースする必要があります。 また、Premiere ProでテロップをPRTLファイルとして書き出せるのはCS6までで、それ以降のバージョンでは書き出し機能は削除されてしまいました。 このような状況で、将来的にPremiere Proがレガシータイトルをサポートしなくなる恐れもあるため、できればエッセンシャルグラフィックスを使ってテロップを挿入できるようにしたいところです。

エクステンションのパッケージング

Adobe CEPのエクステンション自体はPremiere Proのエクステンション用のディレクトリに配置すれば使用できるのですが、動画編集をするスタッフに毎回その場所に配置してもらうのも手間がかかります。 そこで、エクステンションをインストーラーでインストールできるようにしました。 全員Mac上でPremiere Proを使用するので、インストーラーとしてpkgファイルを生成します。

パッケージングの詳細や使用したコマンド、npmパッケージなどは以下を参考にしてください。

パッケージングを手動で行うのも面倒なので、GitHub上でPullRequestをmasterにマージした際にCIでパッケージングし、 そのpkgファイルをtcnksm/ghrを使用してGitHub Releasesに自動的にアップロードするようにしました。

これでpkgファイルをGitHub Releasesからダウンロードして開けばMacでおなじみのインストーラーが起動し、エクステンションをインストールできるようになります。

f:id:ton1517:20210224143216p:plain
エクステンションのインストーラー

まとめ

このエクステンションを使うことによってPremiere Pro内でテロップの挿入が完結できるようになりました。 また、ドラッグ&ドロップでテロップを非常に簡単に挿入できるようになり、コピペミスを減らすことができました。 もちろん動画編集作業はこれだけで終わりではないのですが、地味に時間のかかっていた作業を減らすことができ、編集効率を向上させることができました。

このPremiere Proのエクステンションは2018年に作成したものですが、3年弱経った現在も毎日使われています。 自分が作ったものが毎日使ってもらえているというのは開発者冥利に尽きる思いですね。

DELISH KITCHENのサービスも毎日沢山の方に使っていただくため日々開発に励んでいます。

これからもDELISH KITCHENをよろしくお願いします。

MAMADAYS iOSアプリについて

f:id:nanakookada:20210203144149p:plain

はじめに

MAMADAYSにはiOSとAndroidのアプリがあります。 Flutterなどのクロスプラットフォーム開発ではなく、それぞれネイティブで開発しています。

この記事ではMAMADAYSのiOSアプリの全体的な構成を紹介します。 全体の雰囲気を掴んでもらうことを目的とし、細かい採用技術はまた別の機会に紹介できればと思います。

MAMADAYSアプリの機能

MAMADAYSアプリには大きく次のような機能があります。

メディア

MAMADAYSには動画を含む数千本の記事があり、ユーザーさんの状態やお子さんの月齢に合わせて適切な記事をおすすめする仕組みがあります。 リリース当初は記事を WKWebView で表示していましたが、表示速度向上などのためにネイティブに変更しています。 動画再生には AVPlayer を用いていて、自動再生処理や待ち時間短縮のために、それなりに複雑な非同期的な制御が必要になっています。

f:id:nanakookada:20210205173707p:plain

育児記録

お子さんの睡眠や授乳などを簡単な操作で記録し、グラフでわかりやすく振り返ることができる機能です。 この機能のみ、 Firebase Cloud Firestore を利用しています。 Firebase Cloud Firestore の採用には以下のような利点がありました。

  • サーバーの実装が不要
  • クライアントの実装が簡単
  • 非同期通信で待ち時間なし
  • 入力した記録をパートナーにリアルタイムに同期できる

リリース当初の時間が無い中では、工数削減、品質向上に非常に役立ったと思います。 ただし、育児記録機能と他機能の連携を進める上で障害になってきているため、将来的には独自のAPIに置き換えることになりそうです。

f:id:nanakookada:20210205173744p:plain

離乳食

離乳食の進み具合を記録したり、時期にあった調理法を探せる食材リスト機能があります。

f:id:nanakookada:20210205173810p:plain

カレンダー

家族の予定を一つのカレンダーで共有できます。 また、思い出として写真をアップロードし、簡易的なアルバムのようにする機能があります。

パートナー共有

上記全ての機能はデータを家族内で共有できるようになっています。

アーキテクチャー

アーキテクチャーはMVVMとしています。 ただし ViewController から ViewModel の接続はメソッドコール、 ViewModel から ViewController の接続はクロージャーで、Rx等によるバインディングを用いていないので一般的なMVVMとは異なるかもしれません。 Viewはほぼ UITableView で構成されており、Viewの更新は UITableView のリロードですることが多いため、個別のデータをバインディングするメリットを感じなかったためにこのような構成になっています。

また、ViewControllerの階層化を積極的に使っています。 コンテナを使って階層化することによってView Controllerの肥大化を防ぐようにしています。

まとめ

MAMADAYSのモバイルアプリは2019年10月にリリースして以来コンスタントにアップデートを続け、離乳食、カレンダー、妊娠週数と大きめの機能を追加してきました。 今後もユーザーさんの声を聴きながら進化を続けていきます。 開発者としてはコードをできるだけシンプルで変更に強い状態に保つことで、開発速度と品質でサービスに貢献したいと考えています。

Nxを使ってnpm projectをmonorepo管理した話

DELISH KITCHEN RS事業部では、小売向けにサイネージやチラシ等のサービスを提供しています。 従来は、そのサービスの管理が出来るWebアプリのみ運用していたのですが、新たに広告配信設定用のWebアプリが必要になりました。 そこでNxを使って、2つのアプリをmonorepoで管理し、コードの共通化を計りました。

Nxとは

Nxはmonorepo用の拡張可能な開発ツールセットです。堅牢なCLI、キャッシュシステム、依存性管理などを提供すると共に、Jest、Cypress、ESLint、Prettierなどのモダンなライブラリの統合をサポートしています。元GoogleのAngularチームにいたメンバーによって創設されたNrwlが開発しており、Googleは全てのプロジェクトをmonorepoで管理しているという有名な話がありますが(詳細は知りません)、それと似た開発体験を提供することを目的に開発されているそうです。

Nxへの移行

RS事業部で開発しているWebアプリはAngularで作られており、それをまずNxに移行しました。

f:id:yukiya-takagi:20210128142040p:plain
従来のディレクトリ構成

NxはAngularをサポートしているので、移行自体は簡単でした。 まずNxで新しくworkspaceを作成します。

npx create-nx-workspace --preset=angular

その後、既存のアプリのコードをapps以下に配置し、angular.jsonやtsconfig.json、tslint.jsonなどの設定ファイルを修正し、既存のアプリで使用していたサードパーティのライブラリ(dayjsなど)を新しいworkspaceに追加して、移行を完了しました。

f:id:yukiya-takagi:20210128142201p:plain
現在のディレクトリ構成

※ 現在のcreate-nx-workspaceは、テストフレームワークにデフォルトでJestとCypressが選択されており、AngularデフォルトのKarma、Protractorを使用したい場合は、別途以下のコマンドでアプリを作成する必要があります。

nx generate @nrwl/angular:app myapp --unit-test-runner=karma --e2e-test-runner=protractor`

ライブラリの作成

複数のアプリから共通のコードを使用するために、ライブラリを作成します。

nx generate @nrwl/angular:lib shared

上記のコマンドでlibs配下にsharedディレクトリが作成されます。

今回は例としてSampleComponentをライブラリに作成します。

nx generate component sample --project=shared

作成したら、shared.module.tsのexportsにSampleComponentを追加します。 次に、アプリからSampleComponentを使用するために、tsconfigにパスを追加します。

{
  ...
  "compilerOptions": {
    ...
    "paths": {
      "@lib/shared": ["libs/shared/src/index.ts"],
      "@lib/shared/*": ["libs/shared/src/lib/*"]
    },
    ...
  },
  ...
}

あとは使用したいモジュールでimportすると、使用可能になります。

import { SharedModule } from '@lib/shared';

@NgModule({
  imports: [SharedModule],
  bootstrap: [AppComponent]
})
export class AppModule {}

また、直接SampleComponentをimportしたい場合は、以下のコードで可能です。

import { SampleComponent } from '@lib/shared/sample/sample.component.ts'

CSSの共通化

上記で作成したsharedライブラリに共通のCSSも置いて、使えるようにします。 場所はどこでもいいのですが、私はlibs/shared/src/stylesにファイルを配置しています。

html,
body {
  height: 100%;
}

body {
  margin: 0;
  font-family: 'Helvetica Neue', Arial, 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', Meiryo, sans-serif;
}

そしたら、angular.jsonの、このスタイルを適用したいアプリの箇所に以下を追加します。

"app": {
  "projectType": "application",
  ...
  "architect": {
    "build": {
      ...
      "options": {
        ...
        "styles": [
          "libs/shared/src/styles/styles.scss", // この部分
        ],
        ...
      }
    }
  }
}

また、partialファイル(_mixin.scssなど)をsharedに置いて参照することも可能です。 これも好きな場所にファイルを配置して、angular.jsonでパスを指定するだけです。

 "app": {
  "projectType": "application",
  ...
  "architect": {
    "build": {
      ...
      "options": {
        ...
        "stylePreprocessorOptions": {
          "includePaths": ["libs/shared/src/styles/partials"], // この部分
        },
        ...
      }
    }
  }
}

ここで注意なのが、指定するのはファイルパスではなくディレクトリパスということです。こうしておくことで、partials以下にあるファイル(_mixin.scss)を@import 'mixin'という形で使うことができます。

CI/CD

monorepoにするとCI/CD周りも変わってきます。おそらく多くの人が、変更があったアプリ、またはライブラリだけをテスト、デプロイしたいと考えると思います。Nxはその希望を叶えてくれます。Nxにはaffectedコマンドがあり、変更の影響があるプロジェクトのみに対してテスト、ビルドを実行する機能があります。

CI/CDはGithub Actionsで行っていて、実際のワークフローを例に紹介したいと思います。Github ActionsはPull Requestを作った時とdevelopmasterブランチにマージされたタイミングで走るように設定しています。

例えば、Pull Requestを作った時に走らせるビルドは以下のように設定しています。

name: build
on: pull_request
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v1
        with:
          node-version: '12.x'
      - name: Run cache/restore node_modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: v1-${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }}
      - name: Run build
        run: make affected-build BASE=${{ github.event.pull_request.base.sha }} // nx affected:build --base=${BASE} を呼んでるだけ

ここで、affectedはbase optionでブランチやコミットIDを指定でき、baseとHEADの差分から、影響のあるプロジェクトを判断します。その仕様から、actions/checkout@v2ではfetch-depth: 0を指定することで、コミット履歴を全部取得するようにしています。

またmasterにマージされた際のデプロイは以下のように設定しています。

name: deploy
on:
  push:
    branches:
      - master
jobs:
  build:
    ...

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Run cache/restore dist
        uses: actions/cache@v1
        with:
          path: dist
          key: v1-${{ runner.os }}-dist-${{ github.run_number }}
      - name: Run deploy
        run: |
          app_paths="dist/apps/*/"
          if ! ls -d $app_paths &>/dev/null ; then
            exit 0
          fi
          for app_path in $app_paths; do
            app=$(basename "$app_path")
            if [ "$app" == "appName1" ]; then
            elif [ "$app" == "appName2" ]; then
            fi
          done

差分があるもののみデプロイするという仕組みはNx自体にはないので、buildフェーズで生成されたものをデプロイするというスクリプトを書いて対応しています。

現在のデプロイの仕組みだと、masterに入ったものは全部対象になってしまうので、リリース前に全プロジェクトの確認が必要になってしまいます。またmasterに入ってもリリースのタイミングは調整したいこともあるでしょう。monorepoにして一番の課題で、依然他に良いフローがないか検討中の部分です。

まとめ

今回はNxを使ってnpm projectをmonorepo管理した話をしました。Nxを使ったComponentやCSSの共通化、CI/CDの運用とかは普段聞く機会がないので、誰かの参考になれば幸いです。

MAMADAYSのサービスとバックエンドシステムのお話

f:id:nanakookada:20210107145935p:plain

自己紹介

はじめまして && あけましておめでとうございます。MAMADAYS開発部長をやっている齊藤です。

開発部長という肩書きですが、マネージメント業務だけではなく、モバイルアプリ開発以外を守備範囲としたユーティリティプレイヤーもつとめ、若い子たちと一緒に草を生やす作業に勤しんでいます。

座右の銘は『枯れた技術の水平思考』です!

閑話休題

弊社オウンドメディアの every.thing にも、CTOのid:kajidaiとの対談が掲載されていますので、時間に余裕がある方は見ていただけると嬉しいです。

【前編】エブリーCTOが聞く!MAMADAYS開発部長のルーツは音楽!?ゲーム開発から組織づくりにも携わってきたこれまでの経歴とは | every.thing(エブリシング)| エブリーのこと、ぜんぶ

【後編】エブリーCTOが聞く!『MAMADAYS』を主力事業に成長させたい!と語るMAMADAYS開発部長の今後の展望 | every.thing(エブリシング)| エブリーのこと、ぜんぶ

はじめに

App/Webのリリースから1年余りが経過した MAMADAYS の、サービス全体像とバックエンド観点でのシステム紹介を行います。

個々の詳細は、後日、若者たちが書いてくれると思いますが、本記事で少しでも MAMADAYS の開発に興味を持っていただけると幸いです。

MAMADAYSのサービス全体像

mamadays:service

MAMADAYSでは『子育てを通じて喜びと幸せを感じられる社会に』をミッションに掲げ、出産・育児に関する課題を解決するため、プロダクト開発を行っています。

出産・育児の課題は多岐に渡るため、複数の機能を提供する多機能アプリとして展開しつつ、データを活用して1人1人に最適化した情報をお届けできるよう日々改善を重ねています。

corp.every.tv

MAMADAYSのバックエンドシステム全体像

基本的な部分は DELISH KITCHEN と同じような感じにしていますが、以下のようにいくつか異なっている点もあります。

  • コンテナオーケストレーションとして、AWS ECS ではなく Kubernetes (AWS EKS) を利用
  • CI/CDとして、CircleCIではなく github Actions や AWS CodeBuild を利用

リリース時期やサービス規模の違いによりそのタイミングで最適と思う選択であり、どの技術が優れているとかではないです。

利用サービス

mamadays-infra

MAMADAYSで利用している基盤や外部サービスは以下の通りです。

  • インフラ
    • AWS EKS
    • AWS Aurora
    • AWS S3
    • AWS CloudFront
    • AWS Route53
    • Elasticsearch
  • ログ/分析
    • fluentd
    • BigQuery
    • metabase
  • 開発/運用
    • github
    • github Actions
    • AWS CodeBuild
    • terraform
    • kustomize

APIサーバ

iOS/Android/WEBなど、クライアント向けに提供しているAPIサーバです。

DELISH KITCHEN 同様に MAMADAYS でも、Golang の軽量フレームワークである echo を利用しています。

テスト周りでは、私が元々 Rails 厨だったこともあり Rspec っぽい記述ができる GoConvey を利用し、カバレッジも Codecov で計測してたりします。

WEBシステム

mamadays:WEB

WEBにおけるMAMADAYSサービスを提供しています。

記事の入稿やお客様からのお問い合わせに対応するためのツール類も含め、MAMADAYSのWEB面は React のフレームワークであるNext.jsを利用しています。

リリース1年が経過した頃、開発メンバーが増えたこともあり TypeScript 化を行ったのですが、ものすごく手軽に対応できたので Next.js 様様です。 『もしかして:Nuxt.js』と毎回問われてしまうぐらいググラビリティが低く、検索するたびに悲しい気分になりますが、それはそれで愛おしいです。

検索システム

mamadays-search

記事/動画情報の検索を提供するサーバです。

検索エンジンには Elasticsearch を利用しています。

元々は使用したいプラグインが対応されていなかったため独自運用していたのですが、AWS Elasticsearch Service のバージョンも上がったので、マネージドに移行することを検討しています。

最後に

かなりざっくりとした内容となってしまいましたが、当たり前の技術を当たり前に、それでいて新しい風を取り込みながら MAMADAYS は開発・運用しています。

まだまだ成長途上のサービスですので、これからも世の中の出産・育児に対する課題に技術でどう解決していくかを考えながら取り組んでいこうと思います。

ここまでお読みいただき、ありがとうございました。