Features Details
Some important GraphQL feature details.
Queries
ViewAll | ViewAllPaged | SelectWhere | <table>Query | DataMesh
Following Query variants are provided in generated code.
- ViewAll
- ViewAllPaged
- SelectWhere
- <table>Query
- FindOne
- GetOne
- ConsumerService
- DataMesh
extend type Query {
ProductViewAll: [Product]!
ProductViewAllPaged(page: Int, size: Int) : [Product]!
ProductSelectWhere(searchBy: String, sortBy: String, page: Int = 0, size: Int = 10) : [Product]!
# ProductDataMesh: [Product]!
}
extend type Query {
ProductQuery(productId: Int): [Product]!
}
ViewAll, ViewAllPaged, <table>Query are self-explanatory.
Search, Filter, Sorting
Query SelectWhere : Flexible SQL-Like Querying
Query type SelectWhere empowers developers in extending data filtering on-the-fly to any columns needed, and also empowers end-users with flexible filter selections via UI Filter Screen.
Please refer to GraphQL_Readme.txt
file for full details on using it, syntax, operators supported and examples.
Some excerpts here:
* Example: searchBy string: " invQty > 100 and invLocation = 'USA' and invDate = '2022-10-20 14:20' and invCost isNotNull 0 "
* Example: sortBy string: " invQty desc , invMinQty desc "
Data Federation | Data Mesh
A default DataMesh Query is provided in generated code. That can be easily customized further. Refer to GraphQL APIs Extending section here.
Nested Objects
Implementing Nested Objects is easy. Configure Table-to-Table Joins and Multi-Table Relations. Generate code. Complete use case via Via Low-Code Customize.
Please refer to One-to-many relationship section on this page for example of Nested Model.
GraphQL Data Modeling
Please refer to common reference on Data Modeling
In this feature details page, we give examples of GraphQL Data Modeling with 1x1, 1xM and MxM relationships.
One-to-one relationship
1x1 relationship between two tables.
1x1 Table Join example
Table Join:
Srl Left Table Lt Tbl Id Relationship Right Table Rt Tbl Id Defn Id
1 erp_inventory 5004391 1x1 erp_product 5004393 5000113
GraphQL API Generated: Query:
{
ErpInventoryErpProductFindOne(invId: 1) {
invId
productId
invDate
invQty
invMinQty
invCost
invLocation
ErpProduct {
productId
productName
productCategory
primarySupplier
}
}
}
Payload:
{
"data": {
"ErpInventoryErpProductFindOne": {
"invId": 1,
"productId": 1,
"invDate": "19/02/23",
"invQty": 10,
"invMinQty": 2,
"invCost": 50,
"invLocation": "USA",
"ErpProduct": {
"productId": 1,
"productName": "Amoxicillin",
"productCategory": "Antibiotics",
"primarySupplier": "Lupin",
}
}
}
}
One-to-many relationship
1xM relationship between two tables.
1xM Table Relation example with multiple tables
Tables Relation:
Srl Left Table Lt Tbl Id Relationship Right Table Rt Tbl Id Defn Id
1 erp_product 5004393 1xM erp_inventory 5004391 5000112
2 erp_inventory 5004391 1x1 erp_inventory_vw 5004399 5000114
GraphQL API Generated: Query:
{
ErpProductErpInventory1MultiFindOne(productId: 1) {
productId
productName
productCategory
primarySupplier
ErpInventoryErpInventoryVw {
invId
productId
invDate
invQty
ErpInventoryVw {
invId
invCost
invMinQty
invLocation
}
}
}
}
Payload:
{
"data": {
"ErpProductErpInventory1MultiFindOne": {
"productId": 1,
"productName": "Amoxicillin",
"productCategory": "Antibiotics",
"primarySupplier": "Lupin",
"ErpInventoryErpInventoryVw": [
{
"invId": 1,
"productId": 1,
"invDate": "19/02/23",
"invQty": 10,
"ErpInventoryVw": {
"invId": 1,
"invCost": 50,
"invMinQty": 2,
"invLocation": "USA"
}
},
{
"invId": 2,
"productId": 2,
"invDate": "19/02/23",
"invQty": 20,
"ErpInventoryVw": {
"invId": 1,
"invCost": 50,
"invMinQty": 2,
"invLocation": "USA"
}
}
]
}
}
}
Many-to-many relationship
MxM relationship between two tables.
MxM Table Relation example
Table Join:
Srl Left Table Lt Tbl Id Relationship Right Table Rt Tbl Id Defn Id
1 erp_product 5004393 1xM erp_inventory 5004391 5000112
GraphQL API Generated: Query:
{
ErpProductErpInventoryViewAllPaged(page: 0, size: 2) {
productId
productName
productCategory
primarySupplier
ErpInventory {
invId
productId
invDate
invQty
}
}
}
Payload:
{
"data": {
"ErpProductErpInventoryViewAllPaged": [
{
"productId": 1,
"productName": "Amoxicillin",
"productCategory": "Antibiotics",
"primarySupplier": "Lupin",
"ErpInventory": [
{
"invId": 1,
"productId": 1,
"invDate": "19/02/23",
"invQty": 10
},
{
"invId": 2,
"productId": 1,
"invDate": "19/02/23",
"invQty": 20
}
]
},
{
"productId": 2,
"productName": "Azithromycin",
"productCategory": "Antibiotics",
"primarySupplier": "Abbot",
"ErpInventory": [
{
"invId": 1,
"productId": 2,
"invDate": "19/02/23",
"invQty": 10
},
{
"invId": 2,
"productId": 2,
"invDate": "19/02/23",
"invQty": 20
}
]
}
]
}
}
Mutations
Following Mutation variants are provided in generated code, for database insert, update, delete actions.
extend type Mutation {
CustomerCreate(CustomerTblRec1: CustomerInput ): Customer
CustomerUpdate(customerId: String, CustomerTblRec1: CustomerInput ): Customer
CustomerDelete(customerId: String): Int
}
Misc
Solving Underfetching and the n+1 problem
What is the problem ?
Underfetching and the n+1-requests problem means that a specific endpoint doesn’t provide enough of the required information. The client will have to make additional requests to fetch everything it needs. e.g. A client needs to first download a list of elements, but then needs to make one additional request per element to fetch the required data.
Using Table Relationship Queries solves this problem. Also Low-Code Customize to implement Nested Objects can help further.
Table Relationship Queries
Table Relationship Queries using Query methods like <table>Query and SelctWhere solve this problem. Master-Detail relationship records have master record (relationship) keys in all detail level tables, which can be used to avoid n+1.
Example : Fetch Table Relation Data For Master:Detail 1:N (Many) Relations
See Example
Query:
query MyProductInventories {
ProductQuery(productId: 1) {
productId
productName
productCategory
primarySupplier
productDesc
}
InventorySelectWhere(searchBy: " productId = 1 ") {
invId
productId
invDate
invQty
invCost
invLocation
}
}
Response Data:
{
"data": {
"ProductQuery": [
{
"productId": 1,
"productName": "Amoxicillin",
"productCategory": "Antibiotics",
"primarySupplier": "Lupin",
"productDesc": ""
}
],
"InventorySelectWhere": [
{
"invId": 1,
"productId": 1,
"invDate": "2022-11-28",
"invQty": 10,
"invCost": 50,
"invLocation": "USA"
},
{
"invId": 42,
"productId": 1,
"invDate": "2023-02-19",
"invQty": 20,
"invCost": 100,
"invLocation": "USA"
},
{
"invId": 43,
"productId": 1,
"invDate": "2023-02-18",
"invQty": 40,
"invCost": 200,
"invLocation": "USA"
}
]
}
}
Use similar approach for Master:Detail:Detail 1:N:N Relations
Example : Fetch Table Relation Data For Foreign Key or 1:1 Relations
This solution is applicable when the relation key value is known and used.
See Example
Query:
query MyInventory {
InventoryQuery(invId: 1) {
invId
productId
invDate
invQty
invCost
invLocation
}
ProductSelectWhere(searchBy: " productId = 1 ") {
productId
productName
productCategory
primarySupplier
productDesc
}
}
Response Data:
{
"data": {
"InventoryQuery": [
{
"invId": 1,
"productId": 1,
"invDate": "2022-11-28",
"invQty": 10,
"invCost": 50,
"invLocation": "USA"
}
],
"ProductSelectWhere": [
{
"productId": 1,
"productName": "Amoxicillin",
"productCategory": "Antibiotics",
"primarySupplier": "Lupin",
"productDesc": ""
}
]
}
}
Setup
Setup Security & Authentication
Customize - Authorize Access
- Security - Role/User based Auth.
API Customization
Handle inserting data to 2 tables via API Created on View
Troubleshooting FAQs