日々是精進。(はてな館)

日々ネットで調べたり、付箋に書き留めたものをアップしています。子育てで中断しながらも、年に数回投稿しています。皆様の恩恵に感謝しつつ。

Chrome Restlet Client を使って、RedmineのREST APIを試します (JSON版)

みなさまこんにちは。 はてなの記事、12件目となります。 今回は、RedmineREST APIについて書いてみます。

はじめに

Redmineについては、最近「インフラ勉強会」でお話を聞いたりやりとりさせていただく中で、ちらほらと耳にする機会が増えました。 実のところ、いろんなモダンなタスク管理ツールも増えて来ているので、個人的にはRedmineは今後どうなんだろう...と思っていたのですが、意外にみなさん利用されていたり、これから立ててみたいというコメントを見かけたりして、単語が出てくると喜んでいたりします。

Rubyという言語、Railsというフレームワークを学ぶというよりは、Webサーバやアプリケーションサーバ、DBを用意し運用をしてみる、というには良い素材だと思っています。

また、運用だけでなく、RedmineにはREST APIが用意されているので、例えば他のアプリケーションやSaaS, PaaS(クラウド関連)のサービスをcurlCLIで操作する練習としても、割といいのではないかなと思っています。

たまたま、初夏にRedmineAPIを使いたいけどちょっとお困りの方がいらしたので、確認方法をコメントさせていただきました。

なんとかうまく試していただけたようなので、こちらで試したやりとりを記事に起こしてみることにしました。

どんなREST APIがあるの?仕様はどうなっているの?

Redmineの公式サイトの、API一覧は以下のページになります。

SwaggerのようにGETやPOSTのリクエストを試せる機能がRedmine自体についていれば、動作確認はしやすいのですが、残念ながらそういう機能はまだありません。 (Swagger Docだけでも生成されていればいいなあとは思ったり)

まずは、ドキュメントにしたがって、ブラウザやcurlその他のツールで実際に試しながら進めることになります。

個人的には、RedmineのそもそものWebからのリクエスト送信方法やバリデーションを理解していないと、特にチケット作成の時に困ったりするかな...と感じています。

XML形式とJSON形式

さて、Redmineには、APIで返すフォーマットとして、XMLJSONの2つの形式をサポートしています。 *1 *2

XMLに関して

XMLでのリクエストに関しては、だいぶまえですが、ブログに記事を書いています。

daily-postit.blogspot.com

また、curlを使ってXMLでチケットを作成するshell scriptはこちらになります。

github.com

JSONの場合

現状、REST APIでのやりとりはJSONが中心だと思いますので、今回はこちらを軽く取り上げてみます。 また、上記のXMLの記事を書いた時から「だいぶ!」過ぎていますので、ツールも変えて、簡単にお手元のブラウザで試せるものを利用してみます。

Chrome Restlet Clientを使ってみます

さて、表題の通り、利用するのはChrome Restlet Clientというツールです。 こちらはChromeの拡張として利用することができます。

外部のサービスは利用せず、localhostで起動しているアプリケーションに対しても、もちろん利用可能です。 Redmineだけでなく、APIを備えたアプリケーション、サービスに対してリクエストを送信し結果を表示してくれます。 curlのようなツールに慣れていないけれど、パラメータをうまく調整しながらどういうリクエストを出せばいいか、どういったレスポンスが返ってくるかを確認しやすいツールです。

GET /issues.json でチケット一覧を取得

実際にJSONでのAPIを叩いた結果は以下の通りです。

f:id:akiko-pusu:20180901215444j:plain

  • GUIでリクエスト時のヘッダが設定可能
    • Content-Type: application/json
    • 認証用のヘッダ
    • その他X-xxxxx といったヘッダも指定可能
  • 抽出条件は、Webからのフィルタのパラメータ通りのものを後ろに繋げてもOK

右側の紙飛行機のボタンを押すと、リクエスト&レスポンスが画面下に表示されます。 簡単ですが、JSONデータが返ってきているのがわかります。

POST /issuesでチケットを作成

Rest Issues - Redmine を参考に、データをPOSTしてみます。この場合も、ヘッダにはContent-Type: application/jsonを指定します。 送信するBodyは、以下のようなJSONになります。

POST /issues.json
{
  "issue": {
    "project_id": 1,
    "subject": "Example",
    "priority_id": 4
  }
}

チケットの新規作成の場合は、うまくいくとStatusCode: 201 と、生成結果のJSONが帰ります。 作成内容はJSONとしてリクエストのbodyに添えますが、Restlet ClientだとGUIのフォームに貼り付けて、そのまま送信ができます。

リクエストを送信しても、認証が通らなかったり、必須項目が不足している場合はエラーになります。 StatusCode: 422 / Unprocessable Entity が返ってくる場合は、とくにこの必須項目が不足しているとか、バリデーションに失敗した、という内容になります。

以下に、キャプチャした動画を添えてみます。 Subjectを添えなかった場合は422が返って来ますが、ただしく添えると201でチケットが作成されているのがわかります。

https://raw.githubusercontent.com/akiko-pusu/misc/master/misc/capture.gif

参考までに、XMLの場合のチケット作成の結果も添えておきます。

f:id:akiko-pusu:20180901220239j:plain

  • XMLでのPOSTなので、ヘッダにはContent-Type: text/xml を設定
  • チケット作成のためのパラメータは、Body用のフォームに入力できます
  • レスポンスもXMLで返ってきているのがわかります

 添付ファイルはどうするの?

実は、Create Issue, Update Issueと一緒に一度に添付ファイルを追加するといった操作ができません。 まずは添付ファイルを作成し、アップロードのtokenを取得してから、チケットのファイル要素に対してそのtokenをセットしてからのファイルとチケットの関連付けになります。

くわしくはこちら。

https://www.redmine.org/projects/redmine/wiki/Rest_api#Attaching-files

認証はどうするの?

認証に関しては、いくつかパターンがあります。

  • Request Headerにユーザ名 / パスワード (Basic認証情報)を渡す
  • Request HeaderにPOSTするユーザのAPI Keyを設定して渡す
  • Requestのパラメータ側にkey=xxxxx で渡す

いずれにしても、通信が暗号化されていることを前提に設定してください。

全ての処理がREST API対応しているの?

実は、まだREST APIが全ての処理に対応しているわけではありません。 公式サイトでの対応状況は、以下のページにあります。

API化されていないものに関しては、通常のWebからのリクエストと同じようなリクエストを送信して処理を行う必要があります。また、その場合は結果がXMLJSONでは無いので、自前でさらにHTMLをパースするといった必要があります。

ただ、いまのところはだいぶチケット関連については充実してきています。 また、APIとは少し違うかもしれませんが、CSVやPDFの出力、Feedデータとしての出力も可能なので、うまく利用すれば大抵のことはできるかな、と思います。

Chrome Restlet Client についてもうすこし

キャプチャを添えた通り、GUIでパラメータを調整しながらリクエストとレスポンスの確認ができます。 また、結果は保存できますし、いくつかのリクエストを組み合わせて、「シナリオ」として連続した複数の操作を行うことができます。

REST APIも含め基本的にはステートレスなのですが、前の処理のレスポンスの結果を変数に格納して、次の処理に渡すこともできます。(たとえばSessionIDや作成されたデータのIDなど)

結果的に、自動のテストツールのSeleniumに似た感じで、実行ボタンを押せば認証情報の取得から検索、洗濯、作成や更新といった一連の操作を行うことができます。 設定も書き出して他のメンバと共有することもできるので、テストツールの1つとして利用してみてくださいね。

*1:え、XMLも?と思われるかもしれませんが、10年以上続くRemine、はじめからAPIというよりはRSS/Feedの機能としてチケット一覧やアクティビティ、検索結果をXMLで返す機能を保持しておりました。

*2:Ajaxも初めはXMLが中心でしたし、XML-RPCSOAPといった時代を踏まえて、まだXMLがサポートされています。実は、わたしがRedmineを選んだ決め手は、このXML形式でデータを取得できる、という点でした。