【初心者わかりやすく】REST APIとは?HTTPのしくみとcurlでの試し方

クラウドの管理や機器の自動化を調べていると、「REST API」という言葉をよく見かけます。Microsoft 365 や Azure も、管理用の REST API を公開していて、画面で行う操作の多くをプログラムから行えます。

この記事では、REST API を初めて触る人向けに、REST という名前の意味から、リクエストとレスポンスの読み方までを図で説明します。後半では、インターネットに公開されている API に curl でリクエストを送り、実際の応答を自分の目で確かめます。

この記事でわかること
  1. REST という名前の意味と、REST API の4つの考え方
  2. リクエストとレスポンスの中身(メソッド、ステータスコード、ヘッダ、JSON)
  3. curl で外部の公開 API を呼び、200・404・401 の応答を読む方法

API とは

API(Application Programming Interface)は、ソフトウェアが外部のプログラムに向けて用意した窓口です。人はブラウザの画面を見てボタンを押しますが、プログラムは画面を読めません。そこで、決まった形式で依頼を送り、決まった形式で結果を受け取れるようにしたものが API です。

画面からの操作も API からの操作も、最終的にはサーバの同じデータを扱います。違うのは入口です。API を使うと、何十台分の設定確認や毎月のアカウント棚卸しのような繰り返し作業を、スクリプトに任せられます。

画面(GUI)API ボタン・入力欄URL・JSON 人(ブラウザ)プログラム サーバ 同じデータ
図1 画面での操作と API での操作

REST API とは

REST は「Representational State Transfer」の頭文字をとった言葉です。HTTP/1.0 の仕様の共同執筆者で、HTTP/1.1 の中心的な設計者でもある Roy Fielding が、Web がうまく動いている理由を設計の考え方として整理し、2000年の博士論文で REST と名付けました。特定のプロトコルや製品の名前ではなく、「こういう約束で作るとうまくいく」という設計のスタイルを指します。

「REST」という名前の意味

3つの英単語に分けると、意味がつかみやすくなります。

Representational= 表現(の)JSON などの形にしたデータState= 状態リソースのその時点の中身Transfer= 転送HTTP でやり取りする あるユーザーの情報サーバ上のデータ {“displayName”: …}JSON の文字 State(状態)Representation(表現) HTTP で送るTransfer(転送)クライアント
図2 Representational State Transfer を分解すると
単語意味
State(状態)サーバにあるリソースの、その時点の中身です。たとえば Microsoft Graph なら、「あるユーザーの表示名や部署が、いまどうなっているか」が状態にあたります。
Representational(表現の)状態を、相手が読める形にしたものが「表現」です。サーバの中のデータそのものを渡すのではなく、JSON のような文字の形に置き換えて渡します。同じリソースでも、JSON や HTML など、違う表現で返すことができます。
Transfer(転送)表現を HTTP のリクエストやレスポンスに入れて、クライアントとサーバの間で送ります。

つなげると「リソースの状態を、表現にして転送する」という意味になります。Fielding 自身は、Web ページのリンクを選ぶと次のページ(アプリケーションの次の状態を表したもの)が送られてくる、という Web の動きを思い浮かべてもらうための名前だと説明しています。ブラウザで Web ページを見るときと同じしくみを、プログラム同士のやり取りに使うのが REST API だと考えると、イメージしやすいと思います。

REST API の4つの考え方

実務で REST API と呼ばれているのは、おおむね次の4つの考え方に沿った Web API です。

1リソースを URL で表す対象ごとに URL が決まっている(Microsoft Graph の例)ユーザーの一覧/v1.0/users自分のプロフィール/v1.0/me2操作は HTTP メソッドで表すURL は同じでも、メソッドで操作が変わるGET取得PUT置き換えDELETE削除1つのリソース3サーバは前のやり取りを覚えない毎回、必要な情報をすべて付けて送る1回目:認証情報+依頼2回目:認証情報+依頼クライアントサーバ4データは「表現」でやり取りする中身そのものではなく、JSON などの形で送るリソース{ … }JSON(表現)
図3 REST API の4つの考え方

1つ目は、リソースを URL で表すことです。操作したい対象(パッケージのタグ、ユーザーのプロフィールなど)を「リソース」と呼び、それぞれに URL を割り当てます。URL を見れば、何を操作しようとしているかが分かります。

2つ目は、操作を HTTP メソッドで表すことです。「取得」「置き換え」「削除」といった操作の種類は、URL ではなく HTTP のメソッド(GET、PUT、DELETE など)で伝えます。同じ URL でも、メソッドを変えると操作が変わります。

3つ目は、サーバが前のやり取りを覚えないこと(ステートレス)です。サーバは「さっき誰からどんな依頼があったか」を覚えておかず、届いたリクエストの中身だけで処理します。そのため、クライアントは毎回、認証情報も含めて処理に必要な情報をすべて付けて送ります。手間は増えますが、サーバ側は1件ずつ独立に処理できるので、台数を増やして負荷を分けやすくなります。

4つ目は、データを「表現」でやり取りすることです。名前の意味のところで説明したとおり、サーバの中のデータそのものではなく、JSON などの形にしたものを受け渡します。

補足

Fielding の論文では、REST の制約としてクライアント/サーバ、ステートレス、キャッシュ、統一インターフェース、階層化システム、コードオンデマンド(任意)が挙げられています。世の中で REST API と呼ばれているものがこれをすべて満たしているとは限りません。この記事では、上の4つの考え方に沿った HTTP の API を REST API として説明します。

リソースと URL

REST API では、リソースごとに URL が決まっています。Microsoft 365 や Entra ID のデータを扱う Microsoft Graph を例にすると、「自分のプロフィール」は次の URL で表されます。

https://graph.microsoft.com/v1.0/me スキーム通信の方式ホストどのサーバかパスどのリソースかAPI のバージョン自分
図4 URL の各部分の役割(Microsoft Graph の例)

リソースを表すのはパスの部分です。/v1.0 は API のバージョンで、その後ろの me が「サインインしている自分」というリソースです。/v1.0/users にすると、ユーザーの一覧という別のリソースになります。

HTTP メソッド:何をしたいか

同じリソースに対して「見る」「作る」「書き換える」「消す」を区別するのが HTTP メソッドです。よく使うのは次の5つです。

メソッド主な用途安全べき等
GETリソースを取得する○○
POST送ったデータをサーバに処理させる。新しいリソースの作成によく使う××
PUT送った内容でリソースを作成する、または丸ごと置き換える×○
PATCHリソースの一部を変更する××(作り方によってはべき等にできる)
DELETEリソースを削除する×○

「安全」は、サーバの状態を変えないという意味です。「べき等」は、同じリクエストを何回送っても、1回送ったときと同じ結果になるという意味です。たとえば通信が途中で切れて応答が分からなかったとき、べき等な PUT や DELETE は送り直しても結果が変わりません。べき等でない POST を送り直すと、同じデータが2件できることがあります。

実際の API では、URL とメソッドをどう組み合わせているかを見てみます。Microsoft Graph でユーザーを操作するときは、次のようになっています。URL は /v1.0/users(一覧)と /v1.0/users/{id}(1人)の2種類だけで、何をするかはメソッドで決まります。変更には、一部だけを書き換える PATCH が使われています。

GET一覧を取得POSTユーザーを作成GET1人を取得PATCH一部を変更DELETE削除 /v1.0/usersユーザーの一覧(コレクション) /v1.0/users/{id}1人のユーザー メソッドリソース(URL のパス)
図5 Microsoft Graph のユーザー操作で使うメソッドと URL

ステータスコード:結果はどうだったか

サーバは応答の先頭に3桁のステータスコードを付けます。1桁目で結果の種類が分かるので、まずここを見ます。

コード意味
1xx情報。リクエストを受け取り、処理を続けている
2xx成功
3xxリダイレクト。完了には別の操作(別の URL へのアクセスなど)が必要
4xxクライアントエラー。リクエストの側に問題がある
5xxサーバエラー。正しそうなリクエストを、サーバが処理できなかった

REST API でよく見るコードは次のとおりです。

コード意味
200 OK成功した
201 Created成功し、新しいリソースができた
204 No Content成功した。応答で返す中身はない
400 Bad Requestリクエストの形がおかしいなどの理由で処理できない
401 Unauthorized有効な認証情報が付いていない
403 Forbiddenリクエストは理解したが、実行を拒否した(権限不足など)
404 Not FoundURL の指すリソースが見つからない
429 Too Many Requests短い時間にリクエストを送りすぎた(レート制限)
500 Internal Server Errorサーバの中で想定外の問題が起きた
503 Service Unavailable過負荷や保守のため、一時的に処理できない

ヘッダとボディ、JSON

リクエストもレスポンスも、ヘッダとボディに分かれます。ヘッダには、ボディの形式(Content-Type)や認証情報(Authorization)などの付帯情報が入ります。ボディは中身そのもので、REST API では JSON がよく使われます。

リクエスト(クライアント → サーバ)メソッドとURLGET /v1.0/meヘッダAuthorization: Bearer <トークン> などボディ送るデータ(GET では空のことが多い)レスポンス(サーバ → クライアント)ステータスコード200 OKヘッダContent-Type: application/json などボディ{“displayName”: “…”, …} クライアントサーバ
図6 リクエストとレスポンスの中身(Microsoft Graph で自分のプロフィールを取得する例)

JSON(JavaScript Object Notation)は RFC 8259 で決められたテキスト形式です。{ } で囲んだ「名前と値」の組(オブジェクト)と、[ ] で囲んだ値の並び(配列)を組み合わせて書きます。値には文字列、数値、true/false、null も使えます。ボディが JSON のときは、ヘッダの Content-Type が application/json になります。

認証:誰からのリクエストか

誰でも読める公開 API を除けば、多くの API は「誰が送ってきたか」を確かめます。REST はステートレスなので、ログインした状態をサーバに覚えさせるのではなく、リクエストのたびに認証情報を付けて送ります。

よく使われるのは、あらかじめ取得したアクセストークンや API キーをヘッダに入れる方法です。OAuth 2.0 のアクセストークンなら、RFC 6750 の形で Authorization: Bearer <トークン> と書きます。Microsoft Graph や Azure の REST API も、Microsoft Entra ID からトークンを取得し、この形で付けて呼び出します。

注意

Bearer トークンは、持っている人なら誰でも使えるトークンです。パスワードと同じように扱い、スクリプトに直接書いたり、画面や出力ごと共有したりしないようにしてください。

curl で公開 API を呼んでみる

ここからは、インターネットに公開されている REST API に curl でリクエストを送り、ここまでの説明を実際の応答で確かめます。curl はコマンドラインから HTTP のリクエストを送れるツールで、Windows にも標準で入っています。

Windows で試す場合

Windows PowerShell 5.1 では、curl が Invoke-WebRequest の別名(エイリアス)になっていて、オプションの書き方が違います。curl.exe と拡張子まで打つと、curl 本体が動きます。PowerShell 7 以降にはこの別名はありません。

今回使う公開 API:npm レジストリ

題材には、npm レジストリの API を使います。npm は JavaScript の部品(パッケージ)を共有するしくみで、レジストリはそのパッケージと情報をためた公開データベースです。registry.npmjs.org で動いていて、読み取りだけなら登録も認証もいりません。応答も短いので、REST API の動きを確かめるのにちょうどよい題材です。npm を使ったことがなくても、インストールしていなくても試せます。

今回アクセスするのは、express(Web アプリを作るときによく使われるパッケージ)の「配布タグ(dist-tag)」の一覧です。配布タグはバージョン番号に付ける別名で、latest はそのパッケージの現在の版を指すタグで、バージョンを指定せずにインストールすると、このタグの版が入ります。

HTTP あなたの PC curl…/express/dist-tags npm レジストリ(公開 API)registry.npmjs.org express(パッケージ) 配布タグ(dist-tags) latest → 5.2.1 latest-4 → 4.22.3 ほかのパッケージ
図7 今回 curl でアクセスする公開 API

使うコマンドは、次の部品でできています。

curl-s-X DELETE-w "…"https://registry.npmjs.org/…コマンド名余計な表示を出さないメソッドを指定(省くと GET)最後に表示する内容(ステータスコードなど)送り先のリソース(URL)
図8 curl コマンドの各部分(STEP 3 の形。STEP 1・2 は -X を省いているので GET になる)

-w の中の %{http_code} はステータスコード、%{content_type} は Content-Type、\n は改行を表します。これを付けておくと、ボディ(JSON)のあとに、結果のステータスコードとボディの形式が1行で表示されます。

以下の出力は、Linux の curl 8.5.0 で、2026年10月に取ったものです。返ってくるバージョン番号は、その後のリリースで変わります。

GET でリソースを取得する

まず、express の配布タグの一覧を GET で取得します。やり取りは次のようになります。

あなたの PC(curl) npmレジストリ GET /-/package/express/dist-tags 200 {“latest”:”5.2.1″,”latest-4″:”4.22.3″} リクエスト →← レスポンス サーバの判断:express の配布タグは登録されている→ 成功(200)。タグ一覧を JSON で返す
図9 STEP 1 のやり取り(GET で取得 → 200)

実際のコマンドと出力です。

ターミナル

$ curl -s -w "\n%{http_code} %{content_type}\n" https://registry.npmjs.org/-/package/express/dist-tags
{"latest":"5.2.1","latest-4":"4.22.3"}
200 application/json

1行目がボディ(JSON)、2行目が -w で表示させたステータスコードと Content-Type です。

表示意味
“latest”:”5.2.1″latest タグが指しているバージョン(取得した時点)
“latest-4″:”4.22.3”express が独自に付けているタグで、4.22.3 を指している
200成功
application/jsonボディが JSON であること

存在しないリソースを指定する

次に、存在しないパッケージ名を指定して GET を送ります。

あなたの PC(curl) npmレジストリ GET /-/package/hirotanoblog-no-such-package/dist-tags 404 ”Not Found” リクエスト →← レスポンス サーバの判断:そのパッケージは登録されていない→ 見つからない(404)
図10 STEP 2 のやり取り(存在しないリソース → 404)

実際のコマンドと出力です。

ターミナル

$ curl -s -w "\n%{http_code} %{content_type}\n" https://registry.npmjs.org/-/package/hirotanoblog-no-such-package/dist-tags
"Not Found"
404 application/json

404 が返りました。URL の指すリソースがないという意味なので、まずパスの綴りを疑います。ボディの "Not Found" も JSON で、文字列1つだけの JSON です。

認証なしで削除しようとする

最後に、-X DELETE でタグを削除するリクエストを送ります。Authorization ヘッダ(認証情報)は付けていません。

あなたの PC(curl) npmレジストリ DELETE /-/package/express/dist-tags/hirotanoblog-test 401 ”Unauthorized” リクエスト →← レスポンス サーバの判断:認証情報(Authorization ヘッダ)がない→ 実行しない(401)。レジストリは何も変わらない
図11 STEP 3 のやり取り(認証なしの DELETE → 401)

実際のコマンドと出力です。

ターミナル

$ curl -s -X DELETE -w "\n%{http_code} %{content_type}\n" https://registry.npmjs.org/-/package/express/dist-tags/hirotanoblog-test
"Unauthorized"
401 application/json

401 で断られました。タグの追加や削除はパッケージの管理者だけができる操作で、このリクエストには誰が送ったかを示す情報がないためです。401 は「リクエストは適用されていない」という意味なので、レジストリの内容は変わっていません。

似たコードに 403 があります。401 は有効な認証情報がないとき、403 は相手が誰かは分かったうえで実行を拒否したときに返ります。トークンを付けているのに 403 になる場合は、トークンに与えた権限が足りないことを疑います。

更新系の操作を試すときは

STEP 3 は認証情報を付けていないので、必ず断られ、レジストリは何も変わりません。ただし、本物のトークンを付けた PUT や DELETE は実際にデータを変えます。更新系の操作は、自分の検証用テナントや検証機など、変えてよい環境で試してください。

実務で出会う REST API

インフラの仕事で触れる機会が多いのは、次のような API です。どれも、URL でリソースを決め、メソッドで操作を伝え、ステータスコードとボディで結果を確かめる、という読み方は同じです。

API内容
Microsoft GraphMicrosoft 365 や Entra ID のデータを扱う RESTful な API。https://graph.microsoft.com を入口に、ユーザー、メール、Teams などを操作する
Azure Resource Manager の REST APIAzure のリソースを作成・変更・削除する API。Azure portal、Azure CLI、Azure PowerShell からの操作も Resource Manager が受け付けて処理する
RESTCONF(RFC 8040)YANG で定義されたネットワーク機器の設定や状態を、HTTP で読み書きするための標準プロトコル

うまくいかないときの切り分け

状態よくある原因確認すること
401認証情報を付けていない、トークンの期限切れ、ヘッダの書き間違いAuthorization ヘッダがあるか、Bearer とトークンの間の空白、トークンの有効期限
403認証はできたが、権限が足りないアカウントやアプリに与えた権限(ロール、スコープ)
404URL の誤り、リソースがない、API のバージョン違いパスの綴り、ID、ドキュメントの URL との違い
405そのリソースが受け付けないメソッドを使ったドキュメントのメソッド。応答の Allow ヘッダに使えるメソッドが入っている
415ボディの形式がサーバの想定と違うJSON を送るときに Content-Type: application/json を付けたか
429短い時間に送りすぎたRetry-After ヘッダがあれば、その時間だけ待ってから送り直す
5xxサーバ側の問題や一時的な過負荷時間をおいて再試行する。POST を送り直すときは、二重登録にならないか確かめる

まとめ

用語ひとことで
REST APIリソースを URL で表し、HTTP のメソッドで操作する Web API
リソース操作の対象(ユーザー、パッケージ、設定など)
メソッドGET 取得、POST 処理・作成、PUT 置き換え、PATCH 一部変更、DELETE 削除
ステータスコード2xx は成功、4xx はリクエスト側の問題、5xx はサーバ側の問題
JSON{ } と [ ] でデータを表すテキスト形式。Content-Type は application/json
認証リクエストのたびに、Authorization ヘッダでトークンなどを送る

最初は GET で公開 API の応答を眺め、ステータスコードとボディの組み合わせに慣れておくのがおすすめです。そのうえで Microsoft Graph やネットワーク機器の API のドキュメントを読むと、どの URL にどのメソッドを送ればよいかが追いやすくなります。

コメント