4.7. アンマネージド拡張機能

プロジェクトによっては、サーバーサイドコードを緻密に管理したいこともあります。このような場合のために開発チームが用意したのが、アンマネージド拡張機能 API です。アンマネージド拡張機能は切れ味の鋭いツールで、ユーザーが任意の JAX-RS クラスをサーバーにデプロイすることができるため、その利用については慎重に検討する必要があります。特に、サーバー上で簡単に大量のヒープ空間を消費してしまい、注意を怠るとパフォーマンスが大きく損なわれるおそれがある点についてはよく理解しておく必要があります。そうした注意事項を理解したうえでアンマネージド拡張機能を利用する場合、使用する JAX-RS クラスを Neo4j Server にロードするには、コードに @Context アノテーションを追加し、Neo4j jar とコンパイルし、使用するクラスを実行時のクラスパスに追加します (Neo4j Server の lib ディレクトリに置きます)。このようにすることで、org.neo4j.server.logging.Logger を介したログの記録をはじめ、Neo4j Server によってホストされる環境にアクセスして利用できるようになります。

コードでは、次に示すように @Context アノテーションを介して、 Neo4j Server の下で動作する GraphDatabaseService にアクセスできます。

public MyCoolService(@Context GraphDatabaseService database)
{
  // Have fun here, but be safe!
}

繰り返しますが、アンマネージド拡張機能は非常に鋭利なツールです。アンマネージド拡張機能を使ってコードをデプロイし場合、サーバーに悪影響を及ぼすことも非常に簡単にできるので、まず最初に、ほんとうにマネージド拡張機能を優先的に使うことができないケースなのかどうか、しっかりと見極める必要があります。ただし、データベースへの参照のように、自動的に用意されるコンテキストパラメータもいくつかあります。

作成した拡張機能のマウントポイントを指定する場合、クラス全体は次のようになります。

@Path( "/helloworld" )
public class HelloWorldResource
{

    private final GraphDatabaseService database;

    public HelloWorldResource( @Context GraphDatabaseService database)
    {
      this.database = database;
    }

    @GET
    @Produces( MediaType.TEXT_PLAIN )
    @Path( "/{nodeId}" )
    public Response hello( @PathParam( "nodeId" ) long nodeId )
    {
        // Do stuff with the database
        return Response.status( Status.OK ).entity(
                ( "Hello World, nodeId=" + nodeId).getBytes() ).build();
    }
}

このコードをビルドし、作成された jar ファイルを (依存パッケージがある場合はそれらのパッケージも含めて) $NEO4J_SERVER_HOME/plugins ディレクトリに置き、次の要領でこのクラスを neo4j-server.properties に追加します。

#Comma separated list of JAXRS packages containing JAXRS Resource, one package name for each mountpoint.
org.neo4j.server.thirdparty_jaxrs_classes=org.neo4j.examples.server.unmanaged=/examples/unmanaged

curl http://localhost:7474/examples/unmanaged/helloworld/123

上のコマンドを実行すると、次の結果が返されます。

Hello World, nodeId=123