JAX-RSは単なるAPIです!

JAX-RSは単なるAPIです!

1. 概要

RESTパラダイムはかなりの数年前から存在しており、今でも多くの注目を集めています。

RESTful APIは、さまざまな方法でJavaに実装できます。Spring、JAX-RSを使用できます。または、十分に勇気があれば、独自のベアサーブレットを作成することもできます。 必要なのは、HTTPメソッドを公開する機能だけです。残りは、APIを呼び出すときにメソッドを整理する方法とクライアントをガイドする方法です。

タイトルからわかるように、この記事ではJAX-RSについて説明します。 しかし、「単なるAPI」とはどういう意味ですか? つまり、ここでの焦点は、JAX-RSとその実装の混乱を明確にし、適切なJAX-RS webappがどのように見えるかの例を提供することにあることを意味します。

2. JavaEEへの組み込み

JAX-RSは、Java EEが提供する仕様、インターフェースのセット、および注釈に過ぎません。 そしてもちろん、実装もあります。よく知られているのはRESTEasyJerseyです。

また、JEE準拠のアプリケーションサーバーを構築することに決めた場合、Oracleの担当者は、とりわけ、デプロイされたアプリが使用するJAX-RS実装をサーバーが提供する必要があることを教えてくれます。 そのため、Java Enterprise EditionPlatformと呼ばれています。

仕様と実装のもう1つの良い例は、JPAHibernate.です。

2.1. 軽量戦争

それで、開発者はこれをどのように助けますか? 役立つのは、デプロイ可能なものが非常に薄く、アプリケーションサーバーが必要なライブラリを提供できるようにすることです。 これは、RESTful APIを開発する場合にも当てはまります。最終的なアーティファクトには、使用されたJAX-RS実装に関する情報を含めないでください。

もちろん、実装を提供することはできます(hereのRESTeasyのチュートリアル)。 ただし、アプリケーションを「Java EEアプリ」と呼ぶことはできません。 明日誰かが来て「Ok, time to switch to Glassfish or Payara, JBoss became too expensive!」と言ったら、それはできるかもしれませんが、それは簡単な仕事ではありません。

独自の実装を提供する場合は、サーバーが独自の実装を除外することを確認する必要があります。これは通常、デプロイ可能な内部に独自のXMLファイルがあることで発生します。 言うまでもなく、このようなファイルには、3年前に退職した開発者を除き、誰も何も知らないあらゆる種類のタグと指示が含まれている必要があります。

2.2. サーバーを常に知っている

これまで、提供されているプラ​​ットフォームを利用する必要があると述べてきました。

使用するサーバーを決定する前に、少なくとも実稼働環境用に提供するJAX-RS実装(名前、ベンダー、バージョン、既知のバグ)を確認する必要があります。 たとえば、GlassfishにはJerseyが付属していますが、WildflyまたはJbossにはRESTEasyが付属しています。

もちろん、これは調査に少し時間がかかることを意味しますが、プロジェクトの開始時または別のサーバーへの移行時に1回だけ実行することになっています。

3. 例

JAX-RSでのプレイを開始する場合、最短パスは次のとおりです。pom.xmlに次の依存関係を持つMavenwebappプロジェクトがあります。


    javax
    javaee-api
    7.0
    provided

JavaEE 7を実装しているアプリケーションサーバーがすでにたくさんあるため、JavaEE7を使用しています。 そのAPIjarには、パッケージjavax.ws.rsにある、使用する必要のあるアノテーションが含まれています。 なぜスコープが「提供される」のですか? このjarは最終ビルドにもある必要がないため、コンパイル時に必要であり、実行時にサーバーによって提供されます。

依存関係が追加された後、最初にエントリクラスを作成する必要があります。javax.ws.rs.core.Applicationを拡張し、javax.ws.rs.ApplicationPath:で注釈が付けられた空のクラスです。

@ApplicationPath("/api")
public class RestApplication extends Application {
}

エントリパスを/api.として定義しました。リソースに対して宣言する他のパスに関係なく、プレフィックスとして/apiを付けます。

次に、リソースを見てみましょう。

@Path("/notifications")
public class NotificationsResource {
    @GET
    @Path("/ping")
    public Response ping() {
        return Response.ok().entity("Service online").build();
    }

    @GET
    @Path("/get/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getNotification(@PathParam("id") int id) {
        return Response.ok()
          .entity(new Notification(id, "john", "test notification"))
          .build();
    }

    @POST
    @Path("/post/")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response postNotification(Notification notification) {
        return Response.status(201).entity(notification).build();
    }
}

アプリを実行しているかどうかを確認する単純なpingエンドポイント、通知用のGETおよびPOST(これは属性とゲッターおよびセッターを含むPOJOです)。

この戦争をJEE7を実装するアプリケーションサーバーに展開すると、次のコマンドが機能します。

curl http://localhost:8080/simple-jaxrs-ex/api/notifications/ping/

curl http://localhost:8080/simple-jaxrs-ex/api/notifications/get/1

curl -X POST -d '{"id":23,"text":"lorem ipsum","username":"johana"}'
  http://localhost:8080/simple-jaxrs-ex/api/notifications/post/
  --header "Content-Type:application/json"

simple-jaxrs-exは、webappのcontext-rootです。

これは、Glassfish 4.1.0およびWildfly 9.0.1.Finalでテストされました。 thisのバグのため、最後の2つのコマンドはGlassfish4.1.1では機能しないことに注意してください。 JSONのシリアル化に関して、このGlassfishバージョンでは明らかに既知の問題です(このサーバーバージョンを使用する必要がある場合は、JSONマーシャリングを自分で管理する必要があります)

4. 結論

この記事の最後で、JAX-RSは強力なAPIであり、必要なもののほとんど(すべてではないにしても)がWebサーバーによって既に実装されていることに留意してください。 デプロイ可能なものを管理できないライブラリの山に変える必要はありません。

この記事は簡単な例を示しており、事態はさらに複雑になる可能性があります。 たとえば、独自のマーシャラーを作成する場合があります。 それが必要な場合は、Jersey、Resteasy、またはその他の具体的な実装ではなく、JAX-RSの問題を解決するチュートリアルを探してください。 問題は1つまたは2つの注釈で解決できる可能性が非常に高いです。