Поддержка GraphQL

Webix полностью поддерживает GraphQL API. GraphQL позволяет получить все необходимые данные в одном запросе.

Инициализация

Согласно философии GraphQL все запросы посылаются в одну точку. Поэтому для начала необходимо указать URL сервера, с которого скрипт будет брать данные:

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

Чтобы реализовать загрузку и сохранение данных с использованием GraphQL бэкенда, необходимо инициализировать GraphQL прокси объект. Для этого вызовите функцию webix.proxy(), которая принимает 2 параметра:

  • имя прокси; здесь GraphQL;
  • строка запроса, которая начинается с ключевого слова query (для загрузки данных) или с mutation (для сохранения данных). Оба слова - сущности языка GraphQL.

У прокси GraphQL есть 2 метода: load() и save(), которые используются для запросов и, дополнительно, имеют специальные параметры для них. Оба метода возвращают объект промиса с ответными данными.

Загрузка данных

// инициализируем прокси
var graphql = webix.proxy("GraphQL", `query($rowId: Int!){
    getPackage(id: $rowId){
        id, 
        url,
        name
    }
}`);
 
// выполняем запрос
graphql.load({ 
    rowId: id.row 
}).then(data => $$("f2").setValues(data));

В результате фомируется POST-запрос со следующими параметрами:

  • query: строка запроса query($rowId: Int!){...}
  • variables: аргумент для метода загрузки { rowId: id.row }

Сохранение данных

var pack = { id:1, title:"Some" };
var graphql = webix.proxy("GraphQL", `
    mutation updatePackage($pack: PackageInput!){
        updatePackage(package: $pack){
            id
        }
}`);
 
graphql.save({ 
    pack 
}).then(() => {
    $$("t2").updateItem(pack.id, pack);
    webix.message("Done")
});

В результате фомируется POST-запрос со следующими параметрами:

  • query: строка запроса mutation updatePackage($pack: PackageInput!){...}
  • variables: ргумент для метода сохранения { id:1, value:"Some" }

Related sample:  Using GraphQL

Handling errors on the client side

You can handle errors on the client side by using the ignoreErrors property. By default this option is enabled, and errors are ignored. To catch errors, you need to enable the property like this:

webix.proxy.GraphQL.ignoreErrors = false;

If a response contains errors, data loading will be interrupted. The way of handling errors depends on the way of data loading:

  • if data is loaded via a widget, you can handle errors via the onLoadError event
  • in case of separate data loading, you can catch errors via the fail()/catch() methods of the promise

Использование GraphQL с компонентами данных

Вы можете использовать GraphQL для реализации загрузки и сохранения данных в Webix компонентах.

  • загрузка данных

Чтобы GraphQL поддерживал загрузку данных в какой-либо компонент, необходимо подсоединить GraphQL прокси к запросу загрузки. Для этого определите свойство url как строку proxy->query:

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

Теперь при загрузке данных компонент спровоцирует POST-запрос с вышеуказанным параметром:

{
    query:"
        {getAllProducts{docslink, name}}
    "
}
  • сохранение данных

Для сохранения данных с клиента на сервер, используется Webix Dataprocessor. Логика сохранения описывается в свойстве компонента save.

Внутри объекта save вы можете описать логику для какой-либо операции: добавление, удаление или обновление элемента. Поэтому на каждую операцию вы получите отдельный ответ.

{
    view:"datatable",
    save:{
        update:function(id, op, product){
            return webix.proxy("GraphQL", `
                mutation updateProduct($id: Int!, $product: ProductInput!){
                    updateProduct(id: $id, product: $product){
                        status
                    }
                }
            `).save({ id, product });
        },
        // другие операции
    }
}

Когда вы вносите изменения в компонент данных, его DataProcessor провоцирует POST-запрос, который содержит поле query с указанной строкой запроса и поле variables с данными для сохранения.

{
    query:"
        mutation updateProduct($id: Int!, $product: ProductInput!){
            updateProduct(id: $id, product: $product){
                status
            }
        }
    ",
    variables:{id: 966, product: {id: 966, name: "New Product1"}
}

Related sample:  GraphQL and Data Processor

Ответ с сервера

Ответ приходит в формате JSON. Пример GraphQL ответа на успешный запрос выглядит следующим образом:

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

GraphQL прокси конвентирует запрос таким образом, чтобы его структура подходила для компонентов данных. К примеру код выше трансфомируется следующим образом:

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

Для операций сохранения мы рекомендуем возвращать объект с ID изменённого элемента и статус операции:

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

DataProcessor придаст ответу компактную форму:

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

Читайте подробнее о DataProcessor

Related sample:  GraphQL and Data Processor

Обработка ошибок на сервере

Успешный GraphQL запрос должен вернуть JSON-объект, который содержит пару "ключ: значение", где ключ это поле "data", а значение это объект с полученными данными. В случае какой-либо ошибки, в ответе появляется другая пара "ключ: значение", где ключ это поле "errors", а значение массив объектов ошибок.

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

Читайте подробнее об обработке ошибок в спецификации GraphQL.

Как послать данные нескольким серверам

Если вам нужно послать информацию к более, чем одному серверу, добавьте путь к серверу третьим параметром функции webix.proxy:

webix.proxy("GraphQL", `
    mutation updatePackage($pack: PackageInput!){
        updatePackage(package: $pack){
            id
        }
    }
`, "http://servername").load() //.save()
Наверх