GraphQL Support

Webix provides full support for GraphQL API query language. GraphQL allows you to get all necessary data in one request.

Initialization

According to the philosophy of GraphQL all requests are sent to one endpoint. So, you need to specify the URL to your server from which data should be taken:

webix.proxy.GraphQL.url = "https://graphql-demo.webix.io/query";

To implement data loading and saving, you should initialize GraphQL proxy object. The webix.proxy() function receives the GraphQL prefix and a string with either query (for loading data) or mutation (for saving updates) keyword, which are both entities of the GraphQL language.

  • loading data
var graphql = webix.proxy("GraphQL", `query($rowId: Int!){
    getPackage(id: $rowId){
        id, 
        url,
        name
    }
}`)
.load({ rowId: id.row })
.then(data => $$("f2").setValues(data));
  • saving data
var graphql = webix.proxy("GraphQL", `
    mutation updatePackage($pack: PackageInput!){
        updatePackage(package: $pack){
            id
        }
    }
`)
.save({ pack })
.then(() => {
    $$("t2").updateItem(pack.id, pack);
    webix.message("Done")
});

Both load and save methods return a promise object which is resolved with necessary data that you can use later on.

Related sample:  Using GraphQL

Using GraphQl with Data Components

To enable GraphQl support for loading data into a data component, use a string that describes what data should be received with the GraphQL prefix.

{
    view:"datatable",
    url: `GraphQL->{
        getAllProducts{
            docslink, name
        }
    }`
}

To save updates made on the client to the server, Webix Dataprocessor can be used. It allows you to specify all the necessary operations inside the save property of the widget configuration:

{
    view:"datatable",
    save:{
        insert:function(id, op, product){
            return webix.proxy("GraphQL", `
                mutation deleteProduct($product: ProductInput!){
                    addProduct(product: $product){
                        id, status
                    }
                }
            `).save({ product });
        },
        // other operations
    }
}

Thus, you will get a separate response on each data operation.

Related sample:  GraphQL and Data Processor

GraphQL Load and Save Pattern

On any type of operation: data loading, updating, items adding and deleting, a POST request is generated. Requests are formed according to the GraphQL specificity:

  • When you load data, the request formed by the GraphQL proxy contains the query field with a string that describes what particular data should be received:
{
    query:"
        {getAllProducts{docslink, name}}
    "
}
  • When you save the data - edit, add or delete items, the request body contains the query field with a string starting from mutation keyword to describe data updates, and the variables field with related parameters:
{
    query:"
        mutation updatePackage($pack: PackageInput!){
            updatePackage(package: $pack){                              
                id
            }                       
        }
    ",
    variables:{pack: {url: "http://", name: "my"}}
}

Server-Side Response

A server-side response comes in the JSON format. An example of a response to a successful request is:

{"data":{"getAllProducts":[
    {"docslink":"","name":"New Product1"},
    {"docslink":"","name":"New Product2"}
]}}

GraphQL proxy will convert the request so that it will have the structure suitable for data components to work with. For example, the above response will be transformed as follows:

[
    {"docslink":"","name":"New Product1"},
    {"docslink":"","name":"New Product2"}
]

For save operations we recommend you to return an object with the id of the changed data item and the status of operation:

{"data":{"addProduct":{"id":25,"status":"OK"}}}

DataProcessor will transform the response into a compact form:

{"id":25,"status":"OK"}

Read more about DataProcessor

Related sample:  GraphQL and Data Processor

Handling Errors

A successful GraphQL query is supposed to return a JSON object that contains a key:value pair, where the key is the "data" field and value is a complex object with received data. If the request fails or something goes wrong, a second key:value pair appears in the response, where the key is the "errors" field and the value is an array with errors objects.

{
    "data":{"updatePackage":null},
    "errors":[{"message":"record not found","path":["updatePackage"]}]
}

Read more about error handling aspects in the GraphQL specification.

Using Several Endpoints

In case you need to send requests to more than one server, there is such a possibility. You can add the path to the server as the third parameter of the webix.proxy function:

webix.proxy("GraphQL", `
    mutation updatePackage($pack: PackageInput!){
        updatePackage(package: $pack){
            id
        }
    }
`, "http://servername").load() //.save()
Back to top