閉じる

GETとPOSTは何が違うのか?PythonでAPIリクエスト入門

Web APIとやり取りするとき、まず押さえるべきはHTTPのGETPOSTの役割と違いです。

この記事では、両者の基本と考え方を丁寧に整理し、Pythonのrequestsライブラリでの具体的な書き方までを一気に学べるように構成しました。

初心者の方でも、この記事を読み終える頃には使い分けの判断ができるようになります。

HTTPのGETとPOSTの基本

何をするメソッドか

まず、GETは「取得」、POSTは「送信(作成・登録)」です

この一言が土台になります。

GETは読み取り専用の要求

GETはサーバにあるリソース(データ)を読み取るためのメソッドです。

原則としてサーバ側の状態を変えないことが期待されます。

ニュース一覧の取得やユーザ情報の参照などが該当します。

繰り返し同じGETを送っても結果や副作用は変わらないのが理想です。

POSTは何かを新しく送る要求

POSTはサーバに新しい情報を送って処理してもらうメソッドです。

典型的には新規登録、作成、問い合わせ送信などです。

同じPOSTを繰り返すと重複作成につながることがあるため、扱いに注意します。

URLとボディ(送る場所)

GETは主にURLの「クエリ文字列」に、POSTは「リクエストボディ」にデータを入れます

GETはURLにパラメータを付ける

GETでは次のようにURL末尾に?key=value&...の形でパラメータを付けます。

例: https://api.example.com/search?q=python&page=2

POSTはボディにデータを入れる

POSTではURLはエンドポイントを示すだけで、送るデータ本体はリクエストボディに入れます。

ボディの形式はapplication/jsonapplication/x-www-form-urlencodedなどContent-Typeで指定します。

見えるデータと隠れるデータ

URLはブラウザやログに残りやすく、ボディはURLほど目につきませんが「完全に隠れる」わけではありません

URLは目に見えて残る

GETのクエリはアドレスバーや履歴に露出します。

アクセスログにも残りやすく、共有もしやすいです。

ボディはURLには出ないが安全とは限らない

POSTのボディはURLに出ませんが、開発者ツールやサーバ側では見えます。

「POSTだから安全」ではありません。

機密は必ずHTTPSで送信し、クエリに秘密情報を入れないのが基本です。

以下は露出の違いの概要です。

観点GETPOST
データの位置URLのクエリリクエストボディ
ブラウザのアドレスバー露出する露出しない
ブラウザ履歴・ブックマーク残りやすい基本的に残らない
サーバアクセスログURLとして残るヘッダのみ、ボディは通常ログに残さない(設定次第)

データ量と形式(ざっくり)

GETは短いクエリ向き、POSTは大きなデータや複雑な構造向きです。

おおまかな上限感覚

GETのURL長は仕様で厳密には定義されませんが、ブラウザやサーバの制限で約2KB〜8KB程度が実用限界になることが多いです。

一方、POSTのボディはより大きなデータを扱えます(ただしサーバ設定に依存します)。

よく使うデータ形式

  • JSON送信: application/json(構造的なデータに向く)
  • フォーム送信: application/x-www-form-urlencoded(HTMLフォームの標準)
  • ファイル含むフォーム: multipart/form-data

Python(requests)でGETとPOST

GETの書き方(クエリ)

Pythonのrequests.getではparamsに辞書を渡すのが基本です。

ライブラリが自動でクエリ文字列に組み立ててURLエンコードしてくれます。

サンプルコード(クエリで検索条件を渡す)

Python
# requestsを使ったGETリクエストの基本例
import requests

def fetch_search_results():
    # デモ用のHTTPエコーサービス(httpbin)のGETエンドポイント
    url = "https://httpbin.org/get"

    # URLに付与したいクエリパラメータを辞書で指定
    params = {
        "q": "python",   # 検索キーワード
        "page": 2        # ページ番号
    }

    # GETにparams=を渡すと、?q=python&page=2 のようなクエリ文字列を自動生成
    response = requests.get(url, params=params)

    # ステータスとJSONを確認(実運用ではエラーハンドリングを追加すると良い)
    print("Status:", response.status_code)
    data = response.json()  # JSONとしてパース
    # サーバが受け取ったクエリは "args" に反映される(httpbinの仕様)
    print("Args:", data.get("args"))
    print("URL:", data.get("url"))

if __name__ == "__main__":
    fetch_search_results()
実行結果
Status: 200
Args: {'page': '2', 'q': 'python'}
URL: https://httpbin.org/get?page=2&q=python

POSTの書き方(JSON)

JSONを送るときはjson=引数を使うのが簡単で確実です。

requestsContent-Type: application/jsonを自動設定し、辞書をJSON文字列に変換してボディへ入れます。

サンプルコード(JSONで新規作成リクエスト)

Python
# JSONボディをPOSTする基本例
import requests

def create_user():
    url = "https://httpbin.org/post"

    # 送信したいJSONペイロード(辞書でOK)
    payload = {
        "username": "alice",
        "email": "alice@example.com",
        "roles": ["reader", "contributor"]
    }

    # json= を使うと自動でJSON化&適切なContent-Typeを付与
    response = requests.post(url, json=payload)

    print("Status:", response.status_code)
    data = response.json()
    # httpbinでは受け取ったJSONが "json" にそのまま返る
    print("JSON echoed:", data.get("json"))

if __name__ == "__main__":
    create_user()
実行結果
Status: 200
JSON echoed: {'email': 'alice@example.com', 'roles': ['reader', 'contributor'], 'username': 'alice'}

フォーム送信の例(data)

HTMLフォームと同等の形式で送りたいときはdata=を使います

requestsapplication/x-www-form-urlencodedとしてボディを組み立てます。

サンプルコード(ログインフォームを想定)

Python
# フォーム形式でPOSTする例(application/x-www-form-urlencoded)
import requests

def login_form():
    url = "https://httpbin.org/post"

    # 典型的なフォームのフィールド
    form = {
        "username": "alice",
        "password": "s3cr3t"  # 実運用ではHTTPS必須。ログにも残さないこと。
    }

    # data= でフォームエンコードしてボディに入る
    response = requests.post(url, data=form)

    print("Status:", response.status_code)
    data = response.json()
    # httpbinではフォーム値は "form" に反映される
    print("Form echoed:", data.get("form"))

if __name__ == "__main__":
    login_form()
実行結果
Status: 200
Form echoed: {'password': 's3cr3t', 'username': 'alice'}

注意: パスワードなど機密はクエリに入れないでください。

必ずHTTPSを使い、ログ出力にも細心の注意を払いましょう。

使い分けの基準と注意点

取得はGET(状態を変えない)

「読むだけ」はGETです。

検索、一覧、詳細の参照など、サーバのデータや状態を変えない操作に使います。

例として、ユーザ一覧の取得はGET /users?limit=20のように表現します。

繰り返し実行しても副作用が起きないように設計します。

GETでやらない方がよいこと

データの新規作成や削除、更新などサーバの状態を変える処理GETでは行いません。

ブックマークやクローラがアクセスしても安全であることが理想です。

追加や登録はPOST(状態が変わる)

「何かを増やす・登録する」はPOSTです。

新規ユーザ作成ならPOST /usersにボディでデータを送ります。

同じPOSTを繰り返すと重複が生じやすいため、クライアント側で送信の二重実行に注意し、必要に応じて<b>重複防止のトークン</b>や<b>リトライ方針</b>を設計します。

POSTのURLは操作対象、ボディは内容

慣れるまでのコツは、URLは「どこに」ボディは「何を」という役割と考えることです。

URLでリソースやコレクションを示し、ボディで作成・処理に必要なデータを渡します。

キャッシュとブックマーク

GETはキャッシュやブックマークとの相性が良く、POSTは基本的にそれらに向きません

GETはキャッシュされやすい

GETはブラウザや中継のキャッシュ対象になりやすく、URL単位で再現可能です。

検索結果ページの共有や、同じ条件での再取得が容易です。

POSTは履歴やブックマークに残しづらい

POSTはボディが履歴に残らないため、URLだけでは再現できません。

「アクションの再送」や「確認のダイアログ」が必要になるのはこのためです。

セキュリティの基本(パスワード)

秘密はURLに載せない、必ずHTTPSを使う

これが最重要です。

守るべき原則

  • パスワードやトークンをGETのクエリに載せない。URLは履歴・ログ・共有で漏れやすいです。
  • HTTPSを必ず使うPOSTでも平文のHTTPでは盗聴されます。
  • リクエストやエラーログに機密を出力しない。サンプル出力にも注意します。

クイックリファレンス(チェックリスト)

GETのチェック項目

  • 処理は「参照のみ」になっているか(サーバ側の状態を変えないか)
  • パラメータはparamsでURLクエリに渡しているか
  • 機密情報をクエリに含めていないか
  • ブックマークや共有を想定したURLになっているか
  • クエリが長くなり過ぎていないか(必要ならPOSTを検討)

POSTのチェック項目

  • 処理は「作成・送信・登録」など状態変化を伴うものか
  • ボディ形式は目的に合っているか(json= or data=)
  • 重複送信の対策や再送時の挙動を決めているか
  • 機密はボディに入れ、必ずHTTPSを使っているか
  • エンドポイントURLは「どこに」送るかが明確か(内容はボディへ)

まとめ

GETは「読む」、POSTは「送る」—この役割をまず確実に押さえ、データの置き場所(URLかボディか)、露出の度合い、キャッシュやブックマークとの相性を理解することが肝心です

Pythonではrequestsを使い、GETparams=POSTjson=data=を使い分ければ、実装は自然と正しい方向に揃います。

機密をURLに載せない、HTTPSを必ず使うという基本を守りつつ、小さなサンプルから手を動かして理解を深めていきましょう。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!