大崎大輝のアバター
大崎大輝のホームページ
gitlabのロゴ

2021/7 ~ 2023/7

某旅行サイト運営会社

時給 4,300円 程度

航空券の予約システムのバックエンド開発および 予約の管理サイトの開発

  • TypeScript
  • Node.js
  • PostgreSQL
  • GraphQL
  • SOAP

利用可能な飛行機を検索して一覧を表示し、チケットの予約を行うWebシステムのバックエンド開発を行いました。さらに、予約情報を管理してその請求書を作る管理サイトの作成を行いました。

thumbnail

概要

航空券の予約をおこなうWebアプリケーションのバックエンド開発と、それらの予約により生じる 会計データを保存するデータベース、およびデータベースの管理をおこなうWebアプリケーションの 開発を行いました。

航空券の予約をおこなうWebアプリケーションのバックエンド開発

サーバーの構成はおおむね下図のようになっています。

航空券予約サーバー構成図

航空券の検索や予約は GDS(Global Distribution System)と呼ばれるシステムによって行われます。 このGDSに対する操作を SOAP(Simple Object Access Protocol) API で提供しているサービス(以下SOAP API)があるので、開発したWebアプリケーションはSOAP APIに対して リクエストをなげ、帰ってきたデータをクライアントに返します。

最近の Web サーバーは JSON 形式でデータを返すのが一般的なのですが、 SOAP インターフェースはデータを XML 形式で返します。 クライアント側で取り扱うには XML 形式では不便なので、開発したサーバーは XML 形式のデータを JSON 形式に変換するのが主な役割になっています。

設計・実装

サーバーは Node.js の fastify.js フレームワークを用いて作成しました。 クライアントとサーバーの処理フローはおおむね以下のようになります。

  • クライアントは JSON パラメータとともに HTTP リクエストをサーバーに投げます。
  • サーバーは受け取ったパラメータを XML に変換し、 SOAP API にリクエストを投げます。
  • サーバーは SOAP API から受け取った XML から必要なデータを抽出して JSON に変換します。
  • サーバーは変換したデータをクライアントに返します。

上記のうち、2~3の処理は SOAP クライアントというモジュールとして分離して実装しました。 こうすることにより、別のフレームワークを使うサーバーに機能を移植することや、サーバー自体のインターフェースを変えずに SOAP API ではない別のサービスを使用するように構成を変更することが可能になります。

SOAP クライアントの処理はさらに query maker と query parser という処理に分かれています。 SOAP クライアントの処理は以下の通りです。

  • 引数としてパラメータを受け取る。
  • query makerにパラメータを渡し、XML形式のデータを生成する。
  • HTTPクライアントを使ってSOAP APIに生成したXMLデータを投げる。
  • SOAP APIから返ってきたXMLデータをquery parserに渡し、JSON形式のデータを生成する。
  • 戻り値として生成したJSONデータを返す。

どのように業務を進めたか

まず SOAP API で返されるデータの構造について調べる必要がありました。SOAP について調べ、どのようにデータを送ればよいのか、 インターフェース定義はどう読めばよいのかを調べました。SOAP は wsdl というファイルでインターフェースを定義しているのですが、 そのままでは Typescript では取り扱えないので、定義の読み方を調べて typescript の型定義として作り直しました。

SOAP API のリスポンスサンプルはドキュメントには書いてありましたが、それだけでは構造がよくわからなかったので、そのリスポンス内に 含まれているオブジェクト同士の関係性を ER 図のような形で書き起こしてみました。さらに航空券の仕組みを調べ、それと照らし合わせることで、 どの要素が何に相当するのかを推定しました。(たとえば「予約」には「運賃」の情報が必要。「運賃」にはさらに「運賃ルール」や実際に使われる「航空便」 の情報が紐づいている。一方で検索で返ってくる情報は「旅程」で、この中には「航空便」のリストや「運賃」のリストが含まれているので、 予約をする場合は「運賃」情報を抜き出す必要がある。)その過程で意味の分かりづらい名前は分かりやすい名前に変更しました。

SOAP APIのオブジェクトはいろいろな場所で使いまわされている(例えば「検索」APIの結果に含まれる「運賃」情報と 「予約」APIの結果に含まれる「運賃」情報が同じ)ので、オブジェクト単位でパーサーが作れるようにしました。例えば、 「検索」結果をパースする機能は「運賃」をパースする機能と「航空券」をパースする機能を組み合わせて作れるようにしています。

画面に表示したいだけの情報を返せれば十分なので、最初は検索・予約の一連の処理をするのに最低限必要なデータをパースする機能だけを作り、 要件に応じてパーサーの機能を追加していきました。

会計データを管理する Web アプリケーションの開発

航空券の予約情報と、それに紐づく請求書や仕訳情報を保存するデータベースの設計と、その管理をおこなうための Web アプリケーションの開発を行いました。

データベースには以下の情報を保存できるようにする必要がありました。

  • 請求書(宛先や発行日、締め日、請求項目、請求書の PDF ファイルなど)
  • 仕訳項目(計上日やどの請求項目に紐づくかの情報、借方・貸方勘定科目など)
  • 航空券とホテルの予約内容(予約日や金額、予約者の名前、予約内容など)
  • サブスクリプションの契約情報(航空券の予約サービスをサブスクリプションサービスとして提供している)
  • 顧客情報(どの請求書をダウンロードできるのか、デフォルトの支払い方法などの設定情報)
  • 手数料の計算方法

Web アプリケーションには以下の機能が必要でした。

  • 各データの検索・一覧表示
  • 請求書 PDF ファイルの作成
  • 仕訳項目の入金消込
  • 予約内容に紐づける請求項目・仕訳項目の作成
  • サブスクリプションの契約情報の作成
  • 顧客情報の作成・変更
  • 商品の購入登録(その商品に応じた予約内容・請求内容・仕訳内容を一括で作成する)
  • 外部システムへの入力ファイルの作成や出力ファイルの読み込み

設計・実装

フルスタックフレームワークの Blitz.js を使って実装を行いました。 最終的に、データベースの構造は、大きくわけて請求書、仕訳項目、予約の3つに分かれました。

トップページからそれぞれのデータの検索・一覧ページに飛ぶことができ、さらにその中で 新規作成画面や詳細表示・編集画面に飛べるような構成になりました。 検索・一覧ページは、ページ上部に検索フォームを置き、下部に検索結果のテーブルを置くような 構成にしました。テーブルの行をクリックすることで詳細表示画面に移動できます。

どのように業務を進めたか

会計の仕組みについて調べ、そこからデータベースの ER 図を作成しました。 要件の内容について詳しく聞き、その情報を既存のデータベースに入れるべきかどうかを判断し、 場合によってはテーブルの定義を分けて ER 図に追加しました。