Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CLIツール開発をProtocol Buffers スキーマで駆動する

Naoya Furudono
January 31, 2025
200

CLIツール開発をProtocol Buffers スキーマで駆動する

Naoya Furudono

January 31, 2025
Tweet

Transcript

  1. How to Design Programs How to Design Programs (HtDP) はプログラミングの教科書

    "focuses on habits of good programming" プログラミング言語意味論の大家、Matthias Felleisen が著者 「保存と進行」を証明することで型システムの健全性を示すことを提案した 未邦訳だが、原著がWebで無料で読める https://htdp.org/2024-11-6/Book/index.html https://htdp.org 6
  2. デザインレシピ 関数の設計を扱っている 関数は抽象化の基本単位だから プログラムの設計・実装をステップ分けして、以下の順で成果物を作る 1. From Problem Analysis to Data

    Definitions 2. Signature, Purpose Statement, Header 3. Functional Examples 4. Function Template 5. Function Definition 6. Testing https://htdp.org/2024-11-6/Book/part_one.html#(part._sec~3adesign-func) 9
  3. 2. 関数のシグネチャ、目的文、関数のスタブを書く // number string Image -> Image // sをimgの上からyピクセル、

    // 左から10ピクセルの位置に付け加える function addImage(y, s, img) { return emptyScene(100, 100); } 12
  4. 5. 関数を実装する // number -> number // computes the area

    of a square with side len // given: 2, expect: 4 // given: 7, expect: 49 function areaOfSquare(len) { return len * len; } 15
  5. 6. テストする // number -> number // computes the area

    of a square with side len // given: 2, expect: 4 // given: 7, expect: 49 function areaOfSquare(len) { return len * len; } assert(areaOfSquare(2) == 4); assert(areaOfSquare(7) == 49); 16
  6. 粒度が異なることに起因する、スキーマ駆動開発の障壁 A. どのようにスキーマ(シグネチャ)定義すれば良いかわからない 関数のシグネチャの書き方はプログラミング言語が決めてくれていた スキーマ駆動開発では、データの定義やパラメータ、目的文をどこにどのよ うに書けば良いだろうか B. スキーマ(シグネチャ)定義から実装に移るまでにギャップがある デザインレシピでは、関数シグネチャを元にその関数を実装していた。何も 難しくない

    スキーマ駆動開発では、スキーマを元にAPIを実装する。 ルーティングとかデータのデシアライズ処理とかはどうなる? C. どのようにテストを書くと良いかわからない デザインレシピの文脈では、関数をテストするだけだった もちろんスキーマ駆動開発でも必要。しかしAPIサーバのテストは単体テスト ほど書き方が自明ではない 22
  7. ツールを使えばいい A. どのようにスキーマ(シグネチャ)定義すれば良いかわからない → Protocol Buffersで書く スキーマ駆動開発では、データの定義やパラメータ、目的文をどこにどのよ うに書けば良いだろうか B. スキーマ(シグネチャ)定義から実装に移るまでにギャップがある

    → protocやConnectでコード生成したり、ライブラリを使う スキーマ駆動開発では、スキーマを元にエンドポイントを実装する。 ルーティングとか型検査とかはどうなる? C. どのようにテストを書くと良いかわからない → runnを使ってシナリオテストする もちろんスキーマ駆動開発でも必要。しかしAPIサーバのテストは単体テスト ほど書き方が自明ではない 23
  8. A. スキーマ定義は、Protocol Buffersを用いて書けば良い message Square { int32 len = 1;

    } service Calculator { // 一片の長さがlenである正方形の面積を計算する // given: len = 2, expect: 4 // given: len = 7, expect: 49 rpc AreaOfSquare(Square) returns (int32); } デザインレシピでやったのと同様 // number -> number // 一辺の長さがlenである正方形の面積を計算する // given: 2, expect 4 // given 7, expect: 49 function areaOfSquare(len) { return 0; } 26
  9. C. Web APIのユースケースを説明するようなテストはどのようなものだろうか AAAパターンで考えてみる Arrange: APIサーバの状態を整える ログインする クレジットカードをあらかじめ登録する Act: 実装したAPIにリクエストを送る

    決済APIを実行する Assert: レスポンスを検証したり、意図した状態変化が起きたことを確かめる 200レスポンスが戻る 決済履歴に新しい決済が追加されていることを確かめる 29
  10. シナリオテストがWeb APIのユースケースを説明するようなテストである 「シナリオを用いた効果的なピンポイントテスト」は、ユーザ視点のブラックボ ックステスト技法の1つです。 1. 「夜半(When) 」に「A さん(Who) 」が「自宅(Where) 」から「品物

    (What) 」を検索 2.ショッピングカートに入れる 3.レジに進む 4.サインインする 5.★クレジットカードの有効期限が切れている場合の処理 6.配送条件を確定する 7.注文を確定する 高信頼化ソフトウェアのための開発手法高信頼化ソフトウェアのための開発手法ガイ ドブック(情報処理推進機構) 30
  11. ところでなんのためのCLI開発なのか? Kubernetes CronJobでコマンドを実行する目的 apiVersion: batch/v1beta1 kind: CronJob metadata: name: subscription-payment-cronjob

    spec: schedule: "*/1 * * * *" # 毎分実行 jobTemplate: spec: template: spec: containers: - name: batch image: batch:latest command: - "batch" - "subscription-payment" - "--dryrun" - "false" - "--start" - "2022-01-01T00:00:00Z" - "--end" - "2022-01-02T00:00:00Z" retryPolicy: OnFailure 36
  12. 44