Neo4j is not only available in embedded mode. It can also be installed and run as a stand-alone server accessible via a REST API. Developers can integrate Spring Data Graph into the Neo4j server infrastructure in two ways: in an unmanaged server extension, or via the REST API.
When should you write a server extension? The default REST API is essentially a REST'ified representation of the Neo4j core API. It is nice for getting started, and for simpler scenarios. For more involved solutions that require high-volume access or more complex operations, writing a server extension that is able to process external parameters, do all the computations locally in the plugin, and then return just the relevant information to the calling client is preferable.
The Neo4j Server has two built-in extension mechanisms. It is possible to extend existing URI endpoints like the graph database, nodes, or relationships, adding new URIs or methods to those. This is achieved by writing a server plugin. This plugin type has some restrictions though.
For complete freedom in the implementation, an
unmanaged extension
can be used. Unmanaged extensions are essentially Jersey
resource implementations. The resource constructors or methods can get the
GraphDatabaseService
injected to execute the necessary operations and return appropriate
Representations
.
Both kinds of extensions have to be packaged as JAR files and added to the Neo4j Server's plugin
directory. Server Plugins are picked up by the server at startup if they provide the necessary
META-INF.services/org.neo4j.server.plugins.ServerPlugin
file for Java's ServiceLoader
facility. Unmanaged extensions have to be registered with the Neo4j Server configuration.
Example 26.1. Configuring an unmanaged extension
org.neo4j.server.thirdparty_jaxrs_classes=com.example.mypackage=/my-context
Running Spring Data Graph on the Neo4j Server is easy. You need to tell the server where to find the Spring context configuration file, and which beans from it to expose:
Example 26.2. Server plugin initialization
public class HelloWorldInitializer extends SpringPluginInitializer { public HelloWorldInitializer() { super(new String[]{"spring/helloWorldServer-Context.xml"}, Pair.of("worldRepository", WorldRepository.class), Pair.of("graphRepositoryFactory", GraphRepositoryFactory.class)); } }
Now, your resources can be annotated with the beans they need, like this:
Example 26.3. Jersey resource
@Path( "/path" ) @POST @Produces( MediaType.APPLICATION_JSON ) public void foo( @Context WorldRepository repo ) { ... }
The SpringPluginInitializer
merges the GraphDatabaseService with the Spring configuration
and registers the named beans as Jersey Injectables
. It is still necessary to list the
initializer's fully qualified class name in a file named
META-INF/services/org.neo4j.server.plugins.PluginLifecycle
. The Neo4j Server can then pick
up and run the initialization classes before the extensions are loaded.
Spring Data Graph can use a set of Java REST bindings which come as a drop in replacement for the
GraphDatabaseService API. By simply configuring the graphDatabaseService
to be a
RestGraphDatabase
pointing to a Neo4j Server instance.
The Neo4j Server REST API does not allow for transactions to span across requests, which means
that Spring Data Graph is not transactional when running with a RestGraphDatabase
.
To set up your project to use the REST bindings, add this dependency to your pom.xml:
Example 26.4. REST-Client configuration - pom.xml
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-neo4j-rest</artifactId> <version>1.0.0.RELEASE</version> </dependency>
Now, you set up the normal Spring Data Graph configuration, but point the database to an URL instead
of a local directory, like so:
Example 26.5. REST client configuration - application context
<datagraph:config graphDatabaseService="graphDatabaseService"/> <bean id="graphDatabaseService" class="org.neo4j.rest.graphdb.RestGraphDatabase"> <constructor-arg value="http://localhost:7474/db/data/"/> </bean>
Your project is now set up to work against a remote Neo4j Server.