JerseyとSwaggerでRESTfulなWebAPIサービスを作る(前編)

スクリーンショット 2016-06-20 20.31.13

前書き

ネットはお気楽に使いたい人なので、普段はあまりこういった技術的なネタは意図的に書かないようにしているのですが、色々考えるところがあり、珍しく書こうかなと思います。blogにこういうの書くのは4年ぶりみたいです。

んで、ネタは何にしようという話になるのですが、WebAPIを利用して色々な物を作ろうというエントリは巷に沢山あふれているけど、API自体を作ろうという話はあまり見ないようなそんな気がするので、JerseyとSwaggerを使ってRESTfulなWeb APIを作ってみようと思います。

長くなるので、前編後編、あと番外編に分けます。前編はJerseyを使ったAPIサービスを作ります。サンプルとして簡単な2値の四則演算を行うWebAPIを作成していきます。 後編では作ったAPIのドキュメントをSwaggerを使って自動生成していきます。 番外編ではRESTful APIの設計について触れればと思います。

内容としてはJavaの初学者向けに出来るだけ平易な文章とソースコードを全文載せることを意識して書いていきます。初学者向けに書いていくので説明が冗長ですが、わかりやすさ重視でいきましょう。ではでは。

ソースコードは僕にしては珍しくgithub上にアップロードしてあります。 https://github.com/touka1037/JerseyHandsOn

Jerseyって?

というわけで、皆さんはWebAPI使っておりますでしょうか? 巷にはありとあらゆるWebAPIが公開されていて、有名どころを挙げるとすると以下ですかね。

今やいろんなWebサービスがAPIを公開しているので、Webサーバと連携したクライアントアプリケーションを開発する際に、HTMLデータを強引にスクレイピングして・・・なんてことをしている人はあまりいないと思います。(まさかいないですよね?)

ではでは、これらをどのように作っていくかというと、便利なものでRESTfulなAPIサービスを作るためのフレームワークが世の中には既に沢山有るわけですね。今回触っていくJerseyも数あるRESTfulなAPIサービスを作るためのフレームワークの一種です。(他にもRESTeasyとかApache CXFみたいなフレームワークがあります)

サービスを設計しよう

では早速コードを・・・と行く前に、どんなサービスを作るのかを考えていきます。 今回は冒頭に少し書いたとおり、四則演算サービスを作っていきます。四則演算をするに当たって、どのようなHTTPリクエストを行えばいいかを考える必要があります。 今回はリクエストパスにどのような演算をするのかを明記し、リクエストボディに二つの値を設定するという形にしましょう。具体的には以下のような設計にしていきます。

メソッド URL 機能
POST ドメイン名/v1/calc/plus aとbを加算する。
POST ドメイン名/v1/calc/minus aからbを減算する。
POST ドメイン名/v1/calc/times aとbを乗算する。
POST ドメイン名/v1/calc/per aからbを除算する。

つづけて、今度はリクエストボディを設計します。aとbを設定できれば良いので、以下のような形ですかね。

最後に、どのようなレスポンスを返すのかを決めます。ここでは計算結果を返せば良いですね。

余談ですが、上記の設計は良い設計ではなく、ダメダメな設計だったりします。が、今回はあくまでハンズオンと言うことでこの設計でいきます。 RESTfulなAPIの設計はそれだけで本が1冊書けてしまう結構奥が深い世界です。設計については番外編と言うことで、後日書ければ良いかなと思います。 興味がある方は以下の書籍が参考になります。どちらも良い本です。

Mavenの設定

お待たせしました。では早速サービスを作っていきましょう。適当なIDEで新規のMavenプロジェクトを作成しましょう。作る際には雛形として「maven-archetype-webapp」を選択し、groupIDやartifactIdはお好みで。

スクリーンショット 2016-06-20 21.47.32

Mavenプロジェクトが出来たらpom.xmlを編集します。

上記の17~28行目と32~41行目が追記した箇所です。前者はコメントの通りJerseyの設定です。jersey-media-moxyはJSONを扱う場合に必要です。XMLだけサポートするのであれば必要ありません。後者はweb.xmlの設定です。 Jerseyではサーブレットの設定をする方法が幾つかありまして、詳しくはJerseyのドキュメントにあるとおりなのですが。今回の例ではApplicationサブクラスを作る方法をとります。この方法をとった場合web.xmlはいらなくなるので、不要ですよという設定をしているわけですね。

Applicationサブクラスの作成

アプリケーションの実装に当たって、パッケージを3つ作りました。それぞれ以下のように分けています。

  • config : アプリケーション全般の設定
  • models : レクエストやレスポンスをマッピングするPOJO
  • resources : HTTPリクエストしたときの動作定義

スクリーンショット 2016-06-20 22.16.48

では早速、config配下にApplicationConfigクラスを作成しましょう。

これは公式ドキュメントのサンプルのままですね。ここではリソースクラスを追加してるぐらいで、特別なことは特に何もしていません。このクラスは後編でまた少し触りますが、今はこれだけで十分です。

POJOの作成

先ほどどのようなリクエストボディに対してどのようなレスポンスボディを返すのかを設計したけど、それをそっくりそのままPOJOにしてしまいましょう。 まずリクエストボディに対応するPOJO

つづいて、レスポンスボディに対応するPOJO

どちらも@XmlRootElementアノテーションをclassの頭につけてますが、共にリクエスト、レスポンスのルートオブジェクトとしてマッピングするので記載が必要です。

APIの動作定義

最後にリソースクラスを作っていく。まずは加算処理から。

Jerseyでは@Pathアノテーションと@GET/@POST/@DELETE/@PUTアノテーションを使って、HTTPリクエストをどのメソッドで処理するかを指定します。上記の例では/calc/plusというパスにPOSTメソッドでリクエストをした際に、addValueメソッドが呼ばれるという感じです。 @Consumesアノテーションはリクエストボディの形式を指定しています。同様に@Produceアノテーションでレスポンスボディの形式が指定できます。共に複数指定することが出来て、上記の例ではContent-typeがapplication/json、application/xmlの入出力をするメソッドだと言うことを指定しています。 addValuesの引数calcReqにはPOJOマッピング済みのリクエストが入っています。 関数の返値にはResponseオブジェクトを返していますが、ここでリクエストのHTTPHeaderの内容を参照しています。 これはリクエストHeaderのContent-typeがapplication/jsonならJSON形式で、application/xmlならXML形式で返すという動作にしています。ここでもPOJOからJSON、XMLへの変換はお任せなので楽ちんですね。

同様に、減算処理等を実装しましょう。最終的にCalcResourceクラスは以下になります。

動かしてみる

今回はローカルに立てたTomcatにWARをデプロイしましょう。IDEで実行環境の設定をして実行しましょう。 スクリーンショット 2016-06-20 23.05.40

デプロイが終わったら、HTTPリクエストを投げてみましょう。Advanced REST clientのようなGUIのクライアントを利用しても良いですが、サクッとcurlコマンドでリクエストを投げてみましょう。

http://localhost:8080/v1/calc/plusにPOSTでリクエストを投げると、きちんとレスポンスコード200と計算結果がJSON形式で返ってきていますね。

今度はxml形式でリクエストを投げてみましょう。

XMLでレスポンスが返ってきていますね。

ひとまず、これで簡単なAPIの実装が出来ました。随分と長くなってしまいましたので、前編はいったんここまでとします。後編では今回作成したAPIのドキュメントをSwaggerで作成していきます。 それではお疲れ様でした。


コメントを残す