NAME
Neo4j::Driver::Deprecations - Explains features that have been deprecated, but not yet removed
VERSION
version 0.47
OVERVIEW
Deprecated features are removed from the pod documentation of the individual modules in this distribution in an attempt to keep those short and clear. This document describes all features that are deprecated, but still working for completeness' sake, briefly explains the reason for their deprecation, and suggests alternatives where possible.
The intention is that most deprecated features will be removed with the next major update to Neo4j::Driver. There is no schedule for the release of that update (version 1.00), but there is a decent chance that it will happen in the year 2022.
Neo4j::Driver
close()
Deprecated in version 0.14 and to be removed in 1.00. Originally added in 0.02 as an experimental feature.
$driver->close; # no-op
All resources opened by the Perl driver are closed automatically once they are no longer required. Explicit calls to close()
are neither required nor useful.
Config option ca_file
Deprecated in version 0.15 and to be removed in 1.00. Originally added in 0.13 as an experimental feature.
$driver->config(ca_file => 'neo4j/certificates/neo4j.cert');
Specifies the location of a local copy of the server certificate for the then-experimental HTTPS self-signed certificate support. The driver config option ca_file
corresponded to SSL_ca_file
in LWP::UserAgent and IO::Socket::SSL.
This option was renamed tls_ca
in version 0.15 to be more consistent with the tls
option, then later renamed trust_ca
in version 0.27 to be more consistent with the Neo4j Driver API. See "trust_ca" in Neo4j::Driver::Config.
Custom networking modules
Deprecated in version 0.31 and to be removed in 1.00. Originally added in 0.21 as an experimental feature.
use Local::MyNetModule;
$driver->config(net_module => 'Local::MyNetModule');
The module to be used for network communication may be specified using the net_module
config option. The specified module must implement the API described in "EXTENSIONS" in Neo4j::Driver::Net. Your code must use
or require
the module it specifies here.
The default value of undef
will cause the driver to use its built-in modules. An empty string ""
will do the same.
# use the built-in networking modules
$driver->config(net_module => undef);
$driver->config(net_module => '');
Some versions of the driver also allow users to run its test suite against a custom net module.
TEST_NEO4J_NETMODULE=Local::MyNetModule prove
The net_module
option provides decent flexibility for extending the driver. However, some interesting possible extensions have little to do with networking, and the net_module
API itself lacks flexibility.
Existing networking modules should be converted to HTTP network adapters. This is easily done with the the following two steps.
Rename your existing
sub new {}
constructor to (for example)sub _net_module_new {}
.Insert the following code into your module:
use parent 'Neo4j::Driver::Plugin'; sub new { bless [], shift; } sub register { my ($self, $manager) = @_; $manager->add_handler( http_adapter_factory => sub { my ($continue, $driver) = @_; __PACKAGE__->_net_module_new($driver); }, ); }
See "http_adapter_factory" in Neo4j::Driver::Plugin for details.
At that point, your code setting the net_module
config option can simply be replaced by calls to "plugin" in Neo4j::Driver.
# Deprecated config option:
use Local::Foo;
$driver->config( net_module => 'Local::Foo' );
# New plug-in interface:
use Local::Foo;
$driver->plugin( Local::Foo->new );
Disable or enforce Jolt
Deprecated in version 0.30 and to be removed in 1.00. Originally added in 0.21 as an experimental feature.
$d->config(jolt => undef); # prefer Jolt v2 (the default)
$d->config(jolt => 0); # accept only JSON
$d->config(jolt => 1); # accept only Jolt v2
# Accept only Jolt and request ...
$d->config(jolt => 'sparse'); # sparse Jolt v1 mode + RFC 7464
$d->config(jolt => 'strict'); # strict Jolt v1 mode + RFC 7464
$d->config(jolt => 'ndjson'); # newline delimited mode (non RFC)
Since driver version 0.24, the Jolt response format (JSON Bolt) is preferred for HTTP connections because the older REST-style JSON response format has several known issues and is much slower than Jolt.
This option is no longer useful. The driver will pick the fastest and most reliable format automatically (RFC 7464 sparse Jolt, if available). If you do need a specific response format, for example because you use driver internals to access the raw server response, you can use a plug-in to manipulate the HTTP Accept
header according to your needs. See Neo4j::Driver::Net.
HTTP timeout setting by direct hash access
Deprecated in version 0.34 and to be removed in 1.00. Originally added in 0.05 as an experimental feature.
$driver->{http_timeout} = 10; # seconds
A timeout for making HTTP connections to the Neo4j server. The equivalent config option "timeout" was introduced in version 0.14. Using the internal setting "http_timeout" has been discouraged since that time.
$driver->config(timeout => 10); # seconds
Mutable auth credentials
Deprecated in version 0.15 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
$session1 = $driver->basic_auth('user1', 'password')->session;
$session2 = $driver->basic_auth('user2', 'password')->session;
Early versions allowed modifying the driver object after session creation. This is not very useful in practice. The official Neo4j drivers are explicitly designed to be immutable.
Parameter syntax conversion using cypher_filter
Config option cypher_filter
deprecated in version 0.26 and to be removed in 1.00. Originally added in 0.14 as an experimental feature.
$driver->config( cypher_filter => 'params' );
When this option is set, the driver automatically uses a regular expression to convert the old Cypher parameter syntax {param}
supported by Neo4j versions 2 and 3 to the new syntax $param
supported by Neo4j versions 3 and 4.
This option was meant to support more general filtering of Cypher statements at some point in the future. But plug-ins already make that very easy. Therefore the cypher_filter
option won't be extended any further. However, the existing parameter syntax conversion is probably useful enough to stand on its own feet if given a more appropriate name.
Instead of this option, "cypher_params" in Neo4j::Driver::Config should be used.
$driver->config( cypher_params => v2 );
Plug-in modules by name
Deprecated in version 0.34 and to be removed in 1.00. Originally added in 0.31 as an experimental feature.
$driver->plugin( 'Local::MyPlugin' );
As an alternative to the blessed instance of a plug-in, the module name may be given as parameter. However, because your code must still use
or require
the module it specifies here, this style offers no significant advantage. Just pass a new plug-in instance instead.
$driver->plugin( Local::MyPlugin->new );
Suppress exceptions
Deprecated in version 0.14 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
$driver = Neo4j::Driver->new;
$driver->{die_on_error} = 0;
$result = $driver->session->run('...');
The default value of the die_on_error
attribute is 1
. Setting this to 0
causes the driver to no longer die on server errors.
This is much less useful than it sounds. Not only is the Result structure not well-defined for such situations, but also the internal state of the Transaction object may be corrupted. For example, when a minor server error occurs on the first request (which would normally establish the connection), the expected Location
header may be missing from the error message and the transaction may therefore be marked as closed, even though it still is open. The next request would then fail anyway, but with a misleading error message.
Additionally, client errors (such as trying to call single()
on a result with multiple result records) may cause the driver to die in spite of die_on_error = 0
.
Such inconsistent behaviour makes bugs harder to find and has no clear advantages. It is not present in the official drivers.
To suppress errors, wrap your calls in try
/catch
blocks:
use Feature::Compat::Try;
my $result;
try {
$result = $session->run('MATCH (n:Test) RETURN m');
$result->has_next; # Wait for statement execution
}
catch ($e) { warn "Got a Neo4j error: $e" }
Type system customisation
Deprecated in version 0.25 and to be removed in 1.00. Originally added in 0.14 as an experimental feature.
$driver->config(cypher_types => {
node => 'Local::Node',
relationship => 'Local::Relationship',
path => 'Local::Path',
point => 'Local::Point',
temporal => 'Local::Temporal',
init => sub { my $object = shift; ... },
});
The package names used for bless
ing objects in query results can be modified. This allows clients to add their own methods to such objects.
Clients must make sure their custom type packages are subtypes of the base type packages that this module provides (e. g. with parent):
Neo4j::Driver::Type::Node
Neo4j::Driver::Type::Relationship
Neo4j::Driver::Type::Path
Neo4j::Driver::Type::Point
Neo4j::Driver::Type::Temporal
Clients may only use the documented API to access the data in the base type. As an exception, clients may store private data by calling the _private()
method, which returns a hashref. Within that hashref, clients may make free use of any hash keys that begin with two underscores (__
). All other hash keys are reserved for use by Neo4j::Driver.
The implementation of the custom type packages continues to be defined by the driver. In particular, it is the driver's choice what kind of reference to bless – hash, array, or scalar. This severely limits the freedom of the custom type packages.
Instead of the cypher_types
option, users should consider a custom networking module that provides a custom result handler. This approach offers even more flexibility (albeit at the cost of some degree of convenience). See "Result handler API" in Neo4j::Driver::Plugin for details.
Neo4j::Driver::Net::HTTP::LWP
agent
Deprecated in version 0.30 and currently planned to be removed in 1.00. Originally added in 0.21 as an experimental feature.
use parent 'Neo4j::Driver::Net::HTTP::LWP';
sub foo {
my ($self) = @_;
my $lwp_ua = $self->agent;
...
}
Returns the LWP::UserAgent instance in use. Meant to facilitate subclassing. In version 0.30, this method was renamed ua()
because LWP itself uses agent
for the User-Agent identification string and this was deemed a possible source of confusion.
protocol
Deprecated in version 0.30 and currently planned to be removed in 1.00. Originally added in 0.21 as an experimental feature.
use parent 'Neo4j::Driver::Net::HTTP::LWP';
sub foo {
my ($self) = @_;
my $http_version = $self->protocol;
...
}
Returns the HTTP version of the last response (typically "HTTP/1.1"
). Since version 0.26, this method was no longer required for a net module and using it was discouraged.
Neo4j::Driver::Plugin
Plug-in manager
Deprecated in version 0.34 and to be removed in 1.00. Originally added in 0.31 as an experimental feature.
$plugin_mgr->add_event_handler( event_name => sub {...} );
$plugin_mgr->trigger_event( event_name => @parameters );
The plug-in manager has been replaced by the event manager. This is a name change only. Calls to methods of the plug-in manager should simply be replaced by equivalent calls to those of the event manager.
$event_mgr->add_handler( event_name => sub {...} );
$event_mgr->trigger( event_name => @parameters );
Neo4j::Driver::Record
Cypher type system
Direct access deprecated in version 0.13 and currently planned to be removed in 1.00. Originally added in 0.01.
$result = $session->run('MATCH (n:Person) RETURN (n)');
foreach my $node ( map { $_->get } $result->list ) {
my $properties = $node;
say $properties->{birthday};
}
Early versions of this driver returned nodes and relationships as unblessed hash references of their properties. Neo4j paths were returned as unblessed array references. This was a bug because this driver's goal always was to implement the Neo4j Driver API, which doesn't work this way. This bug made it impossible to distinguish between structural types and simple maps / lists. It also made it difficult to access metadata. See GitHub issues #2 and #8.
Proper blessed types for nodes, relationships and paths were added in version 0.13, and directly accessing their elements and properties using ->[]
or ->{}
was deprecated at the same time. A deprecation warning was added in version 0.18. The current plan is to remove direct access in version 1.00.
To obtain a hash reference of all properties of a node or relationship, use the properties()
method:
$result = $session->run('MATCH (n) RETURN (n)');
foreach my $node ( map { $_->get } $result->list ) {
my $properties = $node->properties;
say $properties->{birthday};
}
To obtain all nodes and relationships in a path as an alternating array, use the elements()
method:
$result = $session->run('MATCH p=(:Person)-[]->() RETURN (p)');
foreach my $path ( map { $_->get } $result->list ) {
my $array = [ $path->elements ];
...
}
get_bool()
Deprecated in version 0.07 and to be removed in 1.00. Originally added in 0.02 as an experimental feature.
$bool = $session->run('RETURN false')->single->get_bool;
$ref = ref $bool; # ''
$undef = ! defined $bool; # 1
Get a boolean value from this record. Behaves exactly like get()
, except that non-truthy boolean values are returned as undef
.
In Perl, which used to not have a native boolean type, JSON booleans are represented as a blessed scalar that uses overload to evaluate truthy or non-truthy as appropriate in Perl expressions. This almost always works perfectly fine. However, some conditions may not expect a non-truthy value to be blessed, which can result in wrong interpretation of query results. The get_bool()
method was meant to ensure boolean results would evaluate correctly in such cases.
If you do need an unblessed Perl scalar to express a boolean value, simply use !!
to force evaluation in a boolean context.
$val = $session->run('RETURN false')->single->get;
$ref = ref $val; # 'JSON::PP::Boolean'
$bool = !! $val;
Neo4j byte array type
Direct unblessed string access deprecated in version 0.46 and currently planned to be removed in Neo4j::Driver 1.00 and Neo4j::Bolt 0.5000.
Support for Neo4j byte array types has always been problematic due to bugs and limitations in Neo4j itself. Version 0.46 adds support for Neo4j::Types::ByteArray for Bolt and Jolt. Unfortunately, automatically detecting byte arrays in JSON result data isn't possible, and the same is true for result data from Neo4j::Bolt version 0.4203 and earlier.
Byte arrays will be made available as Neo4j::Types::ByteArray values (Bolt and Jolt) and integer arrays (JSON); see also Neo4j::Driver::Types. To correctly handle a value which you know is a Neo4j byte array, but don't know how it was retrieved over the network, you need to account for both of the possible formats (or all three of them, if you include the unblessed string legacy format).
my $bytes = $record->get('bytearray');
if ($bytes isa Neo4j::Types::ByteArray) {
$bytes = $bytes->as_string;
}
elsif (ref $bytes eq 'ARRAY') {
# Legacy JSON, primarily Neo4j < 4.3
my $string = '';
for ($bytes->@*) {
$_ += 0x100 if $_ < 0;
$string .= chr;
}
$bytes = $string;
}
else {
# Legacy unblessed string: no action necessary
}
Raw meta data access
Deprecated in version 0.18 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
$meta = $record->{meta};
Allows accessing the entity meta data that some versions of the Neo4j server provide. This meta data is not available reliably due to a known bug in the Neo4j server (#12306). If it is available, it can since version 0.13 be accessed via object methods. This raw access shouldn't be needed anymore and should no longer be relied upon.
stats()
Deprecated in version 0.07 and to be removed in 1.00. Originally added in 0.02 as an experimental feature.
Shortcut for "stats()" in Neo4j::Driver::Result (only for records obtained via "single" in Neo4j::Driver::Result).
Virtual columns
Deprecated in version 0.18 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
$size = $record->{column_keys}->count;
$record->{column_keys}->add('new_field_key');
Access to the internal {column_keys}
data structure allows adding new 'virtual' columns to the record's field key / index resolution used by the get()
method. The virtual columns can then be accessed just like regular columns.
Rather than manipulating the driver's Neo4j statement result, users should make an in-memory copy of the results in a data structure under their own control.
Neo4j::Driver::Result
Control result stream attachment
Deprecated in version 0.30 and to be removed in 1.00. Originally added in 0.13 as an experimental feature.
$buffered = $result->attached; # boolean
$count = $result->detach; # number of records fetched
detach()
forces the entire result stream to be buffered locally, so that it is available to fetch()
indefinitely, irrespective of other statements run on the same session. Essentially, the outcome is the same as calling list()
, except that fetch()
can continue to be used because the result is not exhausted.
The utility of these methods could never be demonstrated. Clients are more likely to call list()
instead. (To begin statement execution, calling has_next()
is a potentially cheaper alternative.) Only one of the official Neo4j drivers has ever offered these methods, and even that one no longer does so in its latest version.
stats()
Deprecated in version 0.07 and to be removed in 1.00. Originally added in 0.02 as an experimental feature.
$tx = $session->begin_transaction;
$tx->{return_stats} = 1;
$stats = $tx->run('...')->stats;
Return a hash ref. The hash ref contains query statistics if these were requested in advance. The hash ref may or may not be blessed.
In the Neo4j Driver API, query statistics are available from the Neo4j::Driver::ResultSummary instead, which is obtained using summary()
.
$stats = $session->run('...')->summary->counters;
Neo4j::Driver::ServerInfo
Protocol string
Deprecated in version 0.26 and to be removed in 1.00. Originally added in 0.19 as an experimental feature.
$protocol_string = $session->server->protocol;
Returns the protocol name and version number announced by the server. Similar to an agent string, this value is formed by the protocol name followed by a slash and the version number, usually two digits separated by a dot (for example: Bolt/1.0
or HTTP/1.1
). If the protocol version is unknown, just the name is returned.
Since Neo4j 4.3, the driver API has an official method for this purpose, "protocol_version" in Neo4j::Driver::ServerInfo. Therefore the experimental protocol()
method is expendable. In the future, the behaviour of the deprecated protocol()
method can be approximated as follows:
$protocol_string = $_ ? "Bolt/$_" : defined ? "Bolt" : "HTTP/1.1"
for $session->server->protocol_version;
Neo4j::Driver::Session
Call run() in list context
Deprecated in version 0.26 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
@records = $session->run('...');
See "Call-run()-in-list-context1" below for details.
close()
Deprecated in version 0.14 and to be removed in 1.00. Originally added in 0.02 as an experimental feature.
$session->close; # no-op
All resources opened by the Perl driver are closed automatically once they are no longer required. Explicit calls to close()
are neither required nor useful.
Neo4j::Driver::StatementResult
Deprecated in version 0.19 and to be removed in 1.00. Originally added in 0.01.
$result = $session->run('...');
warn 'Unexpected type'
unless $result->isa('Neo4j::Driver::StatementResult');
With version 4 of the official Neo4j drivers, StatementResult
was renamed Result
.
This driver deprecated any use of the Neo4j::Driver::StatementResult module name in version 0.19. Use Neo4j::Driver::Result instead.
Neo4j::Driver::Transaction
Call run() in list context
Deprecated in version 0.26 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
@records = $transaction->run('...');
The run
method tries to Do What You Mean if called in list context. However, this may result in unexpected behaviour. For example, consider this code:
$people = {
jane => $tx->run('MATCH (n) WHERE n.name = "Jane" RETURN n'),
john => $tx->run('MATCH (n) WHERE n.name = "John" RETURN n'),
};
You might expect the result to be a hash with two Neo4j nodes as entry values. However, if no nodes match these queries, the list context will make run()
return empty lists and you might end up with the hash {jane => 'john'}
instead. If one node matches and the other doesn't, the code may die.
To avoid this issue, you can wrap every call to run()
in scalar()
. This will always get you a Neo4j::Driver::Result. In the next major version of the driver, wrapping the call in scalar()
will no longer be necessary, because a Neo4j::Driver::Result will be returned in every context.
To obtain a list of Neo4j::Driver::Record instances, simply use list()
in list context:
@records = $tx->run('...')->list;
Call run() with an array of multiple statements
Deprecated in version 0.25 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
@statements = (
[ 'RETURN 42' ],
[ 'RETURN {value}', value => 'forty-two' ],
);
$results = $transaction->run( [@statements] );
foreach $result ( @$results ) {
say $result->single->get;
}
# Call in list context (also deprecated):
@results = $transaction->run($statements);
The Neo4j HTTP API supports executing multiple statements within a single HTTP request. This driver exposes this feature to the client by allowing a multi-dimensional array to be passed to run()
. Unfortunately, the resulting API is confusing to use and implement and is therefore bug-prone.
If you need this feature, you should consider using the private _run_multiple()
method instead. This feature might eventually be used to implement lazy statement execution for this driver. The _run_multiple()
method is expected to remain available at least until that time.
@results = $transaction->_run_multiple( @statements );
foreach $result ( @results ) {
say $result->single->get;
}
Disable obtaining query statistics
Deprecated in version 0.28 and now an internal API. Originally added in 0.02 / 0.13 as an experimental feature.
$transaction = $session->begin_transaction;
$transaction->{return_stats} = 0;
$result = $transaction->run('...');
The experimental {return_stats}
feature for requesting query statistics from the Neo4j server was first added to the driver in version 0.02. Starting with version 0.13, stats are enabled by default. When using HTTP, this feature allowed disabling them. Doing so might provide a very minor performance increase.
As of version 0.28, allowing stats to be disabled is considered to be a failed experiment. The performance impact is too minor to matter; on the other hand, the advantages of a common API between Bolt and HTTP connections are very clear. The driver currently uses {return_stats} = 0
internally, so this feature will likely not be removed soon, but going forward, it will be treated as an internal API. There will be no deprecation warning. See "USE OF INTERNAL APIS" in Neo4j::Driver::Plugin.
To disable query stats in future, use a plug-in to modify includeStats
in the server request.
Return results in graph format
Deprecated in version 0.28 and to be removed in 1.00. Originally added in 0.01 as an experimental feature.
$session = $driver->config( jolt => 0 )->session;
$transaction = $session->begin_transaction;
$transaction->{return_graph} = 1;
$records = $transaction->run('...')->list;
for $record ( @$records ) {
$graph_data = $record->{graph};
...
}
The Neo4j HTTP JSON API supports a "graph" results data format. This feature is only available when Jolt is disabled, which is not recommended.
To request graph format in future, use a plug-in to disable Jolt and modify the resultDataContents
in the server request. Note that $record->{graph}
is an internal API that may or may not be available in future versions. See "USE OF INTERNAL APIS" in Neo4j::Driver::Plugin.
If there is demand for the graph format, equivalent functionality might be added to a future version of the driver itself. This would then also be available for Bolt and Jolt connections.
Neo4j::Driver::Type::Node, Neo4j::Driver::Type::Relationship
Deletion indicator
Deprecated in version 0.26 and to be removed in 1.00. Originally added in 0.13 as an experimental feature.
$node_definitely_deleted = $node->deleted;
$node_definitely_exists = ! $node->deleted && defined $node->deleted;
$node_status_unknown = ! defined $node->deleted;
$reln_definitely_deleted = $relationship->deleted;
...
In some circumstances, Cypher statements using DELETE
may still RETURN
nodes or relationships that were deleted. To help avoid confusion in such cases, the server sometimes reports whether or not a node was deleted. If the deletion status of a node or relationship is unknown, undef
will be returned by this method.
However, that information is not reliably available. In particular, it is only reported for HTTP connections using JSON responses (not for Bolt or Jolt). Additionally, some Neo4j server versions may not report it at all, and if reported, it may be affected by a known bug in the Neo4j server (#12306). Finally, the deletion indicator doesn't reflect whether or not a transaction was successful or rolled back.
Given the low availability and reliability of this indicator, consistency suggests to remove the deleted()
method entirely. To obtain this indicator in the future, use a plug-in to disable Jolt, then try to access the result's raw meta data. For caveats, see "USE OF INTERNAL APIS" in Neo4j::Driver::Plugin.
Neo4j::Driver::Type::Path
path()
Deprecated in version 0.18 and to be removed in 1.00. Originally added in 0.13 as an experimental feature.
$array = $path->path;
$start_node = $array->[0];
Return the path as an array reference, alternating between nodes and relationships in path sequence order.
The word path()
is singular, implying the return of a reference. The alternative methods nodes()
and relationships()
are plural, implying the return of a list. This was inconsistent. Additionally, the path()
method led to awkward expressions such as $path->path
, which are needlessly difficult to comprehend.
Use elements()
instead.
$array = [ $path->elements ];
AUTHOR
Arne Johannessen (AJNN)
COPYRIGHT AND LICENSE
This software is Copyright (c) 2016-2024 by Arne Johannessen.
This is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0 or (at your option) the same terms as the Perl 5 programming language system itself.