Graph
Hentera’s Graph is a simple yet powerful way of querying for almost all data in Hantera. Using very simple declarative object structures, we can describe a query that Hantera will perform for us.
Being a graph, we can navigate between entities as we wish to retrieve related data as we need it. Filters and sorting can be applied at every navigation and you choose which fields you’re interested in.
The main HTTP endpoint for making Graph queries is:
Base Sets
A the start of any query, you need to begin by targeting one of the base sets. These are the sets that provide universal access to nodes of a certain type, for example, Orders or Payments. Every type has a set, usually named the same as the type but in plural. To list all available sets and get additional metadata, such as search-indexed fields, use the below query:
Otherwise, refer to the Graph Types section in the navigation.
Query Format
A query is defined in JSON and declaratively expresses the query, not so different from what you may be used to using SQL. Although the syntax is vastly different. The main idea is that you specify the criterias for the nodes you want, and the Graph will return the resulting matching nodes. What you may not be used to, is how easy it is to fetch related data. While SQL is generally limited to resulting in a table, making joins sometimes rather verbose with a lot of duplicated data, Hantera’s Graph can return a more natural nested object structure.
A query is made up of a navigation, with arguments that define filters and sort orders, a list of fields to return, and potentially nested navigations to fetch related data.
Example: Querying Orders
A simple query that fetches the 10 most recent confirmed orders, their deliveries and order lines, may look like this:
Required Navigations
Each query navigation has a flag require
. If set to true, the left-hand-side node will only be returned if the navigation has at least one related node. This can be combined with a filter to indirectly filter the first node based on a related node’s field value.
Authorization
The Graph maps onto Hantera’s resource tree based on node types as such:
Each node has a primary key, usually a UUID. This can be used to allow access to only specific nodes in the graph.
Query Permissions
In order to be able to query for nodes, a session must have the query
permission. For example, the below ACE allows querying of order
nodes:
With query permission you can filter on any field and retrieve the total count. It’s allso a pre-requisite to retrieve field data.
To give access to an order with orderId
db974a97-e5ca-4114-95de-2a9ade600257
, use:
Field Permissions
The query permissions authorizes queries, but no field information. In order to authorize fields, use the field
permission with optional sub-permission for each field:
The above ACE authorizes the field orderNumber
to be retrieved on order
nodes.
Complex Fields
Some fields are objects, examples are dynamic
and invoiceAddress
. While these are referenced using dot/arrow-notation when querying, the ACE for them are using colon. This allows permissions to be given on all sub-fields:
Or just a single dynamic field:
Attribute Based Access
ABAC is supported for the query
permission. This means
that querying of nodes can be restricted based on user access attributes. All node fields are available as attributes.
For example:
An even more general ACE can be specified. In this case, the ACE is ignored if the channelKey
attribute doesn’t exist on the given node type:
GraphQL
Hantera also provides a GraphQL interface for the Graph, which can be accessed at the /graphql
endpoint. Refer to the introspection API for more details. We generally recommend using the JSON-based interface for querying due to its more consistent integration with actor queries and more universal support. The GraphQL provides a convenient alternative for exploring the graph using a GraphQL client, or for federated scenarios.