なぜ人々はDBALではなくREST APIを行うのですか?


32

過去2つの会社では、Webアプリを介してデータを照会するためにREST APIを使用していました。すなわち。Webアプリに直接SQLを実行させる代わりに、REST APIを呼び出し、SQLを実行して結果を返します。

私の質問は...なぜこれが行われるのですか?

第三者にさらされるとしたら、理解できました。完全なDBよりも制限されたREST APIを公開する方が適切です。しかし、これらの企業の両方ではそうではありません。

これらのREST APIを使用すると、DBMSを簡単に切り替えることができるようになりました。しかし、それはデータベース抽象化レイヤー(DBAL)のポイントではありませんか?ORMをDBALとして使用するか、生のSQLを記述し、必要に応じてDBALにDB固有のものを変換させることができます(たとえば、MySQLのLIMITをMSSQLのTOPに変換します)。

いずれにせよ、それは私には不要のようです。また、問題の診断も難しくなると思います。Webアプリのレポートが間違った数値を提供している場合、SQLクエリをダンプすることはできません。RESTURLをダンプしてから、REST APIとして機能するプロジェクトに移動して、そこからSQLを取り出す必要があります。そのため、診断プロセスの速度を低下させる間接的な余分なレイヤーです。


3
基本的にCRUDのアプリのみを使用したようです。一部のユーザーはフォームでデータを入力し、他のユーザーは同じフォームまたはレポートの印刷でデータを読み取りますか?複雑で洗練されたドメインモデルを必要とするシステムで作業したことがない場合は、その特定の考え方がどのようにあるかを確認できます。多くのアプリケーションでは、処理を行うために追加の間接層が必要です。
-RibaldEddie

1
私は(特にRESTではなく)APIを使って作業しましたが、これは(とりわけ)渡されたパラメーターに対して計算を実行しました。DBMSがこれらの計算で使用されることもありますが、おそらく多くのロジックはDBに存在しません。ただし、私が働いた会社の内部APIはこれを行いません。DBMSにクエリを実行し、SQLクエリの結果を逐語的に吐き出します。REST APIは、トレンディに-実用的ではないように書かれていることが多いようです。
ノイバート

1
REST API設計には、複雑なドメインをうまく設計するのを難しくする癖があります。長年会ったほとんどの開発者は、設計を気にしません。彼らは上司が彼らを愛し、彼らがロックスターであると思うように、できるだけ早くコードを解き放ちたいと思っています。その事実をRESTなどのトレンドと組み合わせると、トレンディで実用的ではないスパゲッティAPIが得られます。REST自体とは関係ありません。
RibaldEddie

3
一部のWeb企業が、ユーザーレコード全体がハッカーに盗まれたと報告するのを不思議に思ったことはありませんか?ハッカーがそれをどのように行ったのだろうか?WebサーバーがDBに直接接続していると考えると、Webサーバーがハッキングされると、攻撃者が好きなDBから任意のものを選択するための完全かつ無制限のアクセス権を持つことに気付きます。中間層の背後に固定すると、攻撃者は中間層のメソッドのみを呼び出すことができます。私はそれがインスタントセキュリティだとは言いませんが、それは非常に優れています。
gbjbaanb

1
@gbjbaanb:私のポイントは、ウェブサーバーがレストサーバーを介してデータにアクセスできるため、ウェブサーバーがハッキングされた場合、攻撃者はレストサーバーをハッキングすることなくレストサーバーを介してデータにアクセスできることです。
ジャックB

回答:


28

クライアントがデータベースに直接アクセスすることを許可する場合-データベース抽象化レイヤーを使用しても、クライアントはこれを実行します。

  • あなたのコードとあなたのコードの間にはカップリングがあります-特に、データベース構造とコードの間には非常に強いカップリングがあります。
  • クライアントはデータベース上でかなり望ましくないことを行う場合があります-更新すべきでないデータを更新している、時間のかかるクエリを書いている、ロックをきれいに取得していないため何かをデッドロックしているなど...
  • データベース構造で最適以下の選択を行った場合、特にクライアントを新しい構造に移行させる良い方法がない場合、その選択から抜け出すことは非常に困難です。

つまり、REST部分についてはまったく触れていません-データベースを維持するチームとそれを使用するチームが同期していない場合、APIの背後でデータベースを分離することは、より賢明な選択です。自分のペースで進化します。


24

あなたは正しいです。Webアプリとデータベースの間にREST APIレイヤーを導入する明確な利点はありません。また、複雑さとパフォーマンスオーバーヘッドのコストがかかります。

矛盾した答えを得ている理由は、アーキテクチャの「クライアント」とは何かに関する混乱です。

アーキテクチャー(正しいと理解している場合)では、ブラウザーが単一のWebアプリと対話し、それがデータベースと対話しています。Webアプリとデータベースの間にREST APIレイヤーを導入してもメリットはありません。記載されているすべての利点(キャッシュ、データベースの分離など)は、コード内のデータアクセス層で実現できます。

しかし、REST APIが理にかなっている他のアーキテクチャがいくつかあります。

  • データベースにアクセスするクライアントが複数ある場合-つまり、単一のWebアプリではなく、同じデータベースにアクセスする複数の独立したWebアプリ。共通のRESTインターフェイスを作成して、データモデル、キャッシュなどの共有を可能にすることには利点があるかもしれません。同じDALライブラリを共有することでいくつかの利点を得ることができますが、アプリが異なる言語および異なる言語で開発されている場合は機能しませんプラットフォーム。これは、エンタープライズシステムでは一般的です。

  • データベースに直接アクセスする複数のデスクトップアプリがある場合。これは、古典的な「2層」アーキテクチャであり、Webアプリに比べて好まれなくなっています。RESTレイヤーを導入すると、データアクセスロジックを集中化できます。特に、複数の分散クライアントが同じデータベースに直接アクセスするのは危険であるため、セキュリティをより厳密に制御できます。

  • サーバーから直接データを取得するJavaScriptコードがある場合は、どのような場合でもREST APIのようなものが必要です。


1
私はあなたの答えが好きでしたが、それに付属するクエリがいくつかあります。別の抽象化層の導入によるパフォーマンスの低下はどうですか?また、単一障害点(これがダウンした場合、他のすべてがダウンした場合)および潜在的なボトルネック(各アプリがプールからのDB接続を待機している)になりませんか?
-sactiw

@satich:あなたが何を求めているのか正確にはわかりません。もっと具体的に教えてください。REST層の有無にかかわらず、単一障害点について質問していますか?
ジャックB

あなたはそれと通信して、複数のアプリを持っている場合は、余分な層が利用することができます
ユアン・

@Ewan:はい、これは私が最初の箇条書きで述べたことです。
ジャックB

1
@JacquesB複数のWebアプリケーションが同じDBを共有し、同じデータを共有しないと仮定します。つまり、それぞれがそのDB内の個別のデータセットに対してCRUD操作を実行します。だから、Restful永続フレームワークの背後にアプリを置くことは理にかなっていますか(DBがクエリで良好なレベルの同時実行性を提供すると仮定します)?さらに、そのフレームワークは、それを介して対話する非常に多くのWebアプリのボトルネックであり、単一障害点でもありませんか?
-sactiw

12

警告:大きな投稿、いくつかの意見、あいまいな「あなたに最適なことをする」結論

一般的に、これはデータベースの周りに「六角形のアーキテクチャ」を実装する手段として行われます。Webアプリケーション、モバイルアプリケーション、デスクトップアプリケーション、バルクインポーター、およびバックグラウンド処理のすべてで、データベースを均一に消費させることができます。確かに、データベースにアクセスするための豊富なライブラリを作成し、すべてのプロセスでそのライブラリを使用することで、ある程度同じことを達成できます。確かに、非常にシンプルなシステムを備えた小さな店にいる場合、実際にはおそらくこれがより良いルートです。それはより単純なアプローチであり、より複雑なシステムの高度な機能が必要ない場合、なぜ複雑さを払うのですか?ただし、大規模で洗練された一連のシステムで作業している場合、すべて大規模にデータベースとやり取りする必要があります。

プラットフォームの独立性とメンテナンス

データベースがあり、そのデータベースと対話するPythonライブラリを作成し、誰もがそのライブラリを引き込んでデータベースと対話する場合、それは素晴らしいことです。しかし、突然モバイルアプリを作成する必要があり、そのモバイルアプリもデータベースと通信する必要があるとしましょう。また、iOSエンジニアはPythonを使用せず、AndroidエンジニアはPythonを使用しません。たぶん、iOSの人たちはAppleの言語を使い、AndroidのエンジニアはJavaを使いたいと思うでしょう。そうすると、データアクセスライブラリを3つの異なる言語で記述し、維持する必要がなくなります。iOSとAndroidの開発者は、Xamarinなどを使用して、共有できるコードを最大化することを決定するかもしれません。ただし、データアクセスライブラリを.NETに移植する必要がある場合を除き、完璧です。そして、あなたの会社はちょうど別の会社を購入しました s Webアプリケーションは、異種ではあるが関連製品であり、企業は、自社のプラットフォームのデータの一部を、新しく買収した子会社のプラットフォームに統合したいと考えています。唯一の問題があります。子会社は新興企業であり、アプリケーションの大部分をDartで作成することにしました。さらに、何らかの理由(おそらく制御できない理由)のために、Xamarinを試験運用していたモバイルチームは、それは彼らのためではなく、開発対象のモバイルデバイスに固有のツールと言語を使用することを決定しました。しかし、その段階では、あなたのチームはすでに.NETでデータアクセスライブラリの大部分を提供していたため、社内の別のチームがSalesforceのクレイジーな統合作業を書いていたので、そこからすべてを.NETで行うことにしました。は既にのデータアクセスライブラリでした。

イベントの非常に現実的な変化により、Python、.NET、Swift、Java、およびDartで記述されたデータアクセスライブラリが用意されました。どちらもあなたが望むほど良いものではありません。各言語には異なるORMツールがあるため、希望するほど効果的にORMを使用できませんでした。そのため、必要以上のコードを記述する必要がありました。そして、5つあるので、それぞれの化身にあなたが望むほど多くの時間を割くことができませんでした。ライブラリのDartバージョンは、ライブラリとサポートが実際には存在しなかったため、一部のトランザクションのものをロールバックする必要があるため、特に毛深いです。このため、Dartアプリケーションにはデータベースの読み取り専用機能のみが必要であるというケースを作成しようとしましたが、しかし、ビジネスはすでに、計画している機能はすべて追加の努力に見合う価値があると考えていました。そして、データアクセスライブラリのこれらすべてのインカネーションに存在する検証ロジックのいくつかにバグがあることがわかりました。これらのすべてのライブラリでこのバグを修正するためのテストとコードを作成し、これらすべてのライブラリの変更のコードレビューを取得し、これらすべてのライブラリのQAを取得し、すべてを使用してすべてのシステムの変更をリリースする必要がありますこれらのライブラリ。一方、あなたの顧客は不快になり、Twitterに連れて行かれ、あなたの会社の主力製品をターゲットにしたことは言うまでもなく、想像もしなかった下品の組み合わせをつなぎ合わせました。そして、製品の所有者は、状況についてまったく理解していないと判断します。

一部の環境では、上記の例は不自然なものであることを理解してください。また、この一連のイベントが数年にわたって展開する可能性があることも考慮してください。一般に、アーキテクトやビジネスマンが他のシステムをデータベースに接続することについて話し始める段階に達すると、ロードマップに「データベースの前にREST APIを置く」ことを望みます。早い段階で、このデータベースがいくつかのシステムで共有され始めることが明らかになったときに、Webサービス/ REST APIがその前に置かれたかどうかを検討してください。検証バグの修正は、5回ではなく1回行うため、はるかに迅速かつ簡単になります。修正プログラムをリリースすると、調整がはるかに簡単になります。なぜなら、

TLDR; データにアクセスする必要のある各アプリケーションにデータアクセスロジックを配布するよりも、データアクセスロジックを集中化し、非常に薄いHTTPクライアントを維持する方が簡単です。実際、HTTPクライアントはメタデータから生成されることさえあります。大規模なシステムでは、REST APIを使用すると、少ないコードで管理できます

パフォーマンスとスケーラビリティ

一部の人々は、最初にWebサービスを経由するのではなく、データベースと直接対話する方が速いと考えるかもしれません。アプリケーションが1つしかない場合、それは確かに真実です。しかし、大規模なシステムでは、私は感情に同意しません。最終的には、ある程度の規模では、データベースの前に何らかのキャッシュを置くことは非常に有益です。Hibernateを使用していて、InfinispanグリッドをL2キャッシュとしてインストールしたい場合があります。アプリケーションとは別にWebサービスをホストする4つの強力なサーバーのクラスターがある場合は、同期レプリケーションを有効にした埋め込みトポロジを使用する余裕があります。これを30個のアプリケーションサーバーのクラスターに配置しようとすると、そのセットアップでレプリケーションをオンにするオーバーヘッドが大きすぎるため、分散モードまたはある種の専用トポロジでInfinispanを実行する必要があり、キャッシュから読み取るためにHibernateが突然ネットワークを経由する必要があります。さらに、InfinispanはJavaでのみ機能します。他の言語がある場合は、他のキャッシングソリューションが必要になります。データベースに到達する前にアプリケーションからWebサービスに移動する必要があるネットワークオーバーヘッドは、一般に独自のオーバーヘッドが伴うはるかに複雑なキャッシングソリューションを使用する必要があるため、すぐに相殺されます。

さらに、REST APIのそのHTTPレイヤーは、別の貴重なキャッシングメカニズムを提供します。REST APIのサーバーは応答にキャッシュヘッダーを配置でき、これらの応答はネットワークレイヤーでキャッシュできます。1つまたは2つのサーバーがある小規模なセットアップでは、データベースと通信するときにアプリケーションのメモリ内キャッシュを使用するのが最善の策ですが、多くのサーバーで実行される多くのアプリケーションがある大規模なプラットフォームでは、ネットワークを使用してキャッシングを処理します。適切に構成すると、squid、ニス、nginxなどが比較的小さなハードウェア上で非常識なレベルにスケールアウトできるためです。1秒あたり数十万または数百万のリクエストのスループットは、アプリケーションサーバーまたはデータベースからの場合よりもHTTPキャッシュからの方がはるかに安価です。

それに加えて、データベースを指す少数のサーバーをすべて指すのではなく、大量のクライアントがすべてデータベースを指すようにすることで、データベースのチューニングと接続プーリングが非常に難しくなります。一般に、アプリケーションサーバーの実際のワークロードのほとんどはアプリケーションに関連しています。データベースからデータが戻ってくるのを待つことは、多くの場合時間がかかりますが、一般的には非常に計算コストがかかりません。アプリケーションのワークロードを処理するために40台のサーバーが必要な場合がありますが、おそらくデータベースからデータを取得するために40台のサーバーは必要ありません。そのタスクをWebサービス専用にすると、Webサービスはおそらくアプリケーションの他の部分よりもはるかに少ないサーバーで実行されます。つまり、データベースへの接続がはるかに少なくなります。これは重要です。データベースは一般的に

TLDR; 異なる言語やテクノロジーを使用する多くの異なるアプリケーションで発生する場合よりも、単一の専用Webサービス内で発生する場合の方が、データアクセスの調整、スケーリング、およびキャッシュが容易です。

最終的な考え

「おっと、データを取得するために常にREST APIを使用する必要があります」または「このバカは、Webアプリがデータベースと直接通信するため、間違っていると言っています」という考えから離れないでください。私たちのものは正常に動作します!」。私がやろうとしている主なポイントは、異なるシステムと異なるビジネスには異なる要件があるということです。多くの場合、REST APIをデータベースの前に配置することは本当に意味がありません。それはより複雑なアーキテクチャであり、その複雑さを正当化する必要があります。しかし、複雑さが保証される場合、REST APIを使用することには多くの利点があります。さまざまな懸念事項を比較検討し、システムに適切なアプローチを選択できることが、優れたエンジニアになります。

また、REST APIが物事のデバッグを妨げている場合、その図に何か問題があるか、欠落している可能性があります。追加された抽象化レイヤーが本質的にデバッグを難しくするとは思わない。大規模なn層システムで作業する場合、分散ロギングコンテキストがあることを確認するのが好きです。おそらく、ユーザーがリクエストを開始したときに、そのリクエストのGUIDを生成し、そのユーザーのユーザー名とユーザーが行ったリクエストを記録します。次に、アプリケーションが他のシステムと通信するときに、そのGUIDを渡します。適切なログの集計とインデックス作成により、問題を報告しているユーザーについてプラットフォーム全体を照会し、すべてのアクションを可視化できます。システムを細かく調べて、問題が発生した場所をすばやく特定できます。繰り返しますが、より複雑なアーキテクチャです。

出典:http : //alistair.cockburn.us/Hexagonal+architecture https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing


非常に良い答えで、読む価値があります。この素晴らしい返事を書いてくれてありがとう!
ドミニク

6

DBALが何であるかを正しく理解している場合、その答えは、RESTインターフェイスを使用すると、そのクライアントで任意の言語を使用でき、DBALは、クライアントで単一の言語を使用できるライブラリであるということです。

これは、多くの開発チームがあり、すべてのチームが同じ言語に習熟しているわけではない企業にとっては、有利な場合があります。ソフトウェアが直接DBを照会できるようにすることは機能的には同等ですが、あなたが言うように「完全なDBよりも制限されたREST APIを公開する方が良い」。

より抽象的な用語では、あなた自身が質問に答えています:

そのため、診断プロセスを遅くする間接的な追加レイヤーです

... 「コンピュータサイエンスのすべての問題は、別のレベルの間接参照によって解決できる」と述べているこの有名な格言があるためです。:)


6

同じ会社にいるからといって、すべてをすべての人に公開する必要があるわけではありません。REST APIは、明確な契約で、企業内のチーム間の限定された消費者/プロバイダーの関係を定義する方法です。Amazonは、この形式の組織の先駆者です。

APIは抽象化の層も提供するため、特定のイディオムのセットを使用できます。データベースで使用されているのと同じ用語で消費者と話す必要は必ずしもありません。また、必ずしも各消費者と同じように話したいとは限りません。


3

RESTはデータベースクエリ用であり、そうではないと考えています。RESTは、現在の何かの状態を表します。RESTを使用すると、表現が変更または取得されますが、それだけです。その状態がデータベースで利用可能になっても、その表現がどのようになるかはRESTの一部ではなく、データベースクエリでもないため、重要ではありません。


データベースクエリ== RESTを提案しているわけではありません。確かに、RESTはデータベース抽象化レイヤーよりもはるかに優れた機能を備えていますが、過去に私が働いていた2つの会社は、本質的にそれだけでした-データベース抽象化レイヤーです。それは何もしません、他の DBのクエリに変換するHTTPリクエストよりを。そして、それがあなたがしているすべてであるならば、DBALによってより良く仕えられるように思えます。確かに、最近、一部の人々がRESTを使用している唯一の理由は、それが流行しているためであるように思われます-手元のタスクに最適なソリューションではないからです。
ノイバート

@neubertは、RESTのようにDBALをインターネット経由で直接機能しますか?
ロブ

確かに。インターネット上の別のコンピューターに属するIPアドレス/ドメイン名/ポートを使用するようMySQLに指示できます。SSHトンネリングと(私は信じている)SSL認証も使用できます。おそらく、他のDBMSでも同様に機能します。
ノイバート

@neubert:その場合、REST API DBALですよね?
RemcoGerlich

2
@RemcoGerlich-確かに、REST APIをDBALとして使用すると、不要な中間層が追加され、問題の診断が妨げられる可能性があります。つまり、DBALの十分に広い定義を使用するのであれば、Google SERPはDBALであると考えることができます。Googleのサーバーからページ分割されたデータを取得するには、HTMLを解析する必要があります
...-neubert
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.