GraphQL Extensions
This feature is currently in preview. Although the implementation is complete and the schema extensions are available for everyone, the access to data model extensions is restricted to selected customers. If you are not one of these customers, you cannot create data model extensions. You can still use all the API extensions available in the schema for generically querying the model, but only for the code data model.
The GraphQL schema is dynamically built from the core data model. It exposes tables, columns, relations, processings, reports the way they are defined in the core model.
BNXT supports extending the model with new tables, columns, relations, and others. These data model extensions (DMEs for short) are accessible through GraphQL just like the core model. However, these extensions are not available the same way the core model is. GraphQL features a single schema, and that cannot expose all customer-specific extensions in a strongly-type named. For this reason, generic extensions are available everywhere DMEs are possible.
Although these generic extensions to the schema are designed for DMEs, it is possible to also query the core model using them. However, we advice that you only use them for DMEs.
Getting started with extensions
Extensions are referenced using their name identifiers, and not model numbers:
- columns and tables by their name
- relations by their name and where necessary to avoid ambiguity, also by their source and target table name
A few examples are provided here to get you started.
query read_order($cid:Int!)
{
useCompany(no:$cid)
{
order(first:5)
{
items
{
orderNo
orderDate
extensions
{
customerNo : integerValue
createdAt : dateValue(name: "createdDate")
}
}
}
}
}The extensions field is available on all tables, and it exposes all extension columns defined for that table. You can query the extension columns by their name using the appropriate typed field. There are two ways to query a field:
- using an alias, which is interpreted as the name of the extension column, such as in
customerNo : integerValue - using the
nameargument to specify the name of the extension column, such as increatedAt : dateValue(name: "createdDate")
When both an alias and the name argument are used, the name argument takes precedence and the alias is not considered for identifying the company.
The possible field names for extension columns are:
integerValuedecimalValuestringValuebooleanValuedateValuetimeValuetimestampValue
Each column has a domain with a specific data type. Data types can be integer, decimal, boolean, string, date, timestamp. If the requested data type (such as integer for integerValue) does not match the domain data type of the extension column, the value null is returned.
The following example utilizes a relation extension to query related data from an extension table:
query read_order($cid:Int!)
{
useCompany(no:$cid)
{
order(first:5)
{
items
{
orderNo
orderDate
extensions
{
customerNo : integerValue
createdAt : dateValue(name: "createdDate")
}
joinup_Associate_via_Customer
{
name
extensions
{
joinup(relation: "Country")
{
name : stringValue
}
}
}
}
}
}
}The last example here shows how to query a table, use filters and sorting, and also do joins using the generic extensions schema:
query read_table($cid:Int!)
{
useCompany(no:$cid)
{
table(
name : "order",
first: 5,
filter : {
joindown : {
relation : {
name : "Order",
from : "OrderLine"
}
_some : {
joinup :{
relation : {
name : "Product"
},
column : "Description",
stringValue : {
_eq : "Product 103"
}
}
}
}
}
orderBy : [
{column : "customerNo", order : DESC},
{column : "orderDate", order : ASC},
{column : "orderNo"}
])
{
items
{
orderNo : integerValue
customerNo : integerValue
address : stringValue (name : "addressLine1")
orderDate : dateValue
createdDate : dateValue
createdTime : timeValue
createdTimestamp : timestampValue
totalDiscountPercent : decimalValue
editStatus : integerValue
joindown(relation : "Order", from : "OrderLine")
{
items
{
orderNo : integerValue
lineNo : integerValue
joinup(relation : "Product")
{
description : stringValue
}
}
}
joinup(relation : "Customer")
{
name : stringValue
joinup(relation : "Country")
{
name : stringValue
joinup(relation : "Language")
{
name : stringValue
}
}
}
}
}
}
}This query uses the core model entirely and is the equivalent of the following:
query read_order($cid:Int!)
{
useCompany(no:$cid)
{
order(
first: 5,
filter : {
joindown_OrderLine_via_Order : {
_some : {
joinup_Product : {
description : {
_eq : "Product 103"
}
}
}
}
}
orderBy : [
{customerNo : DESC},
{orderDate : ASC},
{orderNo : ASC}
])
{
items
{
orderNo
customerNo
joindown_OrderLine_via_Order
{
items
{
orderNo
lineNo
joinup_Product
{
description
}
}
}
joinup_Associate_via_Customer
{
name
joinup_Country
{
name
joinup_Language
{
name
}
}
}
}
}
}
}