📜 ⬆️ ⬇️

Unified services goszakup.gov.kz - Version 2

I work as a developer in the JSC "Center for Electronic Finance".
One of our projects is the Government Procurement Portal of the Republic of Kazakhstan - goszakup.gov.kz.

A year ago, we launched a large project - Unified Services (OpenData).
For implementation, the RestAPI methodology was used.

Today I will talk about the new version of our services and the new interface for working with them.
')


We have developed and launched 6 Open Data services:


Many companies in Kazakhstan are already connected and receive data on these services.
The launch of Open Data made it possible to reduce the database load by about 40% due to the fact that companies do not need to write various parsers to collect data on Government procurement. It is enough to pass not difficult Quest :)

  1. write an access token request
  2. Read the service documentation on our portal goszakup.gov.kz/ru/developer/ows
  3. write your RestAPI client

Unified Services - New Approach


RestAPI makes it easier and faster to get data than site parsing, but standard RestAPI does not give companies the flexibility and to build a connection with objects, they have to get all the data first and only then build connections between them.
In order to obtain data on the ad, RestAPI needs to firstly request the register of ads, then the register of lots and at the end of the register of plans. This means that at least one request must be received for receiving one ad, and if you need to receive data for 50 ads, you will need at least 101 requests to RestAPI, provided that each ad contains 1 lot (1 for receiving 50 ads, 50 for receiving lots, 50 per receiving plan items).

We have found a way to reduce this amount to a single request!

We are launching the 2nd version of Unified Services - ows.goszakup.gov.kz/v2 .
In addition to expanding data sets, we expand the ability to work with our API.

Now the data can be obtained both via RestAPI and the new interface GraphQL.
ows.goszakup.gov.kz/v2/graphql



I will not describe what GraphQL is; for this you can read the article aliksend - What is this GraphQL? .

I'll tell you what advantages we got after running GraphQL:


Query flexibility


With a simple RestAPI request, you get the format of the data that was laid in advance.
When you request a GraphQL, you receive data in the format in which you need it.

When you request data, you yourself determine the format of the data you need, for example, ID and

Number of contract

{ contract { id contract_number_sys } } 

In response, we receive only this data:

 { "data": { "contract": [ { "id": 1, "contract_number_sys": "_" } ] } } 

Well, such queries are the easiest to implement GraphQL. Companies get the opportunity to choose which data they want to receive, and we don’t need to make any adjustments as if it were when working with RestAPI. You only get the set of fields you need.



Getting related objects


We didn’t stop at repeating the functionality of RestAPI just by giving the opportunity to partially select data.

We implemented the 2nd feature of GraphQL - object communication.

If to receive data on RestAPI in order to receive data on the contract and on the company, the customer in the contract was required to first obtain data from the Participants Registry , and only then receive data from the Contract Registry and build the connection between the objects themselves.

Now, when working with GraphQL, you do not need to perform full data acquisition by the Participants Registry; it is enough to request data in the format you are interested in:

 { contract { id contract_number_sys customer { name_ru } } } 

Thus, in one request we get both the data on the contract and the company’s data for the customer:

 { "data": { "contract": [ { "id": 1, "contract_number_sys": "_", "customer" : { "name_ru": " " } } ] } } 



And there have been many such connections; now, companies will need significantly fewer requests for data to get data. At the same time, it is no longer necessary to guess exactly how objects are connected with each other, to receive complete data sets in order to connect them with each other.

I tried to visually show in part the structure of the bonds that I managed to achieve.



Typing requests and responses


Many supporters of SOAP requests have always put the most important advantage - data typing.
RestAPI, unlike SOAP, does not have a description of its structure and you do not know in advance what type of data is. But GraphQL changes everything.

Now you can query GraphQL for the entire data scheme and you will receive:


I use the Insomnia REST Client - insomnia.rest to work with GraphQL
When working with GraphQL, it receives the entire structure of objects and prompts when building a query.

I will give as an example some screenshots.

1. Help in building queries because the program received the full structure of objects



2. Hint on the description of each field with its data type and description



3. Hint if some field received a flag - Deprecated



And this GraphQL feature allows you to have a complete picture of which fields and objects you are working with.



New data search interface


And I left the most interesting thing in the end.

Everything seems to be cool, there is an opportunity to build your data structure, there is a connection with other objects, all data is typed. But still something is missing ...

There is not enough opportunity to search by this data.

The bottom of the beginning was the search format with the parameters in the query itself:

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

But then I ran into a number of problems:

  1. with a large number of search criteria, the query becomes simply unreadable;
  2. It is impossible to define an array when searching for data to search for several variants of the same field.

To simplify the construction of queries, and to expand the search capability, I implemented nested objects to filter data.

We define a variable in the request with an indication of the filtering object.

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

We describe the data search parameters themselves:

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

As a result, we get all the ads that have statuses 1 and 2.

In the request itself, we specify only the data structure, and all search parameters go into the transfer of parameters where we can already transfer and data arrays for filtering by several criteria.



At the same time, in the GraphQL scheme itself, we all also have a description of the following search object:



Unified Services - Version 2.0:


Services work:


We have launched a new functionality that simplifies working with our API many times, has a flexible query structure and the ability to search data by specified criteria.

We have not lost in the speed of receiving data, but only reduce due to this the number of requests necessary to receive data.

We were able to warn in the schema data about disabled or renamed fields.

We plan to further develop the API and give the opportunity also morphological data retrieval of services.

Source: https://habr.com/ru/post/441438/


All Articles