Qiita の json schema に"type": "object"
がない
Qiita の API レスポンスは json schema で表現されています。
Go 用の struct を作るのが面倒だったので、この json schema を解析して struct を自動生成したら楽だろと思いまして、schematyper で解析しようと試みました。
しかしできない。解析に失敗する。
この失敗理由が何かというと、Qiita の json scheme には "type": "object"
が省略されているんですよね。。。
"properties": { "properties": { "client_id": { "description": "An unique ID to identify a registered client", "example": "a91f0396a0968ff593eafdd194e3d17d32c41b1da7b25e873b42e9058058cd9d", "pattern": "^[0-9a-f]{40}$", "type": "string" }, (snip) }, "required": [ "client_id", "scopes", "token" ], "title": "Access token" ここに "type": "object" がない },
json schema 的には "type": "object"
がなくても valid なようです。なぜなら、 properties
key があればそれが object だとわかるから。
しかし、今回使おうとする schematyper が対応していないのでどうしようもない。手動で "type": "object"
をつけるしかありません。
"type": "object"
の付与
面倒なのは、"type": "object"
をつけるべき階層はいくらでも深くなり得ることです。
これは人類がやるべきことではないので、なんとか楽をしなければならない。
jq での再帰的な処理戦略
JSON の処理というと jq なわけですが、jq の walk
を使えば再帰的な処理が可能です。
今回は以下のようなコマンドを実行することで、 properties
key がある object を再帰的に探し、当該の object に対して "type": "object"
を付与するようにしました。
$ curl --silent --output schema.json https://qiita.com/api/v2/schema $ jq 'walk(if type=="object" and has("properties") then .type|="object" else . end)' schema.json
walk(f)
は引数として jq の関数 f
を取ります。関数 f
は、引数として JSON の要素を取ります。
ここでは、引数の要素が object であり、かつ、properties
という key を保つ場合に "type": "object"
を付与するように構成しました。