Spring Data Neo4j + Spring Data Rest: Using a Natural Key for all CRUD operations instead of the Neo4J node Id - spring-data-neo4j

I'm writing writing a Spring Restful microservice that relies on Spring Data Rest and Spring Data Neo4J.
We don't want to expose the internal Neo4J node identifier in the HAL links of the JSON response. The reason being (as far as I understand) that these identifiers are reused by Neo4J in case of node deletion. If this is the case this will present us with data integrity problems. And so we'd rather use a natural key, for example, UUID. Please correct me if my assumption regarding the reuse of neo4J node Ids is wrong.
What we want to achieve is using a Natural Key for all CRUD operations instead of the node Id (ie: PUT http://localhost:8080/apiname/5448ae86-fe87-4daf-bfb5-985522a1cf14 with some body).
Our first approach was to extend NodeGraphRepositoryImp . E.g.
protected Node getById(UUID id) {
Node node = (Node) this.findByPropertyValue("uuid_id", id);
return template.getNode(node.getId());
}
And instantiate it by injecting a customized Neo4jTemplate in the Neo4J configuration.
However this approach doesn't work for the following reasons:
1) I cannot define any other idProperty different from the one annotated with #GraphId in the NodeEntity class. As a result Spring Data Rest ends up trying to assign the natural key (e.g. UUID) to the neo4j node id field (that is a Long) and fails on type conversion.
2) It seems that the Spring Data Neo4J is not using our custom class that extends NodeGraphRepositoryImpl but the original not extended NodeGraphRepositoryImpl class instead.
Maybe this approach is wrong. Could you please recommend a way to achieve it?
Thanks a lot for your help.

Spring Data Rest introduced a BackendIdConverter for overriding/customizing the field that gets exposed in the URIs.
Please have a look at DATAREST-155 (https://jira.spring.io/plugins/servlet/mobile#issue/DATAREST-155)
Can you give it a try?
You can also have a look at the following thread:
How can you customise self, parent, children links in spring data rest with neo4j

Related

Best way to stock tokens with WSO2 Enterprise Integrator

I am working on some systems that needs to use Access and Refresh tokens.
In my process now, I save tokens in registry, and I update them when they need to be updated. But sometimes, I get an error because one of my process tries to retrieve a token, but this token has been changed just before (like a lock in the registry).
What is the best way to store, update and retrieve that kind of informations ?
I tried to use a class mediator which stores properties in a Hashmap, but WSO2 always create a new instance of my custom class, so a new instance of my hashmap.
Any idea ? Thank you !
The usual practice to store the token is in the registry. This is used in the connector implementation [1] in the ESB server. Could you elaborate more on the issue? What is the ESB server version? What is the error stack trace? Have you used a similar implementation as in [1]?
Further to answer your question regarding the class mediator, you can use a static variable in the class mediator to share the token among the objects created. But then again, static variables are not thread-safe.
[1]-https://github.com/wso2-extensions/esb-connector-gmail/blob/master/src/main/resources/config/getAccessTokenFromRefreshToken.xml
I'm using the registry for reading / storing data, and here is some issue..
When you read using property mediator, for example token - he is also cached for default 15sec. So after read, revoke new one, and store back - you will still get from property mediator the "old" one. This can be bypassed, using script mediator and store registry entry using code, and setting the CachableDurationto 0.
I described this reading storing from registry in my blog, check out especially the Known downside paragraph.

Designing RESTful API for Invoking process methods

I would like to know how do design the RESTful web service for process methods. For example I want to make a REST Api for ProcessPayroll for given employee id. Since ProcessPayroll is time consuming job, I don't need any response from the method call but just want to invoke the ProcessPayroll method asynchronously and return. I can't use ProcessPayroll in the URL since it is not a resource and it is not a verb. So I thought that, I can go with the below approach
Request 1
http://www.example.com/payroll/v1.0/payroll_processor POST
body
{
"employee" : "123"
}
Request 2
http://www.example.com/payroll/v1.0/payroll_processor?employee=123 GET
Which one of the above approach is correct one? Is there any Restful API Design guidelines to make a Restful service for process methods and functions?
Which one of the above approach is correct one?
Of the two, POST is closest.
The problem with using GET /mumble is that the specification of the GET method restricts its use to operations that are "safe"; which is to say that they don't change the resource in any way. In other words, GET promises that a resource can be pre-fetched, just in case it is needed, by the user agent and the caches along the way.
Is there any Restful API Design guidelines to make a Restful service for process methods and functions?
Jim Webber has a bunch of articles and talks that discuss this sort of thing. Start with How to GET a cup of coffee.
But the rough plot is that your REST api acts as an integration component between the process and the consumer. The protocol is implemented as the manipulation of one or more resources.
So you have some known bookmark that tells you how to submit a payroll request (think web form), and when you submit that request (typically POST, sometimes PUT, details not immediately important) the resource that handles it as a side effect (1) starts an instance of ProcessPayroll from the data in your message, (2) maps that instance to a new resource in its namespace and (3) redirects you to the resource that tracks your payroll instance.
In a simple web api, you just keep refreshing your copy of this new resource to get updates. In a REST api, that resource will be returning a hypermedia representation of the resource that describes what actions are available.
As Webber says, HTTP is a document transport application. Your web api handles document requests, and as a side effect of that handling interacts with your domain application protocol. In other words, a lot of the resources are just messages....
We've come up with the similar solution in my project, so don't blame if my opinion is wrong - I just want to share our experience.
What concerns the resource itself - I'd suggest something like
http://www.example.com/payroll/v1.0/payrollRequest POST
As the job is supposed to be run at the background, the api call should return Accepted (202) http code. That tells the user that the operation will take a lot time. However you should return a payrollRequestId unique identifier (Guid for example) to allow users to get the posted resource later on by calling:
http://www.example.com/payroll/v1.0/payrollRequest/{payrollRequestId} GET
Hope this helps
You decide the post and get on the basis of the API work-
If your Rest API create any new in row DB(means new resource in DB) , then you have to go for POST. In your case if your payroll process method create any resource then you have to choose to POST
If your Rest API do both, create and update the resources. Means ,if your payroll method process the data and update it and create a new data , then go for PUT
If your Rest API just read the data, go for GET. But as I think from your question your payroll method not send any data.So GET is not best for your case.
As I think your payroll method is doing both thing.
Process the data , means updating the data and
Create new Data , means creating the new row in DB
NOTE - One more thing , the PUT is idempotent and POST is not.Follow the link PUT vs POST in REST
So, you have to go for PUT method.

Retrieving a process Instance diagram in Camunda

I have been trying to retrieve a process instance diagram from Camunda engine. All the JAVA and REST methods deal with retrieving the deployed process diagram. So, the closest I am is this method.
InputStream getProcessDiagram(String processDefinitionId)
But its of no use to me as I want to be able to get the current state of the particular process instance.
The process diagram representing the current state can be viewed in Camunda Tasklist but I have no clue as to how to retrieve it.
Thanks!
The diagram with its state does not simply come from the REST API as is. Instead, data from two sources is collected:
GET /process-definition/{id}/xml provides the BPMN diagram (which you have already found) [1]
GET /process-instance/{id}/activity-instances provides the state of a process instance in a tree structure [2]
The tasklist has some client-side logic that renders the BPMN XML with bpmn.io and places markers on top of it based on the activity instance tree.

Is there a way to map an object graph with #Query?

I'm am trying to migrate my SDN3 embedded configuration to using SDN 3.3.0 with a Neo4j instance in server mode (communicating via the REST API then).
When the DB was embedded making a lot of small hits to the DB was not a big deal as Neo4j is capable of handling this kind of queries super fast.
However now that I run my Neo4j separately from my application (ie. in server mode) making a lot of small queries is not advisable because of the network overhead.
User user = userRespository.findOne(123);
user.fetch(user.getFriends());
user.fetch(user.getManager());
user.fetch(user.getAgency());
This will trigger quite a few queries, especially if I want to get, not a single user, but a list of users.
Can I use the #Query annotation and fetch the user and the related entities and map it into an User object?
I was thinking of something like this:
#Query("MATCH (u:User)-[r:FRIEND]->(f) RETURN u,r,f"
Is such a thing possible with Spring Data Neo4j? Will it be possible with Spring Data Neo4j 4?
You can define a class for query result using the #QueryResult directive and let the method for the query return an object of that class, i.e.:
#QueryResult
public interface UserWithFriends {
#ResultColumn("u")
User getUser();
#ResultColumn("f")
List<User> friends();
}
#Query("MATCH (u:User)-[:FRIEND]->(f) WHERE u.name={name} RETURN u,f")
UserWithFriends getUserByName(#Param("name") String name);

How to limit nodes retrievable via Service module in Drupal?

I've put together a simple web service in my Drupal website, using the apposite module (Services). Now, i can check the endpoint "node" and "retrieve" inside the module, for it to expose content of nodes of my website, but i don't really want to include EVERY node in it. I'd rather want to expose only a couple of selected contents.
To explain myself better: i need to expose the content of my 'disclaimer' nodes to a mobile app, but activating the node-retrieve endpoint means all nodes are exposed and i don't really want it.
So, there's a way to limit which node must be exposed via the Service module endpoint node-retrieve?
You can use services_entity module, and use pagesize query parameter to return a specific number of nodes.
Example: return 15 nodes of type page
/api/node?pagesize=15&parameters[type]=page