最初のモジュールは、HTTPリクエストを作成し、それを送信し、レスポンスを取得することで終了しました。

これから先も何度もこのようなことをすることになります。サードパーティのサーバーにリクエストを送ることもあります。自分自身がそのようなリクエストを受け取り、レスポンスを返すアプリケーションを作る。リクエストを処理するための複雑なロジックを作成する。

ですから、このようなリクエストに関することは、徹底的に勉強して、細かく分析しておくとよいでしょう。ただ単にリクエストをどこかにコピーして繰り返すのではなく、それがどのような仕組みになっているのかを本当に理解することができるように。

これが、2番目のモジュールで行うことです。さあ、行きましょう。

理論から始めましょう。


REST APIを学ぶ

REST APIの基本

最初のモジュールで宿題をやってドキュメントを勉強したのなら、APIという頭文字に気づいたはずです。実は、ネットワーク上の何らかのサービスやアプリケーションとのやりとりを理解したい場合、開発者が最初に勉強すべきなのはAPIドキュメントなのです。

API - Application Programming Interface(アプリケーション・プログラミング・インターフェース)。 これは、クライアントとサーバーが互いに通信するための方法を記述したものです。私たちはAPIのドキュメントを開き、そこからサーバーから必要なデータを取得する方法を学びます。

私たちは常に、このやり取りがシンプルで理解しやすいものであることを望んでいます。これにより、開発者(新しいサービスを設計する際に車輪の再発明をする必要がない)とユーザー(以前に慣れ親しんだサービスと同じ原理で動作する場合、サービスははるかに容易に習得できる)の両方にとってタスクが簡素化されます。ここで、新しい用語であるRESTを覚えておくとよいでしょう。

RESTとはRepresentational State Transferの頭文字をとったものです。あまりピンとこないかもしれませんが、簡単に言うと、RESTはクライアントとサーバーの間のインタラクション(情報交換)のスタイルの1つです。

これは、何か厳格なルールや要件があるわけではありません。RESTは、特定のプログラミング言語の使用を強制するものでもなければ、厳格なガイドラインで手を縛るものでもない。RESTはアーキテクチャのスタイルと呼ばれ、システムアーキテクチャが遵守すべき6つの原則を定義している。

したがって、RESTの原則を踏まえて開発されたAPIをREST APIと呼び、そのアプリケーション自体をRESTfulと呼びます。

今回はまさにそのようなRESTfulなアプリケーションを作成することになるので、早速その遵守すべき原則について説明します。

  1. クライアント-サーバモデル。この原則は、クライアントとサーバーの分離、ニーズの差別化を定義している。クライアントは、データがどのように保存されているかを気にする必要はなく、主なものは要求に応じて発行されることである。一方、サーバーは、クライアントがこのデータをどのように処理し、どのように表示するかは気にしない。そのため、互いに独立した開発が可能となり、システムのスケーラビリティが向上する。
  2. ステートレス(静的)であること。この原則は、サーバーがこのクライアントとの過去の経験に基づいてレスポンスを「考え出す」べきではないことを意味します。どのようなリクエストも、以前のリクエストに関係なく、その処理に必要なすべての情報を含むように行われます。
  3. キャッシュする。 送信データを最小限にするために、キャッシュの仕組みがあります。例えば、あるページにロゴが表示されている場合、それを毎回サーバーにリクエストするのは意味がない。ロゴは頻繁に変わるものではないので、一度取得して、クライアントのコンピュータのキャッシュに保存しておけば十分である。しかし、車の現在の速度についての情報を得る必要がある場合、キャッシュは何の役にも立たない。この原則は、サーバーから送信されるデータをキャッシュ可能かどうか指定することを決定する。
  4. 統一されたインターフェース。 この原則は、クライアントとサーバーのやりとりの形式を統一することを定義しています。すべてのリクエストの構造は同じでなければなりません。データは、誰が要求しても同じ形式で送信されなければならない。
  5. レイヤーシステム。 クライアントとサーバーは必ずしも直接通信するわけではありません。データ転送はいくつかの中間ノードを経由することもある。この場合、クライアントもサーバーも、最終的なアプリケーションとやりとりしているのか、中間ノードとやりとりしているのかがわからないようなシステムになっています。これにより、サーバーの負荷分散、スケーラビリティの向上が可能になる。
  6. コードオンデマンド (任意)必須ではない唯一の原則です。これによると、クライアントはサーバーから実行可能なコード(例えばスクリプト)をダウンロードすることで機能を拡張することができます。この場合、コードはオンデマンドでのみ実行されなければならない。

理論が多すぎないか?

では、実践してみましょう。

APIリクエストの作成

AppMasterを開き、それを使ってAPIリクエストを作成し、このリクエストがどのように機能するかをより深く理解することにしよう。


APIリクエストは、"Business logic" セクションの "External API Requests" タブに作成されます。

いよいよ "+新規APIリクエスト "をクリックします。


名前と説明は何でも設定できますが、これらは私たちが個人的に使用するためだけのものです。

本当に重要なデータを扱いましょう。

リクエストの作成に最低限必要なのは、メソッドとアドレス(URL)を指定することです。最後の1つから始めましょう。


URL- Uniform Resource Locator(ユニフォーム・リソース・ロケーター)。インターネット上の特定のリソースに与えられるアドレス。ブラウザのアドレスバーにURLを入力すると、目的のサイトが表示されます。ブラウザーのアドレスバーにURLを入力し、目的のサイトを開く。同時に、リソース自体は、画像、ビデオ、データセットなど、何でもよい。重要なのは、このリソースには特定のポインタ、つまりこのリソースを取得するためのリクエストを送信するためのURLがあるということです。

そのアドレスのデータを参照しながら、リクエストの方法(タイプとも言えます)、つまり、このデータに対して実際に何をする必要があるのかを示します。

最初のモジュールのタスクに対してリクエストを送ると、データを受け取ることができました。これがGETメソッドです。このメソッドは最もわかりやすいメソッドであり、また唯一必要とされるメソッドでもあります。そのため、明示的に指定しなくても、デフォルトでこれがGETであると判断されました。

他にどんなメソッドがあるのか見てみましょう。


HTTPの規格自体は、使用できるメソッドの数を制限していません。同時に、互換性を維持するために、最も標準的なメソッドの一部だけが今も使われています。AppMaster APIのリクエストで使用できるメソッドは、5種類あります。

  • GETする。すでに対処済みです。このメソッドは、リソースの提供を要求し、データを受け取ります。
  • POST。どこかからデータを受け取るには、まずこのデータをそこに置く必要があります。POSTメソッドはまさにそれを行うものです。データをサーバーに送信し、リソースを作成します。
  • PUT。POSTメソッドと似ていますが、このメソッドはデータを更新するのが仕事です。新しいデータを作成するのではなく、既存のデータを置き換えて更新します。
  • DELETE。その名の通り、データを削除します。
  • PATCH。このメソッドはPUTと似ているが、データを完全に置き換えるのではなく、部分的に更新するために使用される。例えば、PATCHメソッドを使用すると、記事のタイトルを変更したり、あるパラメータの値を変更したりすることができる。

ここで重要なのは、サーバーはメソッドで指定されたことを正確に実行する必要は全くないという事実を考慮することです。DELETEメソッドを使ってあるページのアドレスを送ることはできますが、これはサーバーが実際にそれを削除することを意味するものではありません。しかし、純粋に理論的には、彼はGETコマンドでこれを行うことができます。あるいは、何も変更せず、同時にPOSTに応答してデータを送信する。開発者がそのように設定したというだけの理由で。

ここでRESTが登場するわけだが、これは命令の遵守に同意し、混乱を止め、メソッドに示されたことを正確に実行する時だと言っているのである。少なくとも、これが主な作業であるべきです(必ずしもこれだけではありませんが)。例えば、ある記事の内容をGETメソッドで転送するとき、同時にその記事の閲覧数のカウンターを1増やすことができる。

というわけで、データがどこにあって、何ができるのかがわかりました。さらに進めて、リクエストが他にどのようなコンポーネントを持つことができるのかを見てみましょう。


URL パラメータ。URLの一部しか知らないという状況があります。例として、Appmaster.ioのウェブサイトの記事があります。すべての記事の開始アドレスは同じです - https://appmaster.io/en/blog/。しかし、各記事にはそれぞれタイトルがあり、それに応じて、この特定の記事を正確に表示するための個別の部分があります。

このような場合、URL Params が使われます。一般的な部分は即座に規定し、残りはプロセスで決定するようにします。その結果、URLはhttps://appmaster.io/ru/blog/:id/ のような形で記述されます。

既知の部分はそのまま記述し、「:」記号の後に変数部分を配置する。この変数部分の名前(すでに「:」がない)がパラメータのリストに追加される。この場合、可変部分は複数存在する可能性があり、その位置はURLの任意の場所となります。


クエリパラメータ。最初のモジュールで boredapi.com にリクエストを送ったのを覚えていますか?そして、アドレスに加えて、追加のデータが規定されていました。それがクエリパラムでした。

これらはURLの後に書かれていて、"? "記号で区切られています。パラメータ名、"="記号、パラメータ自体の値が表示される。複数のパラメータを一度に使用する場合は、"&"記号で区切られる。

しかし、AppMasterでパラメータを指定する場合、リクエストルールについて考える必要はない。全て自動的に適切に整形される。パラメータ自体の名前を指定して、リストに追加するだけでいいのです。

クエリパラメータは、データソースは同じでもデータそのものが異なる可能性がある場合に使用します。例えば、Boredapiには膨大なリストが含まれていました。しかし、私たちは一人の人間を対象としたものだけに興味があり、それをリクエスト・パラメータで示したのです。

もう一つのオプションは、アクセスキーです。モジュール1でAlphavantageを参照する際に、このオプションを使用したことがあるかもしれません。データは、登録後、リクエストパラメータでパーソナルキーを送信した後にのみ取得することができました。

インターネット上で閲覧するページにも、様々なパラメータが含まれているはずです。例えば、Ventusky.comの天気予報のページを開くと、クエリパラメータに緯度と経度の地理的な値が送信されます。

ヘッダー。リクエストヘッダ。通常、ヘッダーにはリクエストに関するサービス情報(メタ情報)が含まれる。ヘッダによって、サーバーはデータを要求しているクライアントに関する詳細な情報を得ることができます。ヘッダーには、どのブラウザーが使われているか、どのエンコーディングでレスポンスが期待されているか、どの言語で書かれているか、リクエストの正確な時刻、などの情報が含まれることがあります。保護されたデータにアクセスする場合、ヘッダーには認証キーが含まれることがあります。

ほとんどの場合、ヘッダは任意です。最初のモジュールでも、すでにヘッダを指定しないリクエストを行いました (ただし、ヘッダなしで実際にリクエストが送信されたわけではありません)。

ボディ。リクエストのボディです。GET リクエストでは通常これを指定しませんが、もし何らかのデータをサーバーに送りたい場合、POST や PUT リクエストを送れば、このデータはリクエストボディに置かれます。同時に、リクエストボディには、例えば動画ファイルを送るなど、何らかの数値や文字列にとらわれず、複雑なデータを置くことができる。

サーバーから送られてくるレスポンスも、ほぼ同じ仕組みで動いています。明らかな理由により、リクエストパラメータを持ちませんが、ヘッダとボディはレスポンスに含まれます (ただし、空である場合もあります)。

重要な違いは、レスポンスのステータスです。

ステータスコード。これはサーバーレスポンスの最初の行に入ります。ステータスは3桁の数字(コードそのもの)で、その後にそれを説明するフレーズが続きます。

ステータスコードによって、リクエストの結果を知り、次にどのようなアクションをとるべきかを理解することができるのです。

ステータスコードは、5つのクラスに分類されています。コードの最初の桁が、特定のクラスに属するかどうかを決定します。それらを分解してみましょう。

1xx- 情報コード。リクエストの進行状況を報告します。実際の運用では、ほとんど使用されません。

2xx- 成功コード。すべてが正常に行われ、リクエストが成功したことを報告する。GETリクエストの応答として、私たちは通常200(OK)コードを受け取ることを期待します。PUTリクエストに成功すると、201 (Created) コードが送信されます。

3xx- リダイレクト。リクエストが別のアドレスに送信される必要があることを示します。例として、コード301(Moved Permanently)があり、必要なデータが新しいアドレスにあることを示します(新しいアドレス自体はLocationヘッダで渡されます)。

4xx-クライアントエラーコード。最も有名なのは404(Not Found)で、指定されたアドレスに必要なデータが存在しないことを報告する。その他の一般的なケース。400(Bad Request、リクエストの構文エラー)、401(Unauthorized、アクセスに認証が必要)、403(Forbidden、アクセスが拒否された)。

5xx- サーバーエラーコード。サーバー側で発生したエラーを報告します。例として500(内部サーバーエラー、既知のコードに帰着できない不可解なエラー)、503(サービス不能、サーバーが技術的な理由で一時的にリクエストを処理できない)。

ここまでで、REST APIとHTTPリクエスト、レスポンスの構造を理解するための基本的な情報を扱ったと考えてよいでしょう。あとは1点だけ、データ型について明らかにしておきます。AppMasterでAPIリクエストを作成しようとした場合、すべてのデータ(パラメータ、ヘッダ、ボディ)が名前だけでなくデータ型も要求されることに気づいたと思います。


通常、人間にとってデータをどのように扱うかは、特定のコンテキストがあるため、非常に明白である。例えば、2 + 2 = 4と知っているとしよう。これらは数字であり、足し算の結果は別の数字になると推測される。

しかし、それは数字ではなく、テキストデータかもしれない。そうすると、足し算の結果は文字列の連結となり、2+2が「22」になる可能性がある。ここでは、コンピュータが何も考えなくてもいいように、データ型が正確に示されているのだ。そして同時に、他の課題も解決している。例えば、電話番号の入力欄にメールアドレスを登録することはできませんが、間違ったデータを入力しないようにするためです。

データ型には多くの種類がありますが、ここでは最も基本的なものを取り上げ、残りのデータ型については、このコースの次のモジュールで詳しく説明します。

文字列- 文字列データ型、特別な書式のないプレーンテキスト。

Integer- 整数データ型。カウンタや分数を必要としない計算に使用されます。

Float- 浮動小数点数。精度を上げる必要があり、整数値では十分でない場合に使用されます。

ここで論理的な疑問が生じるかもしれません。なぜ常にFloatを使わないのか,それならなぜIntegerが必要なのか,ということです.しかし、精度を上げるにはより多くのリソースが必要です。小さな計算であれば、これは全く気にならないかもしれませんが、大量のデータの場合、合理的なデータ型を使用することで、計算能力やディスクスペースに対する要求を大幅に削減することができます。

Boolean- ブール型データ型。最も単純なデータ型。2つの値のいずれかを取り、TrueまたはFalseと表記される。1(真)、0(偽)という形で指定されることが多いようです。


ホームワーク

宿題から最初のモジュールへのリクエストを、AppMasterのExternal API Requestsセクションで作成し、繰り返してください。

  1. BoredAPIへのリクエストを作成します。ドキュメントにある5種類以上のパラメータを指定します。必要なパラメータのみを指定し、複数のリクエストを送信します。
  2. Alphavantageにリクエストを作成します。パラメータを使用して、異なる通貨間のレートを取得します。