どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。
仕事でRedfishという広大な遺跡を探査していると、@odata.idという名の無数の道標に出会う。しかし、その道を一つ一つ手作業で辿るのは、あまりに果てしない旅だ。Postmanやcurlという名の松明を手にしても、道の数が二桁を超えたあたりで、私の心は折れそうになっていた。
「この迷宮の、完全な地図を描き出す魔法の道具はないものか?」 そう、全ての道を自動で辿り、その景色を一枚の巨大な羊皮紙に描き出す、そんな夢のような道具を。 今回は、実物の遺跡がなくとも試せるよう、Redfishのモックアップサイトという名の「設計図の断片(JSONファイル)」を使い、その夢をC#で実現する、壮大な錬金術の記録である。
この羊皮紙のあらまし
- この羊皮紙のあらまし
- この羊皮紙が導く者
- 第一の儀式:遺跡の構造を理解する(Redfishとは)
- 第二の儀式:魔法のレンズを手に入れる(Newtonsoft.Json)
- 秘儀の核心:再帰によるマージ
- 羊皮紙を巻く前に
- 砂漠で見つけた魔法のランプ
- ラクダの独り言
この羊皮紙が導く者
- Redfishのような、JSONの入れ子構造という迷宮に挑む者
- 再帰という名の美しい魔法で、複雑な問題をエレガントに解決したい探求者
- JSONという古代文字を、自在に読み解き、編集する術を知りたい冒険者
第一の儀式:遺跡の構造を理解する(Redfishとは)
Redfishとは、REST APIを使い、JSONという言葉でサーバの魂と対話する、現代の魔法体系だ。その最大の特徴は、@odata.idという道標によって、情報が入れ子状に繋がっていることにある。

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

第二の儀式:魔法のレンズを手に入れる(Newtonsoft.Json)
この難解な迷宮を解き明かすには、Newtonsoft.Jsonという、強力な「魔法のレンズ」が必要だ。特に、JSONをトークン単位で読み解くJsonTextReaderと、それを再び組み上げるJsonTextWriterは、我々の旅に欠かせない。
秘儀の核心:再帰によるマージ
この錬金術の核心は、@odata.idという道標を見つけるたびに、自分自身を呼び出す(再帰する)という、シンプルかつ強力な魔法にある。
その魔法を司るのが、RedfishとJsonElementという、二つの設計図(クラス)だ。
設計図:魂を読み解くための器
/// <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という広大な遺跡の「地図の断片」を使い、その完全な地図を描き出す方法を紹介した。この魔法の核心は、@odata.idを見つけるたびに再帰的に情報を辿る、というシンプルな考え方にある。
この羊皮紙に記した呪文を改良し、ファイルを読む代わりにREST APIで直接遺跡を探査するようにすれば、この魔法はさらに強力なものとなるだろう。 (そして、その旅の記録は、また別の羊皮紙に記されることになる)
この記録が、同じように複雑なJSONの迷宮で迷う、未来の冒険者の助けとなることを願う。
おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。
羊皮紙の余白に書き足す
実際にサーバからRedfishで情報を取得するように修正した、Webアクセス版の冒険日誌はこちらだ。
遺跡の魂を直接読み解け ~RestSharpで、Redfishの深淵を覗く~ - 砂漠の旅人(たびと)
砂漠で見つけた魔法のランプ
- DMTF Redfish | 遺跡に関する公式の古文書
- Redfish Mockup | 遺跡の精巧な幻影
- Json.NET | 古代文字を読み解く魔法のレンズ
ラクダの独り言
ご主人が「じぇいそんのめいきゅう」とか言って、何枚もの羊皮紙を睨みながら、ぶつぶつと呪文を唱えている。なんでも、クモの巣みたいに繋がった情報を、一枚の大きな地図にしているらしい。俺に言わせりゃ、そんな面倒なことする前に、普通に道を歩けばいいだろうに。まったく、人間ってのは、どうしてこう、物事をややこしくするのが好きなのかねえ。やれやれだぜ。