たびとの旅路 ~電脳砂漠の冒険譚~

フロッピー頼りに歩き、クラウドの地平を見つめる今日まで。見つけたオアシス、迷い込んだ砂の迷宮、全てこの羊皮紙に。

JSONの迷宮を解き明かせ ~Redfishの入れ子構造をマージする、再帰の魔法~

どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。

仕事でRedfishという広大な遺跡を探査していると、@odata.idという名の無数の道標に出会う。しかし、その道を一つ一つ手作業で辿るのは、あまりに果てしない旅だ。Postmanやcurlという名の松明を手にしても、道の数が二桁を超えたあたりで、私の心は折れそうになっていた。

「この迷宮の、完全な地図を描き出す魔法の道具はないものか?」 そう、全ての道を自動で辿り、その景色を一枚の巨大な羊皮紙に描き出す、そんな夢のような道具を。 今回は、実物の遺跡がなくとも試せるよう、Redfishのモックアップサイトという名の「設計図の断片(JSONファイル)」を使い、その夢をC#で実現する、壮大な錬金術の記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • Redfishのような、JSONの入れ子構造という迷宮に挑む者
  • 再帰という名の美しい魔法で、複雑な問題をエレガントに解決したい探求者
  • JSONという古代文字を、自在に読み解き、編集する術を知りたい冒険者
  • REST APIから大量のデータを効率的に収集する方法を模索している開発者
  • C#のNewtonsoft.Jsonライブラリを実践的に活用したい技術者

砂漠の道標

  • Redfish - サーバのハードウェア情報を取得するためのREST API仕様。DMTF(分散管理タスクフォース)が策定。
  • @odata.id - Redfishにおいて、関連リソースへのリンクを示すプロパティ。この道標を辿ることで階層構造を探索できる。
  • JSON - JavaScript Object Notationの略。構造化データを表現するテキスト形式。
  • 再帰処理 - 関数が自分自身を呼び出す処理パターン。階層構造の探索に有効。
  • Newtonsoft.Json - .NETでJSON処理を行う定番ライブラリ。Json.NETとも呼ばれる。
  • JsonTextReader - JSONを逐次的にトークン単位で読み込むクラス。大容量JSONに有効。
  • JsonToken - JSONの構文要素を表す列挙型。StartObject、PropertyName、String等の種類がある。
  • モックアップ - 実際のシステムを模倣した模型やサンプルデータ。実機なしで動作検証できる。

第一の儀式:遺跡の構造を理解する(Redfishとは)

Redfishとは、REST API(Webサービス通信規格)を使い、JSON(構造化データ形式)という言葉でサーバの魂と対話する、現代の魔法体系だ。その最大の特徴は、@odata.id(リンク情報を示すプロパティ)という道標によって、情報が入れ子状に繋がっていることにある。

Redfish のトップに表示される情報

全ての道の起点となる、遺跡の入り口

一つの道標を辿れば、また新たな道標が現れる。この無限に続くかのような構造こそが、我々冒険者を悩ませる、迷宮の正体だ。

Systems の情報

一つの道を辿ると、また新たな道が現れる

第二の儀式:魔法のレンズを手に入れる(Newtonsoft.Json)

この難解な迷宮を解き明かすには、Newtonsoft.Jsonという、強力な「魔法のレンズ」が必要だ。特に、JSONをトークン単位で読み解くJsonTextReaderと、それを再び組み上げるJsonTextWriterは、我々の旅に欠かせない。

秘儀の核心:再帰によるマージ

この錬金術の核心は、@odata.idという道標を見つけるたびに、自分自身を呼び出す(再帰処理) という、シンプルかつ強力な魔法にある。 その魔法を司るのが、RedfishJsonElementという、二つの設計図(クラス)だ。

設計図:魂を読み解くための器

遺跡の断片を記録する最小単位の器と、探査全体を司る設計図だ。

/// <summary>
/// JSONの要素(魂の欠片)を記録する器
/// </summary>
class JsonElement
{
    public JsonToken TokenType { get; set; }  // 要素の種類
    public object? Value { get; set; }        // 要素の値
}

/// <summary>
/// Redfishの迷宮を探査し、地図を描く者
/// </summary>
class Redfish
{
    public string Root { get; set; } = string.Empty; // 遺跡の断片が眠る場所
    public List<JsonElement> Elements { get; set; } = new List<JsonElement>(); // 集めた魂の欠片

    // 一度通った道を記録しておく羊皮紙
    HashSet<string> OdataItems { get; set; } = new HashSet<string>() { "/redfish/v1/" };
    // ...

    /// <summary>
    /// 全ての道を再帰的に読み込む
    /// </summary>
    public void Read(string path)
    {
        // 遺跡の断片(JSONファイル)を探す
        var jsonfile = @$"{Root}\{path}";
        if (!System.IO.File.Exists(jsonfile)) return;

        // 魔法のレンズで、断片を読み解く
        using var file = File.OpenText(jsonfile);
        var reader = new JsonTextReader(file);
        while (reader.Read())
        {
            // ...(魂の欠片をElementsリストに記録する処理)...

            // もし、そのページに「@odata.id」という名の「新たな道」が記されていたなら…
            if (((string)val1).Equals("@odata.id"))
            {
                // そして、その道がまだ我々の知らない道であったなら…
                if (!OdataItems.Contains((string)val2))
                {
                    // 新たな道を記録し、再びこのReadメソッド自身を呼び出す(再帰)
                    OdataItems.Add((string)val2);
                    Elements.Add(new JsonElement() { TokenType = JsonToken.PropertyName, Value = "/* @odata.child */" });
                    Read(((string)val2)[12..].Replace("/", "_") + ".json");
                }
            }
        }
    }
    // ...(Writeメソッドは、集めたElementsを一つの羊皮紙に書き出すだけなので省略)...
}

この再帰の魔法により、最初にmain.jsonという入口から入るだけで、そこから繋がる全ての道を自動的に探査し、巨大な一枚の地図(JSONファイル)として描き出すことができるのだ。

羊皮紙を巻く前に

今回の旅で、私はRedfishという広大な遺跡の「地図の断片」から、完全な地図を描き出す方法を見出した。入れ子の迷宮に迷う多くの冒険者にとって、再帰という魔法がいかに強力な武器となるか、この体験を通じて実感している。

再帰マージの優れた点

  1. シンプルな思想 - @odata.idを見つけたら自分自身を呼び出す。この一つのルールだけで、どれほど複雑な階層構造も自動探査できる。
  2. 拡張性の高さ - ファイル読込をREST API通信に置き換えるだけで、実際のサーバ探査に進化する。設計の本質は変わらない。
  3. メンテナンス性 - 再帰のロジックが一箇所に集約されているため、改良も容易だ。

実践時の注意点

  1. 循環参照の罠 - OdataItemsのような訪問済み記録がなければ、無限ループに陥る危険性がある。
  2. メモリ消費 - 全てを一度にメモリ展開するため、巨大な遺跡では工夫が必要になるだろう。

まとめ

複雑に見える問題も、その本質を見抜けば、驚くほどシンプルな解法が見えてくる。再帰という美しい魔法は、まさにそれを体現している。

この羊皮紙が、JSONの迷宮で途方に暮れる未来の旅人の、一筋の光となることを願う。そして、あんたもまた、この魔法を自らの冒険に応用し、新たな地平を切り開いてくれることを。

おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。

砂漠で見つけた魔法のランプ

羊皮紙の余白に書き足す

実際にサーバからRedfishで情報を取得するように修正した、Webアクセス版の冒険日誌はこちらだ。

遺跡の魂を直接読み解け ~RestSharpで、Redfishの深淵を覗く~

ラクダの独り言

ご主人が「じぇいそんのめいきゅう」とか言って、何枚もの羊皮紙を睨みながら、ぶつぶつと呪文を唱えている。なんでも、クモの巣みたいに繋がった情報を、一枚の大きな地図にしているらしい。「さいき」って魔法を使うと全部勝手に集まるんだとよ。魔法ってのは便利だな。でも、俺に言わせりゃ、砂漠の道なんて足で歩いて覚えるもんだろうに。まったく、人間ってのは、頭でっかちが過ぎる。やれやれだぜ。