Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow customised package names in Cypher type system #4

Closed
johannessen opened this issue Nov 15, 2019 · 5 comments
Closed

Allow customised package names in Cypher type system #4

johannessen opened this issue Nov 15, 2019 · 5 comments
Assignees
Labels
enhancement New feature or request

Comments

@johannessen
Copy link
Owner

The package names that this driver’s Cypher type system uses to bless objects like Neo4j nodes and Neo4j relationships returned from executed queries should be customisable. This would support clients adding their own methods to such objects. See majensen/rest-neo4p#20 (comment) for an example of how this might work.

API usage might look like this:

use Neo4j::Driver;

my $driver = Neo4j::Driver->new('bolt://localhost')->basic_auth(...);
$driver->config(cypher_types => {
    node => 'REST::Neo4p::Node',
    ...
});

my $query = 'CREATE (n) SET n = {properties} RETURN n';

my $result = $driver->session->run($query, properties => {...});
my $node = $result->single->get();
say $node->isa('REST::Neo4p::Node');  # result: 1

The client’s type package could implement any methods that it likes. For example, REST::Neo4p::Node might wish to offer methods such as new() or add_labels(), which Neo4j::Driver::Type::Node doesn’t have.

@johannessen
Copy link
Owner Author

johannessen commented Nov 15, 2019

A possible problem with this approach is that the client’s type package would use the exact same data structure as the Neo4j::Driver type package does. This might violate encapsulation and result in more brittle code.

To combat this, Neo4j::Driver should document that direct data structure access is unsupported, even from the client’s package. Instead, clients should inherit from the Neo4j::Driver type package using @ISA (or equivalent) and use the accessor methods provided.

package REST::Neo4p::Node;

# Bad example
sub add_labels {
    my $id = shift->{_meta}->{id};  # Don't do this!
    ...
}

# Good example
our @ISA = qw( Neo4j::Driver::Type::Node );
sub add_labels {
    my $id = shift->id();
    ...
}

Additionally, Neo4j::Driver should provide at least one hash key for safe internal use by the client. For example, Neo4j::Driver documentation could guarantee to never use hash keys beginning with __, so that methods in REST::Neo4p::Node could use $_[0]->{__whatever} to store any private data they may need to store.

@johannessen johannessen added enhancement New feature or request good first issue Good for newcomers labels Nov 15, 2019
@johannessen johannessen self-assigned this Dec 16, 2019
@johannessen johannessen added question Further information is requested and removed good first issue Good for newcomers labels Dec 21, 2019
@johannessen
Copy link
Owner Author

Initial implementation landed, see "Type system customisation" in Neo4j::Driver 0.14. Would @majensen consider this suitable for adapting REST::Neo4p to use Neo4j::Driver? Are any other changes to Neo4j::Driver necessary (or perhaps just useful)?

@majensen
Copy link

Will have a go at this

@johannessen
Copy link
Owner Author

Great! Just let me know what you need.

@johannessen johannessen removed the question Further information is requested label Oct 12, 2020
@johannessen
Copy link
Owner Author

With REST::Neo4p 0.4000 released, I guess this can be closed.

But I like the flexibility this option provides, and am leaning towards eventually making it a stable feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants