Web API の目的と技術要素 ③Web API の開発に必要な技術要素

by 杉本和也 | 2024年10月30日 | 最終更新日:2024年10月31日

Web APIの目的と技術要素 ③Web API の開発に必要な技術要素

※本記事は Software Design 2022年8月号 Web API 特集 「第1章:Web APIの目的と技術要素」の記事を再編集したものです。以下の章に分けて公開しています。

ここからは実際にWeb API を開発するにあたって必要となる技術要素について解説していきます。

なお、Web API は前述のとおりネットワークのプロトコル、現状はほぼHTTP(HTTPS を含む)で利用するリモートAPI です。HTTP の機能を活用して、プログラム同士のやりとりが成立していれば、それらはすべてWeb API と呼んで差し支えありません。

しかしながら、その自由度の高さゆえに今まで数多くのWeb API のベストプラクティスが 編み出されていきました。それぞれが好き勝手に作ってしまうと、効率的なサービスの構成が難しくなることは容易に想像できるでしょう。提供側にとって、利用側にとって作りやすい、使いやすいAPI とは何か?必要な技術要素を通じて理解してみましょう。

ベースプロトコル:HTTP

それではまずHTTP についておさらいしておきます。とはいえ、HTTP も膨大な仕様の上に成り立っているため、今回は主流である「HTTP/1.1」の仕様と、Web API 利用時におもに必要となる要素に絞って解説します。

HTTPはクライアントとサーバが通信を行い、ハイパーテキスト、つまるところHTMLといった複数の文書を関連付けたテキストデータなどの送受信に利用されるプロトコルの1つです。「クライアントからサーバへのリクエスト」そして「サーバからのレスポンス」で構成されており(図2)、それぞれのリクエスト/レスポンスのやりとりが独立した「ステートレス」なプロトコルである点が特徴です。

▼図2 HTTP のリクエスト/レスポンスの流れ

HTTP のリクエスト/レスポンスの流れ

実際のリクエストを見てみましょう。Web API のリクエストを行っているHTTP はリスト1のようなフォーマットの構成で成り立っています。

▼リスト1 HTTP リクエストのフォーマット

POST /books HTTP/1.1

Host: example.com
Authorization: Basic dXNlcjpwYXNzd29yZA==
Content-Type: application/json
Content-Length: 32

{
    "title": "hello world"
}

1行めを「リクエストライン」、2行めから5行めまでを「ヘッダ」、6行めで一度空行を挟んで、7行め以降を「ボディ」と呼びます。

リクエストラインにはGET やPOST といったリクエストの役割を定義する「HTTP メソッド」と、リクエストを送信する先のリソースを一意に示す「/books」といったパス、および「HTTP/1.1」と記述されているプロトコルバージョンで成り立っています。

パスは「/books」に続いて、「?name=hello」といったクエリ文字列(Query String)として疑問符(?)に続いてパラメータを定義することが可能です。

メソッドは「GET」「POST」「PUT」「HEAD」「DELETE」「OPTIONS」「TRACE」「CONNECT」 の8種類と拡張仕様(PATCH など)があり、たとえば「GET」は対象パスのリソースを取得、「POST」はリソースにデータを送信、データの追加といった役割を担います。

「ヘッダ」はリクエスト内容の制御情報で各行ごとに「フィールド名:内容」という構成で成り立っています。HTTP/1.1では「Host」ヘッダが必須となっており、Host を用いてリクエストの送信先となるサーバホスト名やポート番号を指定します。

Host 以外にもさまざまなヘッダが存在しており、たとえばリクエストするデータのフォーマットを指定する「Content-Type」や受け取るデータのフォーマットを指定する「Accept」、認証情報を格納する「Authorization」などがあります。

そして、送信するデータを構成する「ボディ」です。この例ではJSON のフォーマットでリクエストしていますが、XML やキーと値の組み合わせが「=」で結ばれ、かつ「&」区切りでまとめられたx-www-form-urlencoded もあります。

送信したリクエストに対するサーバからのレスポンスはリスト2のようなフォーマットになります。

▼リスト2 HTTP レスポンスのフォーマット

HTTP/1.1 200 OK
Date: Thu, 02 Jun 2022 11:14:42 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Content-Length: 18

{"sample":"world"}

こちらもリクエストと大まかなフォーマットは一緒ですが1行めを「ステータスライン」と呼びます。2行めから5行めまでを「ヘッダ」、6行めで一度空行を挟んで、7行め以降は「ボディ」となっており、この部分はリクエストの仕様と大きく変わりません。

ポイントとなるのは「ステータスライン」に含まれている「200 OK」という部分です。「200」がステータスコードで「OK」がテキストフレーズとなっており、これによりクライアントはサーバの処理結果を識別します。

「200 OK」以外にも「500 Internal Server Error」や「404 Not Found」など、みなさんがWeb サイトを閲覧しているときに見ているものも多いと思います。

最後に「ステートレス」ですが、各リクエストは独立しており、サーバはクライアントの状態を意識しない、というものです。これによりサーバ/Web API 側はクライアントの状態を意識して、情報を出し分けたり、リクエストの順番を意識したりする必要がありません。

アーキテクチャスタイルと各種プロトコル

ここまで、まずはHTTP の基本的な仕様を見てきました。前述のとおり、Web API はこのHTTP の仕様に則って通信を行っていれば、Web API としてみなすことができます。

しかしながら、HTTP のメソッドやボディの使い方に関しては、Web API の使い方として細かな定義はありません。

たとえば「ユーザーのデータを取得するリクエスト」を送るときには「GET /users?name =sample」のようなデザインだけでなく、「POST /search」のようにしつつ、ボディで検索条件を渡すようなデザインもWeb API として開発することができます。しかし、このようなデザインの自由度の高さゆえにさまざまなWeb API の仕様が存在し、利用者は個々の Web API を使おうとするたびに、各デザインの学習コストおよびインターフェースレベルでの実装コストに悩まされます。提供側にとってもそれは同様で、「利用者にとってどのようなデザインがベストなのか?」「スタンダードとなっているのは何か?」といったことに毎回悩みつつ、実装する必要があります。

そこで、さまざまなWeb API としてのスタンダードやプロトコル・仕様に関する議論がなされ、REST、OData、SOAP、GraphQL、gRPC といった要素が出てきました。その中で、現状数多く利用されていて、みなさんも聞いたことがあると思われるのは「REST(Representational State Transfer)」でしょう。今回はこのREST に絞って解説します。

REST はWeb のような分散ハイパーメディアシステムで用いられるWeb API のソフトウェアアーキテクチャスタイルの1つです。

元の論文(https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)にさまざまな要素が出てきますが、現在多くの人々に支持されているのは、Wiki pediaでも紹介されている次の4つの設計原則(https://ja.wikipedia.org/wiki/Representational_State_Transfer)に従って開発されるWeb API ではないでしょうか。

  • Addressability:リソースを一意に識別する「汎用的な構文(URL)」の定義
  • Uniform Interface:すべての情報(リソース)に適用できるHTTP メソッドの定義
  • Client-Server/Stateless:ステートレスなクライアント/サーバプロトコル
  • Connectability:アプリケーションの情報と状態遷移の両方を扱うことができる「ハイパーメディア(リソースリンク)」の使用

これらの要素は1つ前に述べたHTTP の仕様をWeb API としても適切に活用できるという点に基づいて考えられています。

Addressability は、Web 上に存在する名称を持ったあらゆる情報(リソース)を、アドレスとして一意に特定するもの、つまりURL(注10)のことを指します。とくに重要な部分はパス部分であり「/users」のような名詞を用いることでしょう。

注10) URL と同じような意味合いで「URI(Uniform Resource Identifier)」という用語が使われることがあります。URI は、リソースの場所を識別する「URL(Uniform Resource Locator)」とリソースの名前を識別する「URN(Uniform Resource Name)」を総称した用語です。また、API にアクセスするためのURI やURL のことを「エンドポイント」と呼ぶこともあります。

Uniform Interface は、前述のリソースに対して適用できるHTTP メソッド「GET」や「POST」を組み合わせたインターフェースとして提供することを指します。たとえばユーザーを取得したいなら「GET /users」、ユーザーを追加したいなら「POST /users」というように、HTTP メソッドとURL の組み合わせ、つまり動詞と名詞の関係性でWeb API のデザインを統一します。

Client-Server/Statelessは「HTTP」がクライアント/サーバのアーキテクチャスタイルを採用していることに基づいたうえで、サーバ側はクライアントの状態を意識せず、一つ一つのリクエストが独立して処理を完結できる(Stateless である)デザインにしていることを指しています。

これによりサーバ側はクライアントの状態を意識したデータの保持および分岐・計算処理が不要となるため実装が簡略化でき、またそれぞれのリクエストが独立していることからスケーラビリティに寄与しやすくなります。

最後にConnectability です。これは、通常のHTML と同様に別なリソースに移動するときの指標となるリンク、ハイパーメディアとして利用可能な値を持ってWeb API が提供されることを指します。例えばページネーションを行うときに次のページのリクエストがレスポンスから識別できるように、リンク情報を持つようなデザインを指します。これらの原則に従って開発されたWeb API が、しばしばRESTful と称されます。

極端な例が多いですが、表1にREST としてのGood パターン/Bad パターンをまとめてみました。

▼表1 RESTにおけるGood/Bad パターンのまとめ

RESTにおけるGood/Badパターンのまとめ

ちなみによく比較対象に出される「SOAP」はXML ベースのRPC(Remote Procedure Call)プロトコルです。

REST はHTTP メソッドとリソースとなる名詞の組み合わせで操作方法を明示するのに対して、SOAP はProcedure という名のとおり、操作に関する手続きを関数として表現していることが特徴でしょう。XML のデータフォーマットで関数に関する情報を定義して、リクエスト/レスポンスを行います。

これら以外にも、先述のとおりOData、GraphQL、gRPCなど、さまざまな規格・プロトコルが存在します。

https://www.odata.org/

https://graphql.org/

https://grpc.io/

前述のとおり現在の主流はREST API となりますが、ここでみなさんに注意していただきたいことが1つあります。それは「REST はプロトコルや規約ではなく、あくまでWeb API の設計思想、ソフトウェアアーキテクチャスタイルの1つである」という点です。

表1でいくつかBad パターンを挙げましたが、前述のとおりREST API はプロトコルではないため、そのようなREST API は数多く世の中に存在します。

たとえば多くのREST API では大量のデータを取得できるサービスの場合、ページネーションのしくみを提供しますが、そのフォーマットにはルールがありません。たとえば Page-PageSize やLimit-Offset を用いるものなど、多様なアプローチがあります。レスポンスのデータ構造や型もそうです。数値の型1つとっても、これがInt なのかDecimal なのか、Float なのか区別がつきません。そのため、利用する側も「これが正しいのだろうか?」と悩みながら、Web API との連携実装を進めることになります。

そこで、もう1つ紹介したい技術要素が「API 仕様記述フォーマット」です。

Web API の仕様記述フォーマット

Web API の仕様記述フォーマットとは「プログラムが読み取り可能な外部ファイル」の形で対象となるWeb API 仕様を定義するための仕様です。

デファクトスタンダードになっているのは「OpenAPI Specification(以下OpenAPI(以前はSwagger Specification と呼ばれていました。))」でしょう。そのほかにも有名なところではRAML、SOAP の関連仕様であるWSDL もこのフォーマットにあたりますが、今回はOpenAPI に絞って解説します。

https://www.openapis.org/

ベースとなる考えは、REST API の仕様(クエリ文字列や認証方式、HTTP メソッドは何を使うのか、レスポンスの仕様、JSON 構造はどうなっているのか、型はどうなっているのか、など)を記述するための仕様であるということです。

リスト3はStoplight Studio(https://stoplight.io/studio)というOpenAPI の記述を支援するためのツールで提供されているサンプルの一部です。本稿では詳細は省きますが、「GET / users/{userId}」をリクエストするためのパスやパラメータの定義、レスポンスの構造やサンプルが記述されていることが見てとれると思います。

▼リスト3 Stoplight Studio が提供するサンプルコード(一部)

openapi: 3.1.0
info:
  title: Sample API
  version: '1.0'
  summary: This is sample API
  description: ''
servers:
  - url: 'http://localhost:3000'
paths:
  '/users/{userId}':
    parameters:
      - schema:
          type: integer
        name: userId
        in: path
        required: true
        description: Id of an existing user.
    get:
      summary: Get User Info by User ID
      tags: []
      responses:
        '200':
          description: User Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              examples:
                Get User Alice Smith:
                  value:
                    id: 142
                    firstName: Alice
                    lastName: Smith
                    email: [email protected]
                    dateOfBirth: '1997-10-31'
                    emailVerified: true
                    signUpDate: '2019-08-24'
        '404':
          description: User Not Found
      operationId: get-users-userId
      description: Retrieve the information of the user with the matching user ID.

そして、このOpenAPI の大きな特徴はこれらの仕様を「プログラムが読み取り可能な外部ファイル」の形にしてあるという点です。これにより各種ツールを使用して、API ドキュメントの自動生成や、各種プログラミング言語用のサーバ/クライアントコードまたはSDK の生成、テストツールでの利用もできるようになります。

OpenAPI の存在により、私たちはJSON のデータ構造を都度解析してプログラムのクラス定義やSDK を作成する作業や、ドキュメントを毎回整える作業に手間をかけなくて済むようになります。

国内でOpenAPI を活用してWeb API を公開している例としては、電子契約サービスのクラウドサインが挙げられます。クラウドサインのWeb API はSwaggerHub と呼ばれるOpenAPI の共有/ドキュメントサービス上で公開されており(https://app.swaggerhub.com/api/CloudSign/cloudsign-web_api)、API 仕様がグラフィカルにわかりやすく確認できるのはもちろん、各言語のSDK も自動生成できるようになっています。

▼図3 クラウドサインAPI のSDK 自動生成機能。生成対象の言語を選択できる

 クラウドサインAPI のSDK 自動生成機能。生成対象の言語を選択できる

このようにOpenAPI で定義することにより、 提供側・開発側で仕様の認識、実装に関する差異を防ぎ、効率的な連携・実装を進めることができるようになります。

その他の要素

ここまでさまざまなWeb API 開発に関する技術要素を紹介してきましたが、これら以外にもまだまだ知らなければいけない要素は多様に存在します。下記はその一例です。

  • OAuth やBasic などの認証・認可
  • Web API のテスト
  • キャッシュ
  • クッキー

たとえば、「認証」に関する要素はその筆頭でしょう。昨今のWeb API を利用するうえで欠かせない、OAuthのしくみなどはぜひ理解していただきたい要素です。ただ、それらの技術について詳細を語るのは誌面不足のため、ぜひ本誌の認証・認可特集(本誌2020年11月号 第1特集「今さら聞けない認証・認可」 など)で補完してほしいと思います。

トライアル・お問い合わせ

関連コンテンツ