近況
最近仕事がめちゃくちゃ暇で、色々と考えた結果考えがまとまらず将来に漠然とした不安を抱えつつある。
仕事がめちゃくちゃ暇なのは、色々な事情があり仕事しようと思えば仕事出来るんだけど如何せんやる気が無いのと、リリース済みの動いてるコードは必要が出るまで触りたくないというのと、やる気が無いので結果仕事が無いみたいな感じになってる。
所属しているのはソーシャルゲーム作りま〜っす的な会社なんだけど、前に転職未遂した時にゲーム作りたくないで〜っす的なことを言ったが慰留され、内定出たところの諸々の色々が色々で結果転職しなかったんだけど、ゲーム作る会社でゲーム作りたくないって感じなのでまぁ出来ることというか会社がやらせられることも限られて来るわけで、ここ半年くらいはRoRに初挑戦してスマホアプリのAPIを開発などしてた。
RoR凄くてRailsチュートリアル一通りやったらもう大体一通りの事は大体出来るようになるし、API開発程度なら色々と楽に実装が出来て凄いという感じだったけど、やってて全然楽しくねぇという感じがした。
たぶんサービス作るマンとか、色々と楽に実装して空いた時間で色々良くしてくみたいな感じのアレだとアレなんだろうけど、半年たってもアレをアレすることが出来ていない感じになっている。
API開発で一番興味ある部分がドキュメントの自動生成というかドキュメントと実装の乖離を無くすことで、ここ半年やってたプロジェクトでは色々と試せて良かった。
そこら辺の色々を書いてる途中で大分放置してるのを思い出したので仕事がめちゃくちゃ暇なうちに書いて公開したい。
色々と考えた結果考えがまとまらず将来に漠然とした不安を抱えつつあるんだけど、とりあえずこのままじゃいかんとは思っているが、以前まで働いていた動機が詳細端折るが死なないためという感じだったんだけど、意外と全然生きられてしまって、ゲームやアニメや未完の漫画などが増えてきて最近はなるべく長く行きたいが働きたくないという感じになりつつある。
現状だとiOS開発がやりたいが、現職でiOS開発出来る見込みは殆ど無く、以前はiOS開発しか出来ない状態だったけど今はRailsもまぁ触れるようになったし、iOS開発がしたいかって言われるとそうではないがRails使いたいかって言われると違い、僕が出来る全てやりたいという感じもありつつ働きたくないという感じになってる。というかRailsでチーム開発した結果あんま使いたくないんだけど、静的型付け言語でなんかちょうどいい感じの言語は無いんすかって思ってる。
先日また昇給して転職のタイミングを上手いことアレすることが出来ないし、転職するにしても現状の経歴だと何処にも引っかからんだろうみたいな感じがあり、打開策が見つからず将来に漠然とした不安を抱えつつある。
僕が考えた最強のAPIドキュメント生成
2023 追記
2023 年現在では、以下の文章では採用を見送っている OpenAPI を使えば OK という雰囲気です。
TL; DR
- ドキュメント生成にはkevinrenskers/raml2htmlを使った
- ドキュメントはRAML - RESTful API modeling languageで書いた
- RAMLにはJSON SchemaとJSONを記載できる
- APIで返ってくるJSONはRailsアプリのrequest specでJSON Schemaを使ってテストした
- JSON Schemaはr7kamura/json_worldで生成した
- ドキュメントに載せる例示のJSONもJSON Schemaからgin0606/screijiを使って生成した
- 上記の方法だとリクエストパラメタとドキュメントの整合性を担保できないので、可能ならRAMLを使わず、全てJSON Schemaで書いたほうが検証しやすそう
使ってるツールとかだいたいRuby製だけど、最終的にjsonに吐き出したりしてるから他の言語のWAFでも使える気がする。
背景
- 以下を実施したプロジェクトの都合上、APIの実装でクライアントアプリの開発を止められない
- クライアントアプリ開発が始まる段階で一通りのAPIドキュメントの提供したかった
- 過去に経験したプロジェクトで正しい情報が載っていないAPIドキュメントに苦しめられた経験があり、なるべくドキュメントと実装の整合性を保てる状態にしたかった
- 今回はサーバーサイド開発だったが、以前はクライアントアプリ開発メインだったので、そういう問題が起こる諸々の都合を把握したり、解決したりする方法を探りたかった。
- あとサーバーサイド開発初挑戦で、インフラとか整うまで暇を持て余していた。
- 今回はサーバーサイド開発だったが、以前はクライアントアプリ開発メインだったので、そういう問題が起こる諸々の都合を把握したり、解決したりする方法を探りたかった。
他にも色々あったり記憶が歪められてる気もするけど、だいたいはこんなもんだと思う。
技術選定
ドキュメントフォーマット
- r7kamura/autodoc
- JSON Schema
- API Blueprint - API Documentation with powerful tooling
- RAML - RESTful API modeling language
- Swagger – The World's Most Popular Framework for APIs.
以上の5つが割りと使われてそうなフォーマットに上がった。
最終的にはRAMLを使うことにしたんだけど、以下が選定理由。
autodoc
rspecからドキュメント生成するやつ。
リクエストパラメタとか諸々テストしつつ、それを元にドキュメント生成出来るので、大分良さそうという感想だったんだけど、実装よりも先にドキュメント用意したいという感じだったので見送った。
次が諸々の不都合が無いRailsプロジェクトでもautodocは使わないで、json_worldとr7kamura/rack-json_schemaでどうにかすると思う。社内の別プロジェクトでScalaやGoが使われているのもあって、特定の言語やWAFに依存しすぎるの良くないという感じ。
JSON Schema
単体のJSON定義するくらいなら出来なくもないけど、記法を覚えるコストが高くて、これで全てを書くのは無しだという感じになった。
users.jsonをuser.jsonとかreference使って書く方法がどう頑張っても分からなくて、gin0606/schaiというgemを作ったりした。 schaiはプロジェクト中盤まで現役で使ってたけど、json_worldに移行して、レスポンスのJSONとJSON Schemaをjson_worldで生成するようになった。
なんで最初からjson_worldを使わなかったんだって感じだけど、当時はダメやんって思うことが何かあった気がするんだけど覚えてない。
サーバーがRubyでJSON Schema使うならjson_world使おうって感じ。
API Blueprint
Markdown書いてAPIドキュメントとMockサーバー建てられるやつ。
記憶が曖昧なんだけど、JSONとJSON Schemaを記載できる。
Apiary — Homeというサービスがあって、githubにドキュメント置いて、それからドキュメントとかMockサーバーとか作ってくれる。
Apiaryというサービス(会社)で使ってるし、直近でメンテされなくなる可能性とか低そうって思って、最初はAPI Blueprint導入してた。
Mockサーバー建ててくれるので、やりたいことに合致していて、ドキュメントに記載したJSON Schemaを元にnogates/vigiaとかcybertk/abaoを使ってドキュメントをJSON Schemaとの検証含めてテスト出来るかと思ったんだけど、出来なかったし、そんな書きやすくもなかったからやめた。
RAML
最終的に落ち着いたやつ。
http://raml.org/ 見れば分かるけどyaml書いてくやつ。
チャットワークAPIドキュメントで使われてる。
API Blueprintに比べて、APIのエンドポイントをyamlでツリーみたいに書いていけるので、だいぶ良かった。
説明とかが長いAPIあると、その下のエンドポイント書きづらいという問題もあるんだけど、ファイルを分けて書けたはずなので、そんな大きな問題にならないはず。
API Blueprintを止めた時点で、ドキュメントをそのまま使ってAPIとドキュメントの整合性を保とうという甘い考えを捨てて、レスポンスの整合性はrspecでjson schema使って検証しようという感じになった。 ドキュメントをそのまま使ってAPIとドキュメントの整合性保てないなら、API BlueprintよりもRAMLのほうが断然書きやすいので、最終的にRAMLを使うことになった。
Swagger
なんか巨大すぎるしジャバやんみたいな雑な理由で全然調べずに止めた気がする。
雑すぎるので次API開発する機会あったらちゃんと調べたい。
ドキュメント生成
生成と言っても、RAMLなので結局手書きでAPIのドキュメントを書いてくことになる。
↓こんな感じのYAMLを書いていく。
schemas: - User: !include schemata/user.json traits: - client_credentials: usage: Client Credentials Grantでアクセス可能なAPIに指定する headers: Authorization: description: OAuth 2.0 アクセストークン [Client Credentials Grant](http://openid-foundation-japan.github.io/rfc6749.ja.html#grant-client) type: string required: true example: "Bearer ACCESS_TOKEN" - resource_owner_password_credentials: usage: Resource Owner Password Credentials Grantでアクセス可能なAPIに指定する headers: Authorization: description: OAuth 2.0 アクセストークン [Resource Owner Password Credentials Grant](http://openid-foundation-japan.github.io/rfc6749.ja.html#grant-password) type: string required: true example: "Bearer ACCESS_TOKEN" /users: displayName: ユーザー関連API post: is: [client_credentials] description: ユーザー登録 body: application/x-www-form-urlencoded: formParameters: user[screen_name]: description: アカウント名(重複付加) required: true type: string example: yamada user[password]: description: パスワード required: true type: string user[password_confirmation]: description: パスワード確認 required: true type: string responses: 201: body: application/json: schema: User example: !include screiji/user.json /{user_id}: uriParameters: user_id: type: integer get: is: [client_credentials] description: ユーザー情報取得 responses: 200: body: application/json: schema: User example: !include screiji/user.json patch: is: [resource_owner_password_credentials] description: ユーザー情報更新 body: application/x-www-form-urlencoded: formParameters: user[screen_name]: description: アカウント名(重複付加) required: false type: string example: yamada responses: 200: body: application/json: schema: User example: !include screiji/user.json delete: is: [resource_owner_password_credentials] description: ユーザー削除 responses: 204:
schema: User
とかexample: !include screiji/user.json
も手動で生成していて、app/resources/api/resources
以下に存在するjson_worldで書いたクラスのJSON Schemaをファイルに書きだして、screijiでexampleのJSONをファイルに書き出すみたいなことをやった。
やってるrake task https://gist.github.com/gin0606/55bed5902fe820914c5b
更新忘れを防ぐためのテスト書いたりもしたけど、大分ダサい。
ドキュメント閲覧
module Api class DocController < ApplicationController def doc render html: raml2html, content_type: "text/html" end private def raml2html `#{Rails.root}/node_modules/raml2html/bin/raml2html -i #{Rails.root}/docs/api.raml`.html_safe end end end
こんなようなことをしてる。
色々と手動でやっててダサいので、asset pipelineでerbなどでRAMLの元になるやつ書いて、その中でJSON Schema埋め込んで、HTML生成して描写するみたいなこと出来ればよかったんだけど、gemが無い&asset pipeline全く分からんという感じで諦めた。
そんな感じで、TL; DR
に全て書いてあるから他に特に書くことに気付き、JSON Schemaで全て済ませましょうねって感じ。
社内の別プロジェクトではScalaやGoが使われているので、言語やFrameworkが変わってもそこら辺のノウハウが使えることを考えるとJSON Schemaが良いのかなと思う。
Rails以外だとJSON Schemaを上手いこと生成してくれるツールが有るのか分からないけど、無かったらjson_world使っても良いと思う。簡単なDSLでJSON Schema生成出来るし、json吐き出せば各言語にValidatorあると思う。
gin0606/schaiはJSON Schemaの面倒くさいの色々と省いて生成してくれる。RAML使って色々やったプロジェクトでやった限りでは使い物になるんだけど、対応してないJSON Schemaのキーワードとかも多いし、Ruby学習の一環で書いたのもあってコードの品質も糞低い。使い物になるようにするなら1から書き直したほうが良さそうという感じ。
gin0606/screijiは、JSON Schemaから雑にJSONの例示を生成してくれるやつで、これは自分で作ったけど普通に便利だと思う。このプロジェクトでもまだ使っているけど、Ruby学習の一環で書いたのもあってコードの品質が低い。
2016/02/16 14:56 追記
Qiita API v2のJSON Schemaを公開しました - Qiita Blog
最近iOSアプリ開発リハビリがてらQiitaTeam見るやつ作ってて、これさっき読んだけど、JSON Schema使う理由とかドキュメント云々とかはこれに書いてあるとおりだと思う。
r7kamuraくんが書いたJSON Schemaとか周辺の文章にも大分影響されている自覚はある。
「Swiftでコマンドラインツールを作る」という文章をQiitaに投稿した
自分だったら後でストックしたい気がするなみたいなやつを最近Qiitaに投稿してるんだけど、そうするとブログが自炊とゴキブリを食っただけみたいになるので、Qiitaに書いたらブログで書いたというようなことを書こうという気持ちになったので書いた。