For almost 14 years, you could query Neo4j via HTTP — originally with a REST API, later via Cypher — with improvements including streaming, type representations, etc. Since 2016, the focus has shifted to the binary Bolt protocol, advanced routing, and native drivers. The existing HTTP APIs were still running for self-managed customers, but they lacked features, and because of those shortcomings, they were not available in the Neo4j Aura cloud service. This is about to change now.
The new Query API has been in beta for our self-managed customers since the April 2024 release of Neo4j 5.19. At the time, we also stated that it would be coming to Aura in the summer of 2024. Today, we’ve made good on that promise: The Query API is now available on Aura across all tiers and cloud providers for production workloads. We’re also pleased to announce that with Neo4j 5.23, self-managed customers can consider the Query API as completing beta and being ready for production workloads.
The Query API uses secure HTTP(S) communications to make Cypher requests with a JSON document response. You can also request an extended JSON document that incorporates type information. Since there is no requirement to install and maintain drivers, the Query API will work across various platforms and in situations where you do not need the rich feature set available in our drivers or where you can’t install custom libraries or dependencies.
Overall, the Query API is an easily accessible, secure, and efficient method to work with Neo4j Aura.
Let’s walk through some of the functionality of this new capability for Aura.
Making Your First Query API Call
You will need an Aura instance to try out the Query API. If you already have one, along with a set of credentials for it, skip to Query API URL. If not, sign up for the Aura free tier.
Create an Aura Instance
- After logging into Aura, select AuraDB > Instances > New Instance.
2. From the various displayed options, choose the smallest instance size, provide a name, and select a region that works best for you.
3. Make sure any checkbox is selected and choose Create.
4. You will be shown the credentials for the new Aura instance. Make sure you download these or record them. You will need these shortly.
Note: You must do this. You’ve been warned.
Now is a great time to make a pot of tea as its steeping time is roughly the same as how long it will take for the creation process to complete. A poster is available to help you decide on tea strength.
Query API URL
Communication for the Query API takes place on the standard HTTPS 443 port and uses a URL in this format:
https://AURA_HOSTNAME/db/AURA_DATABASE_NAME/query/v2
AURA_HOSTNAME is found within the displayed Connection URI of an Aura instance. In the Aura Console, select AuraDB > Instances and then look in the box for the Aura instance you will use with the Query API for Connection URI, like the one shown below in the red oval box.
The hostname is immediately after neo4j+s://.
AURA_DATABASE_NAME (for now) will always be “neo4j.”
Authorization
Authorization is necessary for every request made to the Query API. Currently, this uses basic authentication — a base64-encoded hash of the database username and password. This is set in the header of the request under Authorization. There are plans to introduce JSON Web Tokens for this purpose later.
Your First Query API Request
You have everything needed to submit your first Query API request to Aura. Here’s a simple example that will check that everything is working. Substitute AURA_HOSTNAME and AURA_DB_PASSWORD for your values:
curl --location 'https://AURA_HOSTNAME/db/neo4j/query/v2' \
--user neo4j:AURA_DB_PASSWORD \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{ "statement": "RETURN 1" }'
If all is well, you will see a response similar to this:
{
"data": {"fields":["1"],"values":[1]},
"bookmarks":["FB:kcwQlRkKozmpRoG708y0045J18kJmZA="]
}
A Basic Cypher Statement
Let’s try getting data from the Aura instance using CURL. You will use this Cypher statement to get five entries:
MATCH (n) RETURN n LIMIT 5
With the Query API, the Cypher statement is the value for the statement key. To try this, substitute AURA_HOSTNAME and AURA_DB_PASSWORD for your values:
curl --location 'https://AURA_HOSTNAME/db/neo4j/query/v2' \
--user neo4j:AURA_DB_PASSWORD \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{ "statement": "MATCH (n) RETURN n LIMIT 5" }'
Here’s an example response from the example movies dataset that has been formatted to improve readability:
{
"data": {
"fields": [
"n"
],
"values": [
[
{
"elementId": "4:751c0ff7-7a1a-448d-9d98-ffc4b4767fef:0",
"labels": [
"Person"
],
"properties": {
"name": "Charlie"
}
}
],
[
{
"elementId": "4:751c0ff7-7a1a-448d-9d98-ffc4b4767fef:1",
"labels": [
"Movie"
],
"properties": {
"tagline": "Welcome to the Real World",
"title": "The Matrix",
"released": 1999
}
}
],
[
{
"elementId": "4:751c0ff7-7a1a-448d-9d98-ffc4b4767fef:2",
"labels": [
"Person"
],
"properties": {
"name": "Keanu Reeves",
"born": 1964
}
}
],
[
{
"elementId": "4:751c0ff7-7a1a-448d-9d98-ffc4b4767fef:3",
"labels": [
"Person"
],
"properties": {
"name": "Carrie-Anne Moss",
"born": 1967
}
}
],
[
{
"elementId": "4:751c0ff7-7a1a-448d-9d98-ffc4b4767fef:4",
"labels": [
"Person"
],
"properties": {
"name": "Laurence Fishburne",
"born": 1961
}
}
]
]
},
"bookmarks": [
"FB:kcwQdRwP93oaRI2dmP/EtHZ/78kAmJA="
]
}
The Query API only accepts a single Cypher statement in a request. If you have several statements you want to perform in a single request, consider using the Cypher CALL subquery facility or make multiple requests.
Using Parameters
Parameterized queries open up many possibilities much like a hot, fresh cup of tea. You can avoid string building and having to escape problematic characters. Additionally, they make caching of execution plans much easier for AuraDB itself, leading to significantly faster query execution times. Consider using parameterized queries as the default pattern when using Cypher in applications and not just with the Query API.
Note: Parameterized queries for bulk data loading are much quicker than sending one request after another.
A parameterized query is when placeholders (like $name) are used for parameters and the parameter values are supplied at execution time. The Query API supports the use of these with a request body that looks like this:
{
'statement': Parameterized Cypher statement that references values,
'parameters': { "key" : [{Values}] }
}
Here’s an example that loads two entries in a single request:
curl --location 'https://c22b6d6e.databases.neo4j.io/db/neo4j/query/v2' \
-- user: neo4j:mypassword \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{ "statement":"UNWIND $items as item MERGE (s:Station {id: item.id}) ON CREATE SET s.name=item.name", "parameters": { "items" : [{"id":"123","name":"station1"},{"id":"456","name":"station2"}]}}'
Let us dig into this a bit deeper and see what is going on.
Start with the parameters:
"parameters": { "items" : [{"id":"123","name":"station1"},{"id":"456","name":"station2"}]}
This is an array of JSON objects with each object having key:value pairs. The array is referenced by its key, items .
Onto the Cypher statement itself:
UNWIND $items as item
MERGE (s:Station {id: item.id})
ON CREATE SET s.name=item.name
The key name from the parameters JSON object array is $items. The array is iterated using the Cypher UNWIND command with each entry in the array referenced by item. The values are accessed using the reference with the wanted property (item.name ).
Read more about using parameters in the documentation for query parameters.
Other Things You Can Do
There are several other useful things you can do with the Query API in Aura:
- Execute a query under the security context of a different user
- Read your writes, also known as causal consistency
- Profile queries
- Retrieve query counters
More detail about each of these is available in the Query API documentation.
What’s Next for the Query API?
Since the April launch, we’ve been hard at work on several improvements and we are always interested in your opinions to make the Query API better. You can give feedback on the Community Forums or in the Drivers area of Discord.
Here’s what we have on the roadmap at the moment:
- Allow for management of transactions for scenarios that require the successful execution of a group of statements where all must succeed or none do, along with rollback
- Use secure JWT for auth
- General performance improvements
We’ll also come back with examples in Python and JS to further illustrate how to use the Query API in applications.
Querying Your Neo4j Aura Database Via HTTPS (Again) was originally published in Neo4j Developer Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.