私たちのプロジェクトの1つは、カザフスタン共和国の公共調達ポータル-goszakup.gov.kzです。
1年前、私たちは大規模なプロジェクト、Unified Services(OpenData)を立ち上げました。
実装には、RestAPI方法論が使用されました。
今日、私たちのサービスの新しいバージョンとそれらと連携するための新しいインターフェースについてお話します。

6つのオープンデータサービスを開発および開始しました。
- 参加者の登録
- 不公正なサプライヤーの登録
- 年間計画の登録
- 州の発表 調達
- ロット登録
- 契約の登録
カザフスタンの多くの企業は、これらのサービスに関するデータを既に接続および受信しています。
Open Dataの発売により、企業は公共調達に関するデータを収集するために異なるパーサーを作成する必要がないため、データベースの負荷を約40%削減することができました。 難しいクエストを通過するだけで十分です:)
- アクセストークンのリクエストを書く
- ポータルgoszakup.gov.kz/ru/developer/owsでサービスのドキュメントを読む
- RestAPIクライアントを書く
統合サービス-新しいアプローチ
RestAPIを使用すると、サイトを解析するよりも簡単かつ迅速にデータを取得できますが、標準のRestAPIでは企業に柔軟性を与えず、最初にすべてのデータを取得してからそれらの間にリンクを構築する必要があるオブジェクトとの接続を構築できません。
アナウンスに関するデータを受信するには、RestAPIで最初にアナウンスの登録、次にロットの登録、最後に計画の登録を要求する必要があります。 つまり、1つのアナウンスを受信するには、少なくとも3つのリクエストを完了する必要があり、50のアナウンスでデータを受信する必要がある場合は、各アナウンスに1ロット(50アナウンス1、50ロット、50プランポイントの受け取り)。
この量を1つのリクエストに減らす方法を見つけました!
Unified Servicesの2番目のバージョンows.goszakup.gov.kz/v2を開始します。
データセットの拡張に加えて、APIを使用する機能を拡張しています。
これで、RestAPIおよび新しいインターフェイスGraphQLを介してデータを取得できます。
ows.goszakup.gov.kz/v2/graphql

GraphQLについては説明しません。これについては、 aliksendの記事- このGraphQLとは何ですか?
GraphQLを起動した後に得られた利点を説明します。
- 要求の柔軟性。
- 関連オブジェクトの取得。
- 要求と応答の完全な入力。
- 新しいデータ取得インターフェイス。
リクエストの柔軟性
単純なRestAPI要求を使用すると、事前に作成されたデータ形式を取得できます。
GraphQLをクエリすると、必要な形式でデータが取得されます。
データを要求するとき、必要なデータの形式、たとえばIDや
契約番号
{ contract { id contract_number_sys } }
応答として、次のデータのみを取得します。
{ "data": { "contract": [ { "id": 1, "contract_number_sys": "_" } ] } }
まあ、そのようなクエリはGraphQLを実装するのが最も簡単です。 企業は受信するデータを選択する機会がありますが、RestAPIを使用しているときのように調整する必要はありません。 必要なフィールドのセットのみを取得します。

関連オブジェクトの取得
データを部分的に選択できるようにするだけで、RestAPIの機能を繰り返すことにとどまりませんでした。
GraphQLの2番目の機能であるオブジェクトリレーションシップを実装しました。
RestAPIに従ってデータを受信する場合、契約および会社に関するデータを受信するために、契約の顧客はまず参加者の登録からデータを取得し、その後、契約の登録からデータを受信し、オブジェクト自体の間に接続を構築する必要があります。
現在、GraphQLを使用する場合、参加者登録からデータを完全に受信する必要はなく、興味のある形式のデータを要求するだけです。
{ contract { id contract_number_sys customer { name_ru } } }
したがって、1回のリクエストで、契約に関するデータと顧客の会社データの両方を取得します。
{ "data": { "contract": [ { "id": 1, "contract_number_sys": "_", "customer" : { "name_ru": " " } } ] } }

そして、実装されている多くのそのような関係があり、現在、データを受信する企業は、データに対する要求が大幅に少なくなります。 同時に、オブジェクトを相互に接続するために完全なデータセットを受信するために、オブジェクトが相互にどのように関連しているかを正確に推測する必要がなくなりました。
私は達成した接続構造を部分的に実証しようとしました。

リクエストとレスポンスの入力
SOAPリクエストの多くの支持者は、常に最も重要なプラスであるデータ型付けを常に行っています。
RestAPIは、SOAPとは異なり、その構造の説明がなく、どのタイプのデータかを事前に知りません。 しかし、GraphQLはすべてを変更します。
これで、データスキーム全体でGraphQLにデータをリクエストでき、次の情報を受け取ります。
- データ構造の完全な説明。
- データ型(Int、String、Boolean)を持つフィールドの説明。
- ネストされたオブジェクトの説明とネストされたオブジェクトのフィールド構造。
- たとえば、各フィールドのロシア語による詳細な説明。
- 一部のフィールドが説明付きの非推奨フラグを受信したという通知を受け取ります。
Insomnia RESTクライアントプログラム-insomnia.restを使用してGraphQLを操作します
GraphQLを使用すると、オブジェクトの構造全体を受け取り、クエリを構築するときにプロンプトを表示します。
例として、いくつかのスクリーンショットを示します。
1.クエリの作成を支援する プログラムはオブジェクトの完全な構造を受け取りました

2.各フィールドの説明とそのデータ型と説明のヒント

3.いずれかのフィールドがフラグを受け取った場合のヒント-非推奨

また、GraphQLのこの機能により、使用するフィールドとオブジェクトの全体像を把握できます。

新しいデータ取得インターフェース
そして、私は最後に最も興味深いものを残しました。
すべてがクールに思えます。独自のデータ構造を構築することができ、他のオブジェクトとの接続があり、すべてのデータが入力されます。 しかし、まだ何かが欠けています...
このデータを検索する十分な機会がありません。
最初から、リクエスト自体のパラメータを使用して検索形式が実装されました。
{ trd_buy(ref_buy_status_id: 1) { name_kz name_ru } }
しかし、ここでいくつかの問題に遭遇しました。
- 多数の検索条件を使用すると、リクエストは単に読めなくなります。
- 同じフィールドの複数のバリアントを検索するデータを検索するときに配列を決定することは不可能です。
クエリの構築を簡素化し、検索機能を拡張するために、データをフィルタリングするためのネストされたオブジェクトを実装しました。
フィルタリングオブジェクトを示す変数をリクエストに定義します。
query($filter: TrdBuyFiltersInput){ trd_buy(filters: $filter) { name_kz name_ru } }
データ検索パラメーター自体について説明します。
{ "filter": { "ref_buy_status_id": [1, 2] } }
その結果、ステータス1および2のすべての広告を受け取ります。
リクエスト自体では、データ構造のみを示します。すべての検索パラメーターは、いくつかの基準に従ってフィルタリングのためにデータ配列を既に転送できるパラメーターの送信に入ります。

さらに、GraphQLスキーマ自体には、このような検索オブジェクトの説明もあります。

統合サービス-バージョン2.0:
サービスの仕事:
- 参加者の登録
- 発表の登録
- 契約の登録
- 行為の登録
- ロット登録
- 年間計画の登録
- 不公正なサプライヤーの登録
APIの操作を大幅に簡素化し、柔軟なクエリ構造と、指定された基準に従ってデータを検索する機能を備えた新しい機能を開始しました。
データの取得速度は低下していませんが、データの取得に必要なリクエストの数を減らすだけです。
データスキーマで無効なフィールドまたは名前が変更されたフィールドについて警告する機会を得ました。
APIをさらに開発し、サービスの形態学的データ検索も可能にする予定です。