利用・活用 Redmine API

本日の担当は岩石です。立春が過ぎましたが、まだまだ寒い日が続きます。
昔は寒さに負けず、梅の花など撮りに出かけていましたが、ここ数年カメラを持ち出すことが少なくなりました。
最近撮影した写真を振り返ると...会社関係の写真ばかり撮ってますね(笑)。

今回のブログは、昨年最後に私が担当したブログで予告した通り、今回はRedmineのREST APIの話を書きます。

Web APIやRESTにお詳しい方なら、今回のブログの話はすでにご存知だと思いますので、ご存じない方へ入門編として書こうと思います。
なお先週末より、とあるCMSのREST APIの話題が広まっていますが、その話題には触れません。

REST API

REST APIとはWeb APIのうちRESTに従った設計で作られたAPIのことを言います。

Web APIとは、簡単に説明するとhttpやhttpsのプロトコルでアクセスするWebシステムに、Webブラウザを使用してデータの登録や閲覧をするのではなく、プログラムなどから指定された形式でアクセスし、システム内の情報を登録したり、取得したりする手順のことを言います。

また、RESTについて簡単に説明するのはとても難しいですが、Webのアドレス(URIとかURLと呼ばれます)を体系立てて設計・実装する考え方のことを言います。

今回の記事では、REST APIと記載していますが、あまりRESTを意識せず、Web APIの一般的な使い方と思って参考にしてください。

Redmineだけでなく、多くのアプリケーションやサービスなどにおいて、情報の登録・編集や取得にWeb APIが使用できるようになっています。これによりWebアプリをWebブラウザを使って利用するのではなく、データベースのように使用することができます。Webアプリの仕様に捉われず、自作のアプリなどから自由に利用することができるようになります。

例えば、弊社では情報セキュリティ維持のためにRedmine上で誰がどのプロジェクトでどのような権限をもっているのか管理するための表を作成していますが、この作業にはAPIで情報を取得し一覧表を作成するプログラムを使っています。手作業だと1時間以上かかる作業が、プログラムを作って自動化したことで一瞬で完了します。

Redmine の REST API

RedmineのREST APIの仕様はRedmine公式サイトのDeveloper Guide内で公開されています。

Redmine API
Redmine - Developer Guide - Rest api

最新の詳しい情報についてはこちらで確認をお願いします。

REST API使用設定

管理権限を持ったアカウントでRedmineにログインし、左上のメニューから 管理 に進み、 設定 を開きます。

APIタブ を選び、 RESTによるWebサービスを有効にする にチェックが付いた状態にし 保存 ボタンをクリックします。
これでREST APIが使用できるようになります。

APIキーの発行

誰でも自由に情報を改変したり、閲覧できると困る場面もありますよね。
認証の仕組みとしてユーザアカウント毎に個別のAPIキーを発行し、キー文字列を認証情報として使用します。

Redmine画面の右上の個人設定をクリックし、アカウントの管理画面を開きます。

画面左の APIアクセスキー表示 をクリックするとAPIキーが表示されます。
今後、ここで発行したキーを使用しますので文字列を確実に保管しておいてください。

なお、キーを紛失したり、誰かに漏れた場合は、同じ項目の リセット をクリックすると再発行(新規キー発行)することができます。

REST APIの利用

例えばRedmineに登録されているアカウントの一覧を取得するには、httpのGETメソッドを使用します。
Rest Users - Redmine 参照)

仮にRedmineへアクセスするURLが http://example.net/redmine とすると、XML形式でチケット一覧データを取得する場合は、 http://example.net/redmine/issues.xml にアクセスします。

同じ様に登録ユーザアカウントの一覧をJSON形式で取得する場合は、GETメソッドで、 http://example.net/redmine/users.json にアクセスします。

また、チケットの新規登録は Rest Issues - Redmine に記載の通り、 projectid (プロジェクトID)や trackerid (トラッカーID)などを、 http://example.net/redmine/issues.xml(もしくはissues.json)にPOSTメソッドで送信します。
(※必須のフィールドを省略すると作成に失敗します)

詳細はRest api - Redmine のページを参照願います。

Linuxコマンドでの利用

APIを使用するのに最も簡単な方法はLinuxなどで利用できるcurlコマンドを使用する方法です。
(※これ以降はRedmineへのアクセスURL( http://example.net/redmine など)を <REDMINE URL> 、APIキーを <API KEY> と表記します。)

下記のコマンドは、プロジェクトの一覧をXML形式で取得します。コマンドラインで実行すると、画面にプロジェクトの一覧がXML形式で表示されます。

curl <REDMINE URL>/projects.xml?key=<API KEY>

次のコマンドを実行すると「APIテスト」というタイトルの新しいチケットが作成できます。

curl -v -H "Content-Type: application/json" -X POST -d '{"issue":{"project_id": 2, "subject": "APIテスト", "tracker_id": 1, "status_id": 1}}' <REDMINE URL>/issues.json?key=<API KEY>

(ちなみにデフォルトの状態で、tracker_id=2は「バグ」、status_id=1は「新規」となってます。)

RedmineのAPI仕様そのままを利用する場合は、次項で説明するプログラミング言語を使った方法より簡単ですね。

プログラムからの利用

curlでREST APIが簡単に利用できますが、プログラムを利用することで、他のシステムと連携したチケットの登録や、標準のAPI仕様に無いデータの抽出なども可能になります。

例えば、全てのプロジェクトに対して、どのアカウントが何のロール(権限設定された役割)で登録されているかを取得したい場合、プロジェクトの一覧取得とプロジェクトの登録メンバーを取得するには、APIを併用することで取得ができます。

下記はRubyでのサンプルですが他の言語でも同様な処理は簡単に作成できます。

プロジェクト一覧の取得

まず、プロジェクトの一覧を取得するにはスクリプトは下記の様になります。

require 'net/https'
require 'json'
uri = URI.parse("<REDMINE URL>/projects.json?key=<API KEY>")
File.open("projectlists.json", "w") {|file|
  file.write projectslist = Net::HTTP::get_response(uri).body
}

実行すると projectlists.json というファイル名でプロジェクトの一覧が取得できます。

プロジェクトメンバーの取得

前項のスクリプトでプロジェクトのidが取得できますので、そのidを使用してプロジェクトの登録メンバーとロールを取得します。
プロジェクトの登録メンバーの情報は memberships で取得することができます。
Rest Membership - Redmine
(※APIの実装としてはStableではなく、Alphaのようです)

ファイルへ書き込む部分にidを配列に追加する処理を追加し、その配列変数を使用します。
またURLなど、何度か同じ文字列を使い回すので、変数で処理することにします。

require 'net/https'
require 'json'

api_key = "<API KEY>"
redmine_url = "<REDMINE URL>"

members = Array.new
projects_uri = URI.parse("#{redmine_url}/projects.json?key=#{api_key}")
File.open("projectlists.json", "w") {|file|
  file.write projectslist = Net::HTTP::get_response(projects_uri).body
  JSON.parse(projectslist)["projects"].each do |project|
    members_uri = URI.parse("#{redmine_url}/projects/#{project["id"]}/memberships.json?key=#{api_key}")
    members << JSON.parse(Net::HTTP::get_response(members_uri).body)
  end
}

members_hash = {"members" => members}
File.open("projectmembers.json", "w") {|file|
    file.write JSON.generate(members_hash)
}

これで、全てのプロジェクトのメンバーとそのロールが projectmembers.json ファイルに取得できます。

JSONデータの活用

APIで取得したいデータはJSON形式とXML形式で取得できますが、最近は比較的記述が簡易なJSON形式でデータを取り扱うことが多くなりました。 しかしながら文字の羅列として表現するため、可読性が高いとは言い難いです。

Microsoft社のExcelなどを使用して、表の形式で管理をすることが一般的なので、CSV形式に変換できると管理が楽という方も多いのではないでしょうか。

JSON形式のデータのをCSV形式に変換するのには、 jq というツールがよく利用されています。

jq
jq

スペースの都合上、jqについての説明を詳しくここでは書きませんが、上記サイトにチュートリアルや詳しいマニュアルが掲載されています。

例えば、ユーザアカウント一覧として取得するJSONデータをそのままCSV形式に変換しファイルに作成する場合は下記のようなコマンドになります。

curl <REDMINE URL>/users.json?key=<API KEY> | jq -r '["ID","ログインID","名","姓","メールアドレス","登録日","最終ログイン"], (.users[] | [.id, .login, .firstname, .lastname, .mail, .created_on, .last_login_on]) | @csv' > redmine_users.csv

結果として取得できるCSVファイル(例では redmine_users.csv )は下記のような内容になります。

"ID","ログインID","名","姓","メールアドレス","登録日","最終ログイン"
1,"admin","Redmine","Admin","admin@example.net","2017-02-07T02:40:50Z","2017-02-07T08:13:13Z"
5,"iwaishi","Mutsumi","Iwaishi","iwaishi@example.net","2017-02-07T05:12:39Z","2017-02-07T08:26:20Z"

上記プロジェクトメンバーの取得で取得した projectmembers.json は、下記のように実行すると、「プロジェクト名」、「氏名」、「ロール」のカラムのCSVファイルを作成できます。

cat projectmembers.json | jq -r '["プロジェクト名","氏名","ロール"], (.members[].memberships[] | [.project.name,.user.name,.roles[].name]) | @csv' > projectmembers.csv

次のようなCSVファイル(例では projectmembers.csv )が取得できます。

"プロジェクト名","氏名","ロール"
"project1","Iwaishi Mutsumi","開発者"
"project1",,"報告者"
"project2","Admin Redmine","管理者"
"project2","Iwaishi Mutsumi","管理者"

(※氏名が空のところは "匿名ユーザ" を表したものです。)

jqはとても高機能なJSON用のパーサーです。
便利な使い方が他にも沢山ありますが、パラメータの指定が難しいので一度にやろうとするとなかなかうまく行きません。
元となるJSONデータをファイルで取得しておき、jqのパラメータを少しづつ調節しながら求める出力形式に近づけていくのがオススメです。

注意

登録されているデータをアプリの仕様に関わらず、自由に利用できるWeb APIですが注意しなければいけいけないこともあります。

システムの負荷を考慮する

ブラウザを使用せず、コマンドやスクリプトで実行できるため、cronなどを使用して定期的に自動実行することもあると思います。この場合、APIアクセスの度にシステムは処理を行うため、あまり頻繁な使用(極端な例で言えば毎秒実行など)を行うとシステムへ著しい負荷を与える可能性があります。

取得する情報などにもよりますが、不必要に頻繁なアクセスは避けるべきです。

APIキーの管理

認証にAPIキーを使用するのですが、そのキーが紐付けられたアカウントの権限で情報の登録や取得が行われます。
よってキーは厳重に管理する必要があります。

キーを他人に見られることの無いように、暗号化通信(https)を使用してアクセスするのが望ましいです。GETメソッドではURLにキーを含めて通信しますが、httpsの場合URLはパラメータを含め、サーバとクライアントの間で暗号化されます。そのため、アクセスしたURLやキーが通信経路から他人に漏れることはありません。

また、社内などでAPIアクセスのスクリプトを共有する場合は、キーは環境変数などに登録し、ソースコードに実際のキーを含めないようにするのが良いと思われます。

最後に

APIを使用することで、

など様々な活用が考えられます。

Redmineのインストールだけで利用できますので、ぜひお試しください。