Унифицированные сервисы goszakup.gov.kz — Версия 2

в 5:17, , рубрики: api, graphql, restapi, Программирование, Разработка веб-сайтов, разработка сайтов

Я работаю разработчиком в компании АО «Центр Электронных Финансов».
Один и наших проектов — портал Государственных закупок Республики Казахстан — goszakup.gov.kz.

Год назад мы запустили большой проект — Унифицированные сервисы (OpenData).
Для реализации была использована методология RestAPI.

Сегодня я расскажу о новой версии наших сервисов и новом интерфейсе работы с ними.

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 1

Мы разработали и запустили 6 сервисов Открытых данных:

  • Реестр участников
  • Реестр недобросовестных поставщиков
  • Реестр годовых планов
  • Объявления о гос. закупках
  • Реестр лотов
  • Реестр договоров

Многие компании Казахстана уже подключаются и получают данных по данным сервисам.
Запуск Открытых данных позволил примерно на 40% снизить нагрузку базы данных за счет того, что компаниям не нужно писать различные парсера чтобы собирать данных о Государственных закупках. Достаточно пройти не сложный Квест :)

  1. написать запрос на получение токена доступа
  2. ознакомиться с документацией по сервисам на нашем портале goszakup.gov.kz/ru/developer/ows
  3. написать свой RestAPI клиент

Унифицированные сервисы — Новый подход

В связи с тем, что объемы данных по Закупкам Казахстана то работать с ними по методологии RestAPI не всегда удобно.

RestAPI дает возможность удобнее и быстрее получить данные чем парсинг сайта, но стандартный RestAPI не дает компаниям гибкости и для построения связи с объектами приходится получать сначала все данные и только потом строить связи между ними.

Мы запускаем 2-ю версию Унифицированных сервисов — ows.goszakup.gov.kz/v2.
По мимо расширения наборов данных мы расширяем и возможность работы с нашим API.

Теперь данные можно получить и по RestAPI и по новому интерфейсу — GraphQL.
ows.goszakup.gov.kz/v2/graphql

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 2

Описывать, что такое GraphQL я не буду, для этого вы можете ознакомиться со статьей aliksendЧто же такое этот GraphQL?.

Я расскажу с какие преимущества мы получили после запуска GraphQL:

  • гибкость запросов;
  • получение связанных объектов;
  • полную типизацию запросов и ответов;
  • новый интерфейс поиска данных.

Гибкость запросов

При простом запросе RestAPI вы получаете тот формат данных которые были заложены заранее.
При запросе к GraphQL вы получаете данные в том формате в котором нужно вам.

При запросе данных вы сами определяете формат данных которые нужны, например нужны ИД и

Номер договора

{
  contract
  {
    id
    contract_number_sys
  }
}

В ответ получаем только эти данные:

{
  "data": {
    "contract": [
      {
        "id": 1,
        "contract_number_sys": "номер_договора"
      }
    ]
  }
}

Ну такие запросы это самое легкое в реализации GraphQL. Компании получают возможность самим выбирать какие данные они хотят получить, при этом нам не надо вносить каких либо корректировок как если бы это было при работе с RestAPI, и при этом не надо получать избыточные данные которые не нужны.

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 3

Получение связанных объектов

Мы не остановились на том, чтобы повторить функционал RestAPI просто дав возможность частично выбирать данные.

Мы реализовали 2-ю особенность GraphQL — связи объектов.

Если получать данные по RestAPI чтобы получать данные по договору и по компании заказчику в договоре требовалось сначала получить данные из Реестра участников, а только потом получать данные из Реестра договоров и самим строить связь между объектами.

Теперь при работе с GraphQL не нужно выполнять полное получение данных по Реестру участников, достаточно запросить данные в интересующем вас формате:

{
  contract
  {
    id
    contract_number_sys
    customer
    {
      name_ru
    }
  }
}

Тем самым один запросом мы получаем и данные по договору и данные по компании заказчику:

{
  "data": {
    "contract": [
      {
        "id": 1,
        "contract_number_sys": "номер_договора",
        "customer" : {
             "name_ru": "Компания Мира"
         }
      }
    ]
  }
}

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 4

И таких связей реализовали много, теперь компаниям для получения данных потребуется значительно меньше запросов для получения данных. При этом больше не надо догадываться как именно связаны друг с другом объекты, получать полные наборы данных чтобы связать их друг с другом.

Я попытался наглядно показать частично структуру связей которой получилось добиться.

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 5

Типизация запросов и ответов

Многие сторонники SOAP запросов всегда ставили самым главным плюсом — типизацию данных.
RestAPI в отличие SOAP не имеет описания своей структуры и вы заранее не знаете какой тип данных. Но GraphQL меняет все.

Теперь можно запросить у GraphQL данные по всей схеме данных и вы получите:

  • Полное описание структуры данных;
  • Описание какое поле какой имеет тип данных (Int, String, Boolean);
  • Описание вложенных объектов и структуры полей вложенных объектов;
  • Детальное описание например на русском языке для каждого поля;
  • Получения уведомления, что какое-то поле получило флаг Deprecated с описанием.

Я для работы с GraphQL использую программу Insomnia REST Client — insomnia.rest
Она при работе с GraphQL получает всю структуру объектов и подсказывает при построении запроса.

Приведу в качестве примера несколько скриншотов.

1. Помощь в построении запросов т.к. программа получила полную структуру объектов

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 6

2. Подсказку по описания каждого поля с его типом данных и описанием

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 7

3. Подсказку если какое-то поле получило флаг — Deprecated

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 8

И все это становится возможным за счет того, что GraphQL имеет четкую типизацию всех объектов, всех полей и вы всегда заранее будете знать какой тип данных ожидаете получить.

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 9

Новый интерфейс поиска данных

И самое интересное я оставил на последок.

Все вроде бы классно, есть возможность строить свою структуру данных, есть связь с другими объектами, все данных типизированы. Но все же чего-то не хватает…

Не хватает возможности искать по этим данным.

Дна начало был реализован формат поиска с указанием параметров в самом запросе:

{
  trd_buy(ref_buy_status_id: 1)
  {
    name_kz
    name_ru
  }
}

Но тут я столкнулся с рядом проблем:

  1. при большом количестве критериев поиска запрос становится просто не читаемым;
  2. невозможно определить массив при поиске данных для поиска по нескольким вариантам одного поля.

Чтобы упростить построение запросов и расширить возможность поиска я реализовал вложенные объекты для фильтрации данных.

Определяем в запросе переменную с указанием объекта фильтрации.

query($filter: TrdBuyFiltersInput){
  trd_buy(filters: $filter)
  {
    name_kz
    name_ru
  }
}

Описываем сами параметры поиска данных:

{
	"filter": {
		"ref_buy_status_id": [1, 2]
	}
}

И в результате мы получим все объявления которые имеют статусы 1 и 2.

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

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 10

При этом в самой схеме GraphQL мы все также имеем описание и такого объекта поиска:

Унифицированные сервисы goszakup.gov.kz — Версия 2 - 11

Унифицированные сервисы — Версия 2.0:

Работают сервисы:

  • Реестр участников
  • Реестр объявлений
  • Реестр договоров
  • Реестр актов
  • Реестр лотов
  • Реестр годовых планов
  • Реестр недобросовестных поставщиков

Мы запустили новый функционал, который во много раз упрощает работу с нашим API, имеет гибкую структуру запросов и возможность поиска данных по заданным критериям.

Мы не потеряли в скорости получения данных, а только сокращаем за счет этого количество запросов необходимых для получения данных.

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

Мы планируем и далее развивать API и дать возможность так-же морфологического поиска данных по сервисам.

Автор: GHostly_FOX

Источник

  1. Азамат:

    Все это хорошо, но почти все запросы на чтение данных с портала (get-запросы), а как быть поставщику если нужно автоматически согласовать договор, который принят (одобрен) заказчиком и в статусе ожидания принятия (согласования) поставщиком. Вручную это делается подписанием ЭЦП, но таких договоров у поставщика может быть много и раз договор уже согласован заказчиком то поставщик обязан подписать все согласованные договоры от заказчика. Логично что поставщик хочет автоматизировать такой процесс. Но в документации API нет методов, которые позволяли бы сделать это. А смысла только на чтение данных get-запросами без возможности программно выполнять рутинные действия post-запросами мало.

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js