Getting started with the Neo4j Java Rest Binding (Heroku deployment)
Believe it or not, the last couple of days were my first attempt at using Neo4j’s Java Rest Binding. My earlier application on Heroku, Flavorwocky, used the Grails Neo4j plugin and for other stuff including work, embedded Neo4j rules.
However, embedded won’t do when deploying to Heroku, so the Java Rest Binding it is. Much better than dealing with raw REST, especially if you are very used to the embedded api’s.
Since it took me a short while to figure things out, mostly due to my shameful lack of Maven knowledge, thought I’d post a simple “getting started” guide.
At the end of this, your application and Neo4j should be talking to each other.
Note 1: This article deals with the rest binding for Neo4j 1.8.1, which is the version used by my Heroku application.
Note 2: Add the Neo4j add-on to your Heroku application if you do plan on trying this out
Step 1: Get/Include the library
If you are not deploying to Heroku and/or want to just include the jars, pick them up from here: http://m2.neo4j.org/content/groups/everything/org/neo4j/neo4j-rest-graphdb/1.8.1/
If you like/have to use maven, include the following dependency in your pom.xml
<dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j-rest-graphdb</artifactId> <version>1.8.1</version> </dependency>
The dependency refused to resolve until I added the following:
<repositories> <repository> <id>mvn-neo4j</id> <url>http://m2.neo4j.org/content/groups/everything</url> </repository> </repositories>
Step 2: Connect to your local Neo4j server
I created a simple servlet to test code and figure out the library, you might add this code to whatever you like.
RestAPI graphDb = new RestAPIFacade("http://localhost:7474/db/data");
Note that you can also use
GraphDatabaseService graphDb=new RestGraphDatabase(“http://localhost:7474/db/data”);
which is what I attempted to use first, and it does work, but doesn’t seem to be a valid parameter when creating a RestCypherQueryEngine (see step 3)
Step 3: Does it work?
Execute a Cypher query to return the number of nodes in the database.
QueryEngine engine=new RestCypherQueryEngine(graphDb); QueryResult<Map<String,Object>> result= engine.query("start n=node(*) return count(n) as total", Collections.EMPTY_MAP); Iterator<Map<String, Object>> iterator=result.iterator(); if(iterator.hasNext()) { Map<String,Object> row= iterator.next(); out.print("Total nodes: " + row.get("total")); }
Step 4: Let’s find out
Now is a good time to start your Neo4j server if you haven’t already.
If you’re using Tomcat and following the guide here https://devcenter.heroku.com/articles/create-a-java-web-application-using-embedded-tomcat then build and run:
mvn package sh target/bin/webapp
or launch your web application otherwise.
Access your servlet/jsp/anything else and you should see the count of nodes in your Neo4j database. A new database will return 1 node (the reference node)
Step 5: Deploy to Heroku
The URL to your Neo4j database on Heroku can be found in the NEO4J_URL environment variable so you don’t need to hardcode this in your application.
The variable value looks like this:
http://username:password@db.hosted.neo4j.org:port
Pick up the variable in your application code using
String neoUrl=System.getenv("NEO4J_URL");
and parse it to extract the username, password and db URL (http://db.hosted.neo4j.org:port)
Modify your code to now accept a username and password:
GraphDatabaseService graphDb=new RestGraphDatabase(dbUrl + “/db/data”,username,password);
Push changes to heroku, access your application, and you should see the count of nodes in your remote instance.
Step 6: Add a node just to be really sure
Transaction tx = graphDb.beginTx(); Map<String,Object> props=new HashMap<String, Object>(); props.put("id",100); props.put("name","firstNode"); Node node=graphDb.createNode(props); tx.success(); tx.finish();
Execute the same Cypher query to fetch the count of nodes and you should see it increment by 1.
If you can’t wait to see the REST calls that the binding is actually producing, you can turn on logging. As per the documentation, you need to set the system property org.neo4j.rest.logging_filter to true. mI saw the REST calls being logged on my Tomcat console.
Further googling told me that I could set this property on Heroku by adding it as an extraJvmArgument in the appassembler-maven-plugin in pom.xml:
<configuration> <assembleDirectory>target</assembleDirectory> <programs> <program> <mainClass>launch.Main</mainClass> <name>webapp</name> </program> </programs> <extraJvmArguments>-Dorg.neo4j.rest.logging_filter=true</extraJvmArguments> </configuration>
That’s it! You should now be able to manipulate your graph using Cypher or the core API, but more on transactions and batching in Part 2.
Thanks a lot Luanne. That was a really useful post. Found exactly what I was looking for.
Please implement a graph database (a kind of NoSQL). This graph database should consist of nodes (with have properties) for entities and edges (which have single or multiple properties and can be directional or bidirectional) for relationships, and support node indexing and query. The query language has following keywords: START, MATCH, WHERE, RETURN, ORDER BY, AGGREGATE, SKIP, and LIMIT. Example Input: Node martin = graphDB.createNode(); martin.setProperty(“name”, “Martin”); Node pramod = graphDB.createNode(); pramod.setProperty(“name”, “Pramod”); Node barbara = graphDB.createNode(); pramod.setProperty(“name”, “Barbara”); martin.createRelationshipTo(pramod, FRIEND, since = 1998); pramod.createRelationshipTo(martin, FRIEND, since = 1998); martin.createRelationshipTo(barbara, FRIEND); barbara.createRelationshipTo(martin, FRIEND); START node = Node:nodeIndex(name = “Barbara”) MATCH… Read more »