連載第4回にて、API単体をコーディングレスで構築する手法を紹介しました。APIエコノミーが進展する状況においては、複数のAPIをいかに組み合わせていくか、また性能やセキュリティといった非機能面をどう担保していくかが求められます。

APIエコノミーは新しい分野ではありつつも、少しずつAPI Gatewayパターンのようなベストプラクティスに相当するものも出てきています。今回はAPIの組み合わせていく上での勘所を紹介します。

API Managementとは

実開発においては、APIを組み合わせて機能面を構築していくとともに、セキュリティや、流量制御・監視といった非機能面の担保も必要になってきます。各APIが非機能面を個別に実装すると、統一的な非機能の担保が困難になるだけでなく、実装のコストもかさみます。

こういった課題へのアプローチとして、非機能の担保を統一的に担うAPI Managementと呼ばれる領域が注目されてきており、3scale API Management PlatformAmazon API Gatewayといったものがあります。買収を発表したように、プラットフォームビジネスを展開する企業にとってAPI Managementの領域をどう考えていくかは、非常に重要な要素となっています。

デザインパターンの視点から見ると、API Gatewayパターンと呼ばれ、APIエコノミーやマイクロサービスを実現する上でベストプラクティスとなっています。

API Managementの有無と非機能実装箇所の違い

OAuth 2.0を使ったAPIのセキュリティ確保

APIを利用したサービス間の連携は私たちの生活に密着したものになってきています。Facebookのアカウントを使ってFoursquareにログインするなど、IDやパスワードなどの個人情報を入力しなくてもサービスを利用できるケースが増えてきました。Instagramに写真投稿すると、Facebookに連携するよう設定している方もいらっしゃるのではないでしょうか?

仮に、Facebookで利用しているIDとパスワードの組み合わせと同じものを、Foursquareに渡すとなると、認証や認可のセキュリティリスクが高まります。加えて、Facebookでパスワードを変更した場合にFoursquare側のパスワードも変更しなければならず、利便性の低下も招きます。

Facebookアカウントを利用したFoursquareログイン

OAuth 2.0はAPIアクセスにおける認可の標準プロトコルで、ID/パスワードではなく、「トークン」のやりとりにより上述のセキュリティ・利便性の課題を解決します。リソースオーナー(エンドユーザ)は、OAuthクライアント(Instagram)にIDやパスワードといった情報を入力することなく、Facebookと連携した認証や連携を行うことができ、OAuthサーバ側のAPIを利用可能になります。仮にトークンが悪用された場合においても、パスワード変更は必要なく、トークンを無効化することで、アクセスを遮断することができます。かつ、トークンは、特定のAPI(例:Instagramからの写真の投稿)のみに認可しているため、影響は限定的です。

トークンを使った認可

Dependency Hell(依存性地獄)の回避

APIエコノミーやマイクロサービスの時代において、さまざまなAPIが生まれてきており、APIの組み合わせにてシステムを構築します。システムでエラーが発生したが、どこのAPIで発生したかわからない。エラーがエラーを呼び、システムのリソースを食いつぶしてしまう。これらは、APIが互いに依存関係にあることに起因してきており、「Dependency Hell(依存性地獄)」と表現されることもあります。10年程前に、Springフレームワーク等のDIが出てきた時の「XML地獄」を連想される方もいらっしゃるかもしれません。

APIをサービスとして小さな単位で分割しているが故に、呼び出される側のサービスの稼働状況に起因して呼び出し側の処理が失敗する可能性があり、この状況にうまく対応する設計が必要となります。

特定のサービスの故障が連鎖し、システム全体の故障へと波及するのを防ぐため、NetflixのHystrixに代表される「Circuit Breaker」がエラー時のリトライの制御等を行います。Netflixにおいては、主に平日日中帯のオンライン時間帯に、サービスやデータセンタ単位で「敢えて」障害を発生させます。これにより、開発・運用チームは耐障害性と監視の有効性について、絶えず検討・改善することができます。監視に関してはPrometheusのようなAPIエコノミーに適した監視ツールの適用が有効です。

Spring Bootを使ったAPIをクラウドに載せてみる

これまでのオープン系の基盤構築では、システム負荷のピーク日・ピーク時間を元にサイジングを行った上でハードウェアを購入し、性能試験によって妥当性を評価するというやり方が多く採られてきました。

しかし、APIを公開するということは、不特定多数のユーザからアクセスされるケースが増え、システム負荷の不確実性が増してきます。連載第5回で紹介したように、クラウドを使うとCPUやメモリといったハードウェアリソースを柔軟に変更できます。特に、Auto Scalingを使うと、流量に応じて自動的にハードウェアリソースの増設を行うことができます。

今回はスクラッチでのAPI構築を極めて簡単に行うことができるSpring Bootを使ってAPIを構築し、Pivotal Web Servicesにデプロイします。

ブラウザからSpring Initializerにアクセスし、以下の通り入力します。Spring InitializerはHello Worldを実行するまでの手順を可能な限り簡易にしてくれる、いわゆるnutshell(ごく小さな単位)です。

  • プロジェクト種別 : Maven Project
  • バージョン : 2.0.0(SNAPSHOT)
  • Group : com.example
  • Artifact : demo
  • Search for dependencies : Web

Spring InitializerにおけるSpring Bootの設定

Search for dependenciesに指定したSpring Bootの「Web」機能を利用します。

Generate Projectをクリックすると、資材一式(demo.zip)がダウンロードされます。

資材の中にDemoApplication.javaをテキストエディタ等で開き以下の4箇所を編集します。最小限のアノテーションを設定するのみで、REST APIを構築できます。

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping; // 追加(1)
import org.springframework.web.bind.annotation.RestController; // 追加(2)

@SpringBootApplication
@RestController // 追加(3)
public class DemoApplication {

     // 追加(4)
    @GetMapping("/")
    String hello() {
        return "Hello World!";
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

ターミナルから以下を実行します。8080ポートでTomcatが起動されます。

$ ./mvnw spring-boot:run
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------
[INFO] Building demo 0.0.1-SNAPSHOT



2017-01-15 15:44:39.866  INFO 92134 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-01-15 15:44:39.881  INFO 92134 --- [           main] com.example.DemoApplication              : Started DemoApplication in 17.694 seconds (JVM running for 292.863)

ブラウザから「http://localhost:8080/」にアクセスすると、以下の通り表示されます。

Spring Bootを使ったHello World

ターミナルから以下を実行し、アプリケーションをビルドします。targetフォルダにdemo-0.0.1-SNAPSHOT.jarが作成されます。

$ ./mvnw package
[INFO] Scanning for projects...
Downloading: https://repo.spring.io/snapshot/org/springframework/boot/spring-boot-starter-parent/2.0.0.BUILD-SNAPSHOT/maven-metadata.xml

<中略>

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 03:24 min
[INFO] Finished at: 2017-01-16T06:09:51+09:00
[INFO] Final Memory: 21M/86M
[INFO] ------------------------------------------------------------------------

連載第5回で構築したクラウド上にアプリをデプロイします。ブラウザから以下の「URL」にアクセスすると、先ほどと同様の画面が表示されます。

$ cf push bootSample -p target/demo-0.0.1-SNAPSHOT.jar -m 256m
aaaaaaaa@bbbb.com としてアプリ bootSample を組織 yujishono-org / スペース development 内に作成しています...
OK
<中略>

URL: xxxxxxxx.cfapps.io
最終アップロード日時: Sun Jan 15 21:30:47 UTC 2017
スタック: cflinuxfs2
ビルドパック: java-buildpack=v3.11-offline-https://github.com/cloudfoundry/java-buildpack.git#eba4df6 java-main open-jdk-like-jre=1.8.0_111 open-jdk-like-memory-calculator=2.0.2_RELEASE spring-auto-reconfiguration=1.10.0_RELEASE


     状態   開始日時                 CPU      メモリー             ディスク           詳細
#0   実行   2017-01-16 06:31:46 AM   132.6%   256M の中の 191.4M   1G の中の 136.4M

*  *  *

今回はOAuthによる認証認可、Spring Bootを使ったAPI構築、またAPIのDependency Hellの回避について、APIを組み合わせる上での勘所としてご理解いただきました。

2017年3月6日に三菱UFJファイナンシャルグループが銀行口座などにアクセスするAPIを公開することを発表しました。同10日に金融庁がインターネットバンキング(IB)を利用していない一部金融機関を除き、APIの公開を実質義務化しました 。

APIエコノミーが進展し、多数のAPIを公開・組み合わせしていく時代においては、API Managementの重要性は増すばかりです。マイクロサービスを構築する上でも、性能・セキュリティ・データ一貫性担保などさまざまな要素がシステムのリリース後に表面化しないためにも、API Gatewayパターンのようなデザインパターンを確立していく必要が出てくるでしょう。

次回以降、APIを使ったシステムの見える化について取り扱います。複雑に絡み合うAPIを使ったシステム運用をどのように効率化していくかを、ツール(Zipkin/Kibana)を交えて解説します。

著者紹介


正野 勇嗣 (SHONO Yuji ) - NTTデータ シニア・エキスパート

2011年頃まで開発自動化技術のR&Dに従事。その後、開発プロジェクト支援やトラブルシューティング等に主戦場を移す。「ソースコード自動生成」に加えて、JenkinsやMaven等の「ビルド自動化」、JsTestDriverやSelenium等の「テスト自動化」を扱うようになり、多様化する開発自動化技術動向に興味。

最近は第四の自動化であるInfrastructure as Code等の「基盤自動化」の魅力に惹かれている。開発自動化技術に関する雑誌・記事執筆も行う。2児のパパ。