Fast track to GraphQL
Less than to read
Okay, let’s talk GraphQL!
- Queries
- Operation Names
- Filtering
- Sorting
- Pagination
- Aliases
- Fragments
- Variables
- Directives
- Mutations
Queries
We’ll start with a simple query, and get a list of customers with code and company name details.
{
sage {
x3BusinessPartners {
customer {
edges {
node {
code
companyName
}
}
}
}
}
}
Operation Names
Let’s give our query a name.
query MyNamedQuery {
sage {
x3BusinessPartners {
customer {
edges {
node {
code
companyName
}
}
}
}
}
}
Filtering
With the ability to pass arguments to fields for filtering results, things get much more interesting.
query MyNamedQuery {
sage {
x3BusinessPartners {
customer (filter : "{code :'AE003'}"){
edges {
node {
code
companyName
}
}
}
}
}
}
Sorting
Now let’s sort the result (1 stands for ascending order, and -1 is for descending order).
query MyNamedQuery {
sage {
x3BusinessPartners {
customer (filter : "{code: 'AE003'}", orderBy: "{ code: 1 }"){
edges {
node {
code
companyName
}
}
}
}
}
}
Pagination
If the result is too long, you can limit the length and manage pagination.
query MyNamedQuery {
sage{
x3System {
site (first: 5){
edges{
node {
code
description
shortDescription
}
cursor
}
pageInfo {
endCursor
hasNextPage
startCursor
hasPreviousPage
}
}
}
}
}
We’ll get the next 5 results in the list using ‘after’.
query MyNamedQuery {
sage{
x3System {
site (first: 5, after : "[\"AO021\"]#10"){
edges{
node {
code
description
shortDescription
}
cursor
}
pageInfo {
endCursor
hasNextPage
startCursor
hasPreviousPage
}
}
}
}
}
‘last’ and ‘before’ can be used to return data in the opposite direction.
query MyNamedQuery {
sage{
x3System {
site (last: 5, before : "[\"AO021\"]#10"){
edges{
node {
code
description
shortDescription
}
cursor
}
pageInfo {
endCursor
hasNextPage
startCursor
hasPreviousPage
}
}
}
}
}
Aliases
You can’t query the same field with different arguments directly, but that’s where aliases come in - they enable you to rename field results.
query MyNamedQueryWithAliases {
sage {
x3Products {
subcoProduct: product(filter: "{productCategory: 'SUBCO'}", first: 5, orderBy: "{ code: -1 }") {
edges {
node {
code
productCategory
accountingCode
description1
localizedDescription1
}
}
}
sfiniProduct: product(filter: "{productCategory: 'SFINI'}", first: 5, orderBy: "{ code: -1 }") {
edges {
node {
code
productCategory
accountingCode
description1
localizedDescription1
}
}
}
}
}
}
Fragments
If you want to compare field results, GraphQL comes with reusable units called fragments.
query MyNamedQueryWithAliasesAndFragment {
sage {
x3Products {
leftComparison: product(filter: "{productCategory: 'SUBCO'}") {
...comparisonFields
}
rightComparison: product(filter: "{productCategory: 'SFINI'}") {
...comparisonFields
}
}
}
}
fragment comparisonFields on Sage_X3Products_Product_Connection {
edges {
node {
code
productCategory
accountingCode
description1
localizedDescription1
}
}
}
Variables
Should you need to repeat the same query with a different filter, use variables. When you work with variables, you’ll need to :
- Replace the static value in the query with $variableName
- Declare $variableName as one of the variables accepted by the query
- Pass variableName value in the separate, transport-specific (usually JSON) variables dictionary
# If you need to use another value than the default value of
# $productFilter, just put it in the Query Variables zone, e.g :
# {"productFilter" : "{productCategory: 'SUBCO'}"}
query ProductsInCategory($productFilter: String = "{productCategory: 'SFINI'}") {
sage {
x3Products {
product(filter: $productFilter, first: 5, orderBy: "{ code: 1 }") {
edges {
node {
code
productCategory
accountingCode
description1
localizedDescription1
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
}
Directives
You may need to change the structure and shape of your queries dynamically, for example - if your App has 2 views: simple and detailed.
There are 2 keywords which can solve this problem…. @include and @skip:
The following example, returns a list of orders and their lines:
query GetOrderDetails($soldToCustomer: String, $orderBy: String, $withLines: Boolean!) {
sage {
x3Sales {
salesOrder(filter: $soldToCustomer, orderBy: $orderBy) {
edges {
node {
id
orderDate
shipmentDate
soldToCustomer {
code
companyName
}
company {
code
companyName
}
orderStatus
currencyRate
currencyRateType
currency {
code
}
lines @include(if: $withLines) {
edges {
node {
lineNumber
sequenceNumber
quantityInSalesUnitOrdered
grossPrice
product {
localizedDescription1
code
}
}
}
}
}
}
}
}
}
}
For a simple view, pass the following variables:
{"soldToCustomer": "{ soldToCustomer: 'AE003' }", "orderBy": "{ orderDate: 1 }", "withLines": false}
For a detailed view, pass these variables:
{"soldToCustomer": "{ soldToCustomer: 'AE003' }", "orderBy": "{ orderDate: 1 }", "withLines": true}
If you replace @include with @skip, switch the variables value (false and true) to achieve the same result.
Mutations
Last but by no means least, let’s talk ‘mutations’. Our attention thus far has been focussed on data fetching, but any complete data platform needs a way to modify server-side data too.
Let’s create a sales order.
mutation {
sage {
x3Sales {
salesOrder {
create(data: {id: "GRAPHQLDEMO", salesSite: "UTFR1", soldToCustomer: "UTFR001", currency: "EUR", category: normal, company: "UTFRA", orderDate: "2018-06-15", paymentTerm: "FRTAC60", taxRule: "FRA", lines: [{lineNumber: 1000, grossPrice: "22.0", product: "UT_KEYBOARD", salesUnit: "UN", quantityInSalesUnitOrdered: "1.0"}]}) {
id
taxRule {
code
}
paymentTerm {
code
}
salesSite {
code
}
lines {
edges {
node {
lineNumber
sequenceNumber
product {
code
}
}
}
}
category
soldToCustomer {
code
}
}
}
}
}
}
Now you’re talking GraphQL!
See Samples - queries, mutations and more to talk some more.