Neo4j 1.2 M06 is out – Better REST Indexing and Server Plugins!


Peter Neubauer

Hi all,

The Neo4j community is proud to release another milestone into the wild – Neo4j 1.2 M06. This time the main effort has been spent in two areas – a more complete REST API, and the first version of a plugin API for the Neo4j Server.

There has been a lot of feedback on the REST API and the server. Thanks to all contributors, mailing list discussions and real customers!

Integrated REST Index API


The new Index API that is integrated with the GraphDatabaseService is now exposed through REST, meaning that you can access the same indexes created through embedded Java. Rather than just a single index for nodes and another for relationships, it is now possible to have multiple named indexes of each type. Adding a node to an index automatically creates that index if it doesn’t already exist.

For instance, to add a (pre-existing) node to a node index called “persons”, you would POST:

curl -HContent-Type:application/json -X POST -d '"https://localhost:7474/db/data/node/123"' https://localhost:7474/db/data/index/node/persons/name/peter

Then, to look up all nodes that have a name property of “peter” in the “persons” index, simply GET:

curl -H Accept:application/json https://localhost:7474/db/data/index/node/persons/name/peter

For more thorough documentation of the REST API, see the API docs. They are even packaged with the download.

Server plugins – Hypermedia at work


Plugins provide an easy way to extend the Neo4j REST API with new functionality, without the need to invent your own API. You simply populate an Iterable of Node, Relationship or Path, specify parameters, point of extension and logic and voila, you are done! Look at this:

 

@Description( "An extension to the Neo4j Server for getting all nodes or relationships" )
public class GetAll extends ServerPlugin
{
@Name( "get_all_nodes" )
@Description( "Get all nodes from the Neo4j graph database" )
@PluginTarget( GraphDatabaseService.class )
public Iterable<Node> getAllNodes( @Source GraphDatabaseService graphDb )
{
return graphDb.getAllNodes();
}

 

@Description( "Get all relationships from the Neo4j graph database" )
@PluginTarget( GraphDatabaseService.class )
public Iterable<Relationship> getAllRelationships( @Source GraphDatabaseService graphDb )
{
return new NestingIterable<Relationship, Node>( graphDb.getAllNodes() )
{
@Override
protected Iterator<Relationship> createNestedIterator( Node item )
{
return item.getRelationships( Direction.OUTGOING ).iterator();
}
};
}
}

 

This will make your extension visible in the database representation (@PluginTarget) whenever it is served from the Neo4j Server (this could also be Node or Relationship), letting clients automatically discover it from e.g. at https://localhost:7474/db/data:

 

curl -v https://localhost:7474/db/data/

 

{
"extensions-info" : "https://localhost:7474/db/data/ext",
"node" : "https://localhost:7474/db/data/node",
"node-index" : "https://localhost:7474/db/data/index/node",
"relationship-index" : "https://localhost:7474/db/data/index/relationship",
"reference_node" : "https://localhost:7474/db/data/node/0",
"extensions" : {
"GetAll" : {
"get_all_nodes" : "https://localhost:7474/db/data/ext/GetAll/graphdb/get_all_nodes",
"getAllRelationships" : "https://localhost:7474/db/data/ext/GetAll/graphdb/getAllRelationships"
}
}

 

Requesting a GET on one of the two extension endpoints…

curl https://localhost:7474/db/data/ext/GetAll/graphdb/get_all_nodes

 

…gives back the meta information about the service:

{
"extends" : "graphdb",
"description" : "Get all nodes from the Neo4j graph database",
"name" : "get_all_nodes",
"parameters" : [ ]
}

To use it, just POST to this URL, with parameters as specified in the description (none in this case).

This way, plugins contribute hypermedia and still maintain the notion of a tight REST API which talks Nodes, Relationships and Paths. Some very real plugins we are thinking of in the near future (and that are less than 100 LoC):

  • global functions with parameters, like getting some named nodes by id.
  • custom traversal implementations
  • server-side scripting wrappers that can execute scripts (JavaScript, JRuby, Gremlin etc) installed in some server directory
  • plugins that let you execute a scripted payload from the request

We have put a couple of example plugins into the download under /examples/java, see https://components.neo4j.org/neo4j-examples/1.2-SNAPSHOT/ for online docs on them.

All in all, we think that we are getting pretty close to Neo4j 1.2 now, so stay tuned for the big push!




Want to learn more about graph databases? Click below to get your free copy of O’Reilly’s Graph Databases ebook and discover how to use graph technologies for your application today.

Download My Ebook